Alex_AMF Posted April 16, 2013 Posted April 16, 2013 (edited) Hello, My goal is to set up a batch printing on all AutoCAD drawings. Each drawing will have a record similar to this: The PartNo records underlined in red are other drawings that my recursive function will go through. That's why I must access this information. I believe I must access an object named "BLOCKNT" in order to do so but I'm unsure about the syntax. FYI, for some reason, whenever I try to use this code: ApplicationServices.Application.DocumentManager.MdiActiveDocument I get the following error: An unhandled exception of type 'System.IO.FileNotFoundException' occurred in Unknown Module.Additional information: Could not load file or assembly 'acmgd, Version=18.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. This is a .exe application and I have read that I cannot use NETLOAD commands in a .exe project? Does this make sense? Thank you! Alex Edited April 16, 2013 by Alex_AMF Quote
BlackBox Posted April 16, 2013 Posted April 16, 2013 Tabling the immense topic of printing drawings through batch processing for now, if you're using a stand alone EXE, then you should be accessing AutoCAD via COM, and not .NET API. http://through-the-interface.typepad.com/through_the_interface/2010/02/handling-com-calls-rejected-by-autocad-from-an-external-net-application.html Separately, hard to tell for sure as you've not posted your calling code, but seemingly your System.IO.FileNotFoundException results from attempting to pass the MdiActiveDocument Object to a System.IO.File.Exists() Method call (or the like), when you'd instead need to supply the qualified FilePath and FileName instead. Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 I see ... I think the documentation of AutoCAD that I've been using is for .NET API. As for the calling code itself, here's what it looked like: Private Sub ACAD() 'The application crashes here and I receive the error posted above. GetBlockContents() End Sub Private Sub GetBlockContents() Dim test = Application.DocumentManager.MdiActiveDocument End Sub Quote
BlackBox Posted April 16, 2013 Posted April 16, 2013 Start here: My First Plug-in Training Regardless of if you're adept at .NET development outside of AutoCAD, or if this is your first attempt at both, you need to better understand the nature of the .NET and COM APIs before your effort(s) will be successful. ** Note - Autodesk's .NET Documentation assumes a basic understanding of .NET Development concepts. Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 Thank you. I'll look into that. I am pretty decent when it comes to .NET development outside of AutoCAD. Pretty new in the AutoCAD concept though. I've done some SolidEdge before but now I'm expanding on this. Thanks again! Quote
BlackBox Posted April 16, 2013 Posted April 16, 2013 Thank you. I'll look into that. I am pretty decent when it comes to .NET development outside of AutoCAD. Pretty new in the AutoCAD concept though. I've done some SolidEdge before but now I'm expanding on this. Thanks again! No worries; we all start somewhere... Methinks your prior .NET Development experience will come in handy very soon. You just need to familiarize yourself with the API Objects' Properties, Methods, and Events. Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 I've learned quite a bit from going through those tutorials. I also checked out the site http://through-the-interface.typepad.com/ which had an insane amount of information. I'm still pretty perplexed on how to retrieve the block records from a drawing. I'm not creating a plug-in, and it that the .NET API is loaded in my project even though I must only communicate with AutoCAD via the COM. I'm not sure which of these references is .NET because I thought I only took them from the COM tab: AcDbMgd AcMgd AutoCAD AXDBLib Anyway, I'll try to advance my project further. I'll post the answer once I get it. Quote
fixo Posted April 16, 2013 Posted April 16, 2013 Just for the quick example try this to open drawings multiple to read, better yet to see Database.ReadDwg method though Code: <CommandMethod("bah")> _ Public Shared Sub BatchStart() Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("SDI", 0) Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor ' Get drawings to process Dim dwgsForm As New Autodesk.AutoCAD.Windows.OpenFileDialog("Drawings to Process", "", "dwg", "", Autodesk.AutoCAD.Windows.OpenFileDialog.OpenFileDialogFlags.AllowMultiple) If dwgsForm.ShowDialog() <> Windows.Forms.DialogResult.OK Then Return End If Dim dwgfiles As String() = dwgsForm.GetFilenames() Using doclock As DocumentLock = doc.LockDocument() For i As Integer = 0 To dwgfiles.GetLength(0) - 1 Dim newdoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.Open(dwgfiles(i), False) 'your rest code to retrieve desired things from opened document here '__________________________________________________' ed.WriteMessage(vbLf & dwgfiles(i).ToString()) ' close doc without changes newdoc.CloseAndDiscard() Next End Using End Sub Quote
BlackBox Posted April 16, 2013 Posted April 16, 2013 You need to add references to the Interop assemblies for your application's target processing environment... As an example, these Interop assemblies can be found here in the ObjectARX 2014 SDK for 32-Bit, or 64-Bit respectively: C:\Autodesk\ObjectARX 2014\inc-win32\Autodesk.AutoCAD.Interop.dll C:\Autodesk\ObjectARX 2014\inc-x64\Autodesk.AutoCAD.Interop.dll Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 Hello Fixo, I've seen you post quite a bit on topics related to AutoCAD. Glad you came and helped me! Appreciate it. In any case, every time I seem to include the "MdiActiveDocument" portion with the document manager, my .exe program crashes and gives me the following error: An unhandled exception of type 'System.IO.FileNotFoundException' occurred in Unknown Module.Additional information: Could not load file or assembly 'acmgd, Version=18.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. Thanks again Quote
BlackBox Posted April 16, 2013 Posted April 16, 2013 Hello Fixo, I've seen you post quite a bit on topics related to AutoCAD. Glad you came and helped me! Appreciate it. In any case, every time I seem to include the "MdiActiveDocument" portion with the document manager, my .exe program crashes and gives me the following error: Thanks again http://www.cadtutor.net/forum/showthread.php?71118-ThisDrawing-Property-with-AutoCAD-2013 Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 You need to add references to the Interop assemblies for your application's target processing environment... As an example, these Interop assemblies can be found here in the ObjectARX 2014 SDK for 32-Bit, or 64-Bit respectively: C:\Autodesk\ObjectARX 2014\inc-win32\Autodesk.AutoCAD.Interop.dll C:\Autodesk\ObjectARX 2014\inc-x64\Autodesk.AutoCAD.Interop.dll Wouldn't this do the same? Imports Autodesk.AutoCAD.Interop I tried importing what you said (I have the ObjectARX 2010 though ...) and it said the namespace was ambiguous. Probably because I already had that code before? It only error'ed out when I imported the Autodesk.AutoCAD.Interop.dll Quote
BlackBox Posted April 16, 2013 Posted April 16, 2013 Wouldn't this do the same? Imports Autodesk.AutoCAD.Interop I tried importing what you said (I have the ObjectARX 2010 though ...) and it said the namespace was ambiguous. Probably because I already had that code before? It only error'ed out when I imported the Autodesk.AutoCAD.Interop.dll The Interop assembly must be added as a reference to your solution, only then will your Imports statement (using in C#) be successful. Additional info you may find helpful: http://forums.autodesk.com/t5/NET/how-to-access-AutoCAD-2012-from-Vb-net-Standard-Exe/td-p/3363237 Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 Derp. XD Thank you haha I'll try that out. Quote
BlackBox Posted April 16, 2013 Posted April 16, 2013 Derp. XD Thank you haha I'll try that out. No worries .... Check out this thread: VB.NET - Open an Existing Dwg from Stand-Alone exe ... Bill and I went back and forth here at CADTutor and there over a few weeks, there's plenty of related threads by us on this small litany of topics, given the related threads a look. Quote
BlackBox Posted April 16, 2013 Posted April 16, 2013 Just for the quick example try this to open drawings multiple to read,better yet to see Database.ReadDwg method though Hi Fixo, I get now that you were just posting some sample code for the OP to pull from (I removed my earlier post), but I did want to ask about ReadDwg... Is that relegated to plug-in, or can stand alone EXE also use ReadDwg? Separately, can one print via ReadDwg (i.e., side Database)? TIA Quote
fixo Posted April 16, 2013 Posted April 16, 2013 No You could not use ReadDwdgFile in side database, just using API,say for example get tables from multiple files and write to csv Public Function GetDirectoryDrawings(directoryFullName As String, subDirsBrowse As Boolean) As List(Of FileInfo) Dim dir As New DirectoryInfo(directoryFullName) If Not dir.Exists Then Throw New DirectoryNotFoundException() Return Nothing End If Dim opt As SearchOption = SearchOption.AllDirectories If subDirsBrowse = False Then opt = SearchOption.TopDirectoryOnly Return dir.GetFiles("*dwg", opt).AsEnumerable().OrderBy(Function(x) x.FullName).ToList() End Function <CommandMethod("wtb", CommandFlags.Session)> _ Public Sub testDirFiles() Dim folder As String = "C:\Test\" Dim csvfile As String = "C:\Test\atable.csv" Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim fd As List(Of FileInfo) = GetDirectoryDrawings(folder, False) '' True for processing the subdirectories Dim collect As New StringBuilder If fd.Count = 0 Then Return Try Using doclock As DocumentLock = doc.LockDocument() For n As Integer = 0 To fd.Count - 1 Dim dwgname As String = fd(n).FullName Using newdb As Database = New Database(False, True) ed.WriteMessage(vbLf + dwgname + vbLf) Try newdb.ReadDwgFile(dwgname, FileOpenMode.OpenForReadAndAllShare, False, Nothing) Catch ex As Autodesk.AutoCAD.Runtime.Exception If ex.ErrorStatus = ErrorStatus.DwgNeedsRecovery Then Continue For End If End Try Using newtr As Transaction = newdb.TransactionManager.StartTransaction ' Open dictionary for reading Dim layoutDict As DBDictionary = DirectCast(newtr.GetObject(newdb.LayoutDictionaryId, OpenMode.ForRead), DBDictionary) ' Loop through dictionary entries For Each entry As DictionaryEntry In layoutDict Dim ltr As Layout = DirectCast(newtr.GetObject(DirectCast(entry.Value, ObjectId), OpenMode.ForRead), Layout) Dim btr As BlockTableRecord = DirectCast(newtr.GetObject(ltr.BlockTableRecordId, OpenMode.ForRead), BlockTableRecord) For Each id As ObjectId In btr Dim obj As DBObject = DirectCast(newtr.GetObject(id, OpenMode.ForRead), DBObject) If TypeOf obj Is Table Then Dim tbl As Table = TryCast(obj, Table) If tbl IsNot Nothing Then collect.AppendLine(String.Format("---------------------------------------")) collect.AppendLine(String.Format("Drawing name: {0}", dwgname)) collect.AppendLine(String.Format("Tab: {0}", ltr.LayoutName)) Dim numrows As Integer = tbl.Rows.Count Dim numcols As Integer = tbl.Columns.Count For i As Integer = 0 To numrows - 1 Dim rowline As New List(Of String) Dim line As String = String.Empty For j = 0 To numcols - 1 Dim cel As Cell = tbl.Cells(i, j) rowline.Add(cel.TextString) line = line + cel.TextString + vbTab Next collect.AppendLine(line.TrimEnd(vbTab)) Next End If End If Next Next newtr.Commit() End Using End Using Next End Using WriteTableToFile(csvfile, collect) Catch ex As System.Exception ed.WriteMessage(vbLf + ex.ToString + vbLf) Finally ed.WriteMessage(vbLf + vbTab + "---> File saved as: {0} <---" + vbLf, csvfile) End Try End Sub Public Sub WriteTableToFile(fpath As String, data As StringBuilder) 'If Not (File.Exists(fpath)) Then ' Using frs As New FileStream(fpath, FileMode.Create) ' frs.Flush() ' End Using 'End If Using fs As New FileStream(fpath, FileMode.Append, FileAccess.Write) Using sw As New StreamWriter(fs, Encoding.ASCII) sw.WriteLine(data.ToString) End Using End Using End Sub Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 http://www.cadtutor.net/forum/showthread.php?71118-ThisDrawing-Property-with-AutoCAD-2013 After reading the URLs you've provided, I came to a conclusion that I do not need the AcDbMgd.dll and AcMgd.dll files since those are used for Internal AutoCAD applications whilst I'm using an outside executable to gather information from AutoCAD. Here's how my project looks: References Imports Variable declarations (my problem at the moment) I referenced it correctly ... No? Quote
fixo Posted April 16, 2013 Posted April 16, 2013 Try change on this: Public vAcadApp as Autodesk.AutoCAD.Interop.AcadApplication Public vAcadDoc as Autodesk.AutoCAD.Interop.AcadDocument ETC Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 Try change on this: Public vAcadApp as Autodesk.AutoCAD.Interop.AcadApplication Public vAcadDoc as Autodesk.AutoCAD.Interop.AcadDocument ETC That was my initial move and I also thought it was going to work. Oddly enough, it still tells me it is ambiguous Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.