.NET

Reply
Distinguished Contributor
SRayC
Posts: 227
Registered: ‎12-10-2003
Message 1 of 8 (459 Views)
Accepted Solution

Create autocad 2012 COM object

459 Views, 7 Replies
01-03-2014 08:51 AM

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.

 

Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.DatabaseServices

Imports Autodesk.AutoCAD.PlottingServices

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.Interop

Imports Autodesk.AutoCAD.Interop.Common

Imports Autodesk.AutoCAD.GraphicsInterface

Imports Autodesk.AutoCAD.EditorInput

 

Public AcadApp As AcadApplication

 

But when I do the CreateObject method its throwing the following error.

 

AcadApp = CreateObject("AutoCAD.Application.18")

 

Error

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

*Expert Elite*
norman.yuan
Posts: 982
Registered: ‎04-27-2009
Message 2 of 8 (454 Views)

Re: Create autocad 2012 COM object

01-03-2014 09:10 AM in reply to: SRayC

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.

*Expert Elite*
dgorsman
Posts: 5,218
Registered: ‎10-12-2006
Message 3 of 8 (450 Views)

Re: Create autocad 2012 COM object

01-03-2014 09:33 AM in reply to: norman.yuan

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.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
Adopt. Adapt. Overcome. Or be overcome.
A good question will be halfway to a good answer.


Distinguished Contributor
SRayC
Posts: 227
Registered: ‎12-10-2003
Message 4 of 8 (440 Views)

Re: Create autocad 2012 COM object

01-03-2014 09:58 AM in reply to: dgorsman
Your assumption is correct, I want to control ACAD from an external exe. I am firing up a separate instance of ACAD in the background and processing some files and then closing ACAD, no user interaction except for file selection. I have several other programs doing similar task for ACAD2006 written VB.NET (VS2005) without issue. Not saying what was done was correct but it has been working. If you have some samples, or can point me to some, that has the best approach to do this I would be most greatful. Thx Ray C.
Board Manager
StephenPreston
Posts: 373
Registered: ‎05-22-2006
Message 5 of 8 (436 Views)

Re: Create autocad 2012 COM object

01-03-2014 10:10 AM in reply to: SRayC

Hi SRayC,

 

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_the_interface/2010/02/handling-com-calls-rejected-b...

 

 

 

 

Cheers,

Stephen Preston
Autodesk Developer Network
Distinguished Contributor
SRayC
Posts: 227
Registered: ‎12-10-2003
Message 6 of 8 (431 Views)

Re: Create autocad 2012 COM object

01-03-2014 10:17 AM in reply to: StephenPreston

Thanks for the update.

 

I tried accessing the link you posted but it could not be found.

 

 

Ray C.

Board Manager
StephenPreston
Posts: 373
Registered: ‎05-22-2006
Message 7 of 8 (428 Views)

Re: Create autocad 2012 COM object

01-03-2014 10:18 AM in reply to: SRayC

Sorry  -the hyperlink included a superfluous '.'. Try this -

 

http://through-the-interface.typepad.com/through_the_interface/2010/02/handling-com-calls-rejected-b...

Cheers,

Stephen Preston
Autodesk Developer Network
Board Manager
StephenPreston
Posts: 373
Registered: ‎05-22-2006
Message 8 of 8 (406 Views)

Re: Create autocad 2012 COM object

01-03-2014 02:44 PM in reply to: StephenPreston

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).

 

>>>

Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports System.Runtime.InteropServices


Public Class Form1
    Implements IMessageFilter

#Region "  IMessageFilter Interface "

    <ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000016-0000-0000-C000-000000000046")> _
    Public Interface IMessageFilter
        <PreserveSig()> _
        Function HandleInComingCall(dwCallType As Integer, hTaskCaller As IntPtr, dwTickCount As Integer, lpInterfaceInfo As IntPtr) As Integer
        <PreserveSig()> _
        Function RetryRejectedCall(hTaskCallee As IntPtr, dwTickCount As Integer, dwRejectType As Integer) As Integer
        <PreserveSig()> _
        Function MessagePending(hTaskCallee As IntPtr, dwTickCount As Integer, dwPendingType As Integer) As Integer
    End Interface

#End Region

#Region "  IMessageFilter to handle failing COM operations "

    <DllImport("ole32.dll")> _
    Private Shared Function CoRegisterMessageFilter(lpMessageFilter As IMessageFilter, ByRef lplpMessageFilter As IMessageFilter) As Integer
    End Function

    Private Function IMessageFilter_HandleInComingCall(dwCallType As Integer, hTaskCaller As IntPtr, dwTickCount As Integer, lpInterfaceInfo As IntPtr) As Integer Implements IMessageFilter.HandleInComingCall
        'LogAction("IMessageFilter_HandleInComingCall")
        Return 0 ' SERVERCALL_ISHANDLED
    End Function

    Private Function IMessageFilter_RetryRejectedCall(hTaskCallee As IntPtr, dwTickCount As Integer, dwRejectType As Integer) As Integer Implements IMessageFilter.RetryRejectedCall
        'LogAction("IMessageFilter_RetryRejectedCall")
        Return 1000 ' Retry in a tenth of a second
    End Function

    Private Function IMessageFilter_MessagePending(hTaskCallee As IntPtr, dwTickCount As Integer, dwPendingType As Integer) As Integer Implements IMessageFilter.MessagePending
        'LogAction("IMessageFilter_RetryRejectedCall")
        Return 1  ' PENDINGMSG_WAITNOPROCESS
    End Function

#End Region

    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
            CoRegisterMessageFilter(Me, _filter)
        End If

        _acadApp = CreateObject("AutoCAD.Application.19")
        _acadApp.Visible = True
    End Sub
End Class

<<<

 

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).

 

Cheers,

Stephen Preston
Autodesk Developer Network
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.