Hi all,
I am writing an EXE .net application and I need to, somehow, use NETLOAD and load a dll file. As far as I understood from here, following line would be the key for me.
Assembly.LoadFrom( <...full path to my DLL file...> )
I run the code and I get no error - AutoCAD has been set to be Visible since I am still debuging my code.
Meanwhile the subroutine's meta data is not recognised at all - as if the DLL file has not been loaded in AutoCAD.
Any idea what that might be for?
Thanks
Yes, code Assembly.LoadFrom/LoadFile() is the same as NETLOAD command in AutoCAD, if the code code is called inside AutoCAD process.
However, since you are doing EXE, which is a separate process from AutoCAD, even you are automating AutoCAD (via COM API), if you call Assemly.Loadxxx() in your EXE project, the DLL is loaded into your EXE process, not into AutoCAD process. Since the code in the DLL is for AutoCAD and likely has references to acdbmgd/acmgd/accore.dll, which cannot be used outside AutoCAD process, that is why you get error.
If you automate AutoCAD froom EXE via COM, you'd better to make sure the .NET DLL is somehow automatically loaded into AutoCAD on its startup. Or, you want to make things more complicated (and often unnecessarily) by expose your functionality in the .NET DLL to COM, so that you can access it from outside AutoCAD via COM API.
Norman Yuan
Thanks for the clear response.
Now, I have another question: Is there any possibility to set a AutoCAD variable via COM API? If the answer is Yes, then I can set FILEDIA value to 0 and then I could pass my dll path to AutoCAD using following:
app.ActiveDocument.SendCommand("NETLOAD" & vbCr) app.ActiveDocument.SendCommand("...<DLL path>..." & vbCr)
Can't I?
Yes, you can set AutoCAD's system variable via AcadDocument:
acadApp.AcitveDocument.SetVariable "FILEDIA", 0
But, if you use SemdCommand to execute "NETLOAD", and you obviously want to execute some commands defined in your .NET DLL after the DLL is loaded.
However, your EXE app's execution of SendCommand may not wait the NETLOAD being completed (especially, if your DLL implementing IExtensionApplication, which do qite somework) and just jump to next line of code (after SemdCommand("NETLOAD"....). That is, you'd better only call SendCommand() from your external app only once as LAST action it ask AutoCAD to do.
So, if you have to automate AutoCAD this way, you'd better, (as I suggested previously) consider some autoloading .NET DLL approach, or loading them on demaond...
Norman Yuan
Actually I was editing my previous post while you sent your response.
The main problem with the command you mentioned i.e.
Application.SetSystemVariable("FILEDIA", 0)
is that I have to add following Refs to my project tobe able to benefit this code.
Which is basically impossible to import them in an EXE application (as we all know).
I appologise. I did not read your response thoroughly enough.
I though you meant
Application.SetSystemVariable
My bad
Although even with acadApp.AcitveDocument.SetVariable , the following exception is thrown:
Public memeber 'ActiveDocument' on type 'IAcadApplication' not found
Depending on how AutoCAD is started, there may or may not be an ActiveDocument. It looks like you launch AutoCAD from your EXE app. Iin this case, unless you expliciltly open a new or existing drawing, the AutoCAd session will not have an ActiveDocument.
So, before you can use AcadDocument.SetVariable() method, or any methods of the AcadDocument class for that matter, you need to obtain an instance of AcadDocument, be it ActiveDocument or not. Without seeing more of your code as what it exactly does, it is difficult to say more.
Norman Yuan
Thank you again Norman but I am afraid that's not the case. I put my code here to have a look:
Public Function InAutoCAD(FilePath As String) As Boolean Dim GivenTaskStatus As Boolean = False Const progID As String = "AutoCAD.Application.19" 'Const DllPath As String = "C:\DLL file.dll" Dim acApp As AcadApplication = Nothing Try acApp = DirectCast(Marshal.GetActiveObject(progID), AcadApplication) Catch Try Dim acType As Type = Type.GetTypeFromProgID(progID) acApp = DirectCast(Activator.CreateInstance(acType, True), AcadApplication) Catch GivenTaskStatus = False MessageBox.Show("Cannot create object of type """ + progID + """") End Try End Try If acApp IsNot Nothing Then Try acApp.Visible = True acApp.WindowState = AcWindowState.acMax Dim doc As AcadDocument = acApp.Documents.Open(FilePath) doc.Activate() ''╔════════ Loading DLL file ═══════╗ 'acApp.AcitveDocument.SetVariable("FILEDIA", 0) 'Try ' acApp.ActiveDocument.SendCommand("NETLOAD" & vbCr & DllPath & vbCr) 'Catch ex As System.Exception ' MsgBox(vbLf & "Cannot load {0}: {1}", DllPath, ex.Message) 'End Try ''╚════════ Loading DLL file ═══════╝ 'acApp.ActiveDocument.SendCommand("MYCOMMAND" + vbCr) 'saving document doc.Close(True) GivenTaskStatus = True Catch ex As Exception GivenTaskStatus = False MessageBox.Show(Me, "Problem executing component: " + ex.Message) End Try End If Return GivenTaskStatus End Function
Having said that, I am not happy with AutoCAD launching part of the code as well. It looks bogus to me. It gives me following error at my very first run of the code (cold start).
But after re-running the code couple of times, that error will not pup up again and AutoCAD is simply launched. Any idea what that might be for?
I found this by Google but unfortunately that article is too technical for me to comprehend 😞
Can't find what you're looking for? Ask the community or share your knowledge.