I have been out of the loop for a while but...
I am trying to create a VB.NET App that starts ACAD2012.
I have referenced the dll's and tlb's and set the Imports.
Public AcadApp As AcadApplication
But when I do the CreateObject method its throwing the following error.
AcadApp = CreateObject("AutoCAD.Application.18")
System.IO.FileNotFoundException was unhandled
Message="The specified module could not be found. (Exception from HRESULT: 0x8007007E)"
I'm at a loss. I've done this many times in the past with earlier versions without issue.
Any suggestions are greatly appreciated
Solved! Go to Solution.
You are doing an EXE application that will automates AutoCAD, aren't you? If so, you CANNOT have references in your EXE project to AutoCAD managed API DLLs (acadbmgd.dll/acmgd.dll): they can only be used inside AutoCAD (e.g. DLLs being loaded into AutoCAD with command "NETLOAD").
It is totally impossible that you "have done this many times in the past..." as you stated. No, not possible.
Not *exactly* like that, anyways. I think the OP is getting a little mixed up with the different methods of automation.
In a somewhat more verbose description for the OP: with .NET there are now three different ways of automating AutoCAD. The first is to use an external EXE program which drives an AutoCAD session, which I think was the original intention. Not the best option, but probably most familiar to those used to the old VB methods. The second way is to use COM inside AutoCAD, similar to how VBA is done. The third is using managed dotNET, again from inside AutoCAD. Thats where all those specific Imports statements come in.
I'd recommend putting aside the existing knowledge specific to VB (whether VB or VBA), and focus on the managed dotNET way of doing things.
As Dgorsman says, you should only be referencing the 'Interop' DLLs from the ObjectARX SDK in your project (don't reference AcMgd or AcDbMgd). And only import the 'Interop' namespaces. This is because AcMgd and AcDbMgd can only be used from inside the AutoCAD process. I believe the error you see is because your external executable is trying to load those DLLs and it can't.
I tested CreateObject with AutoCAD 2014 (I don't have 2012 installed, and it works fine. However, once your call to CreateObject is successful, you will probably run into the issue described in Kean's blog post here - http://through-the-interface.typepad.com/through_t
Sorry -the hyperlink included a superfluous '.'. Try this -
FWIW Here is a VB.NET version of the IMessageFilter code shown in Kean's blog, also including a call to CreateObject (albeit for AutoCAD 2014). This code was kindly provided to a colleague a while ago by an ADN member (who I won't name to maintain his/her anonymity).
Public Class Form1
#Region " IMessageFilter Interface "
Public Interface IMessageFilter
Function HandleInComingCall(dwCallType As Integer, hTaskCaller As IntPtr, dwTickCount As Integer, lpInterfaceInfo As IntPtr) As Integer
Function RetryRejectedCall(hTaskCallee As IntPtr, dwTickCount As Integer, dwRejectType As Integer) As Integer
Function MessagePending(hTaskCallee As IntPtr, dwTickCount As Integer, dwPendingType As Integer) As Integer
#Region " IMessageFilter to handle failing COM operations "
Private Shared Function CoRegisterMessageFilter(lpMessageFilter As IMessageFilter, ByRef lplpMessageFilter As IMessageFilter) As Integer
Private Function IMessageFilter_HandleInComingCall(dwCallType As Integer, hTaskCaller As IntPtr, dwTickCount As Integer, lpInterfaceInfo As IntPtr) As Integer Implements IMessageFilter.HandleInComingCall
Return 0 ' SERVERCALL_ISHANDLED
Private Function IMessageFilter_RetryRejectedCall(hTaskCallee As IntPtr, dwTickCount As Integer, dwRejectType As Integer) As Integer Implements IMessageFilter.RetryRejectedCall
Return 1000 ' Retry in a tenth of a second
Private Function IMessageFilter_MessagePending(hTaskCallee As IntPtr, dwTickCount As Integer, dwPendingType As Integer) As Integer Implements IMessageFilter.MessagePending
Return 1 ' PENDINGMSG_WAITNOPROCESS
Public _acadApp As AcadApplication
Dim _filter As IMessageFilter = Nothing
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Implement IMessageFilter
If (_filter Is Nothing) Then
_acadApp = CreateObject("AutoCAD.Application.19")
_acadApp.Visible = True
This is the code behind for a simple winform with a button. I moved the call to CoRegisterMesageFilter from the constructor to the button click handler for my own convenience while quickly testing it. If you comment out the call to CoRegisterMessageFilter, you should find that the call to _acadApp.Visible throws an exception - unless you put a breakpoint on that line (which will probably slow your code down enough that AutoCAD will be ready for the COM call when it comes).