.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Launching AutoCad Issue

33 REPLIES 33
Reply
Message 1 of 34
mgorecki
2180 Views, 33 Replies

Launching AutoCad Issue

I have another program that will launch this code below (admittedly, I got it from "Through the Interface")

Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
'Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Windows
Imports System
Imports Autodesk.AutoCAD.Interop
Imports System.Runtime.InteropServices
Imports Autodesk.AutoCAD.Internal.Forms
Imports System.Windows.Forms

Public Class launchAutoCad
    Public Shared Sub StartAutoCAD()
        ' "AutoCAD.Application.17" uses 2007, 2008, 2009
        '  whichever was most recently run
        ' "AutoCAD.Application.17.1" uses 2008, specifically
        ' "AutoCAD.Application.18" uses 2010, 2011, 2012
        ' "AutoCAD.Application.18.1" uses 2011, specifically
        ' "AutoCAD.Application.19" uses 2013,...

        Const progID As String = "AutoCAD.Application.18"
        Dim acApp As AcadApplication = Nothing

        Try
            acApp = DirectCast(Marshal.GetActiveObject(progID), AcadApplication)
        Catch ex2 As Exception
            Try
                Dim acType As Type = Type.GetTypeFromProgID(progID)
                acApp = DirectCast(Activator.CreateInstance(acType, True), AcadApplication)

            Catch ex As Exception
                MessageBox.Show("Cannot create object of type """ & progID & """")
            End Try
        End Try
        acApp = DirectCast(Marshal.GetActiveObject(progID), AcadApplication)

        If acApp IsNot Nothing Then
            ' By the time this is reached AutoCAD is fully
            ' functional and can be interacted with through code
            acApp.Visible = True
            acApp.ActiveDocument.SendCommand("(command " & Chr(34) & "NETLOAD" & Chr(34) & " " & _ Chr(34) & "C:\\mystuff\\myprog.dll" & Chr(34) & ") ")
        End If
    End Sub
End Class

 

At the first "Try" it will throw an exception because AutoCad is not running.

In the second "Try" we have:

acApp = DirectCast(Activator.CreateInstance(acType, True), AcadApplication)

Which launched AutoCad (it shows up in the task manager).

 

But still, it then goes into the next "Catch" and the message box says is can't create that ype of object.  But I can see that it launched AutoCad.

So I copied the line:

acApp = DirectCast(Marshal.GetActiveObject(progID), AcadApplication)

and forced it.  It worked.

Why would it throw an error if it did what it was supposed to do?  I see so many people using this same code on many different forums, but I can't understand why it doesn't work for me.

Thanks, in advance.

 

33 REPLIES 33
Message 2 of 34
fenton.webb
in reply to: mgorecki

It's really difficult to say what the problem might be. Usually, when you have issues with COM not working as expected it's because the installation is corrupted somehow...

 

Here's what I would advise...

 

1) Uninstall all Autodesk products

2) reinstall in chronological order.




Fenton Webb
AutoCAD Engineering
Autodesk

Message 3 of 34

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

 

P.S.: Are you trying to use AutoCAD .NET API from external exe-file? It is impossible.

E.g. those namespaces can be using only from  dll-file netloading into AutoCAD:

Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Windows

 

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 4 of 34

"those namespaces can be using only from  dll-file netloading into AutoCAD"

 

Not necessarily - you can import .NET DLLs that are dependent on another EXE as a reference to its types only (the dependencies will be ignored). This is particularly useful when using reflection.




Fenton Webb
AutoCAD Engineering
Autodesk

Message 5 of 34
mgorecki
in reply to: fenton.webb

I've gotten around the thrown exception by changing the code as shown:

Public Class launchAutoCad
    Public Shared Sub StartAutoCAD(ByVal rad As String)
        ' "AutoCAD.Application.17" uses 2007, 2008, 2009
        '  whichever was most recently run
        ' "AutoCAD.Application.17.1" uses 2008, specifically
        ' "AutoCAD.Application.18" uses 2010, 2011, 2012
        ' "AutoCAD.Application.18.1" uses 2011, specifically
        ' "AutoCAD.Application.19" uses 2013,...

        Const progID As String = "AutoCAD.Application.18"
        Dim acApp As AcadApplication = Nothing

        Try
            ' Get a running instance of AutoCad
            acApp = DirectCast(Marshal.GetActiveObject(progID), AcadApplication)
        Catch 'ex As Exception
            Try
                Dim acType As Type = Type.GetTypeFromProgID(progID)
                acApp = DirectCast(Activator.CreateInstance(acType, True), AcadApplication)

            Catch 'ex2 As Exception
                If IsProcessRunning("acad") = False Then
                    MessageBox.Show("Cannot create object of type """ & progID & """")
                Else
                    acApp = DirectCast(Marshal.GetActiveObject(progID), AcadApplication)
                End If
            End Try
        End Try

        If acApp IsNot Nothing Then
            ' By the time this is reached AutoCAD is fully
            ' functional and can be interacted with through code
            acApp.Visible = True
            'acApp.ActiveDocument.SendCommand("(command " & Chr(34) & "NETLOAD" & Chr(34) & " " & _
            '                    Chr(34) & "C:\\mystuff\\myprog.dll" & Chr(34) & ") ")


            Dim AcadDocs As Object = acApp.GetType().InvokeMember("Documents", Reflection.BindingFlags.GetProperty, Nothing, acApp, Nothing)
            ' Create array of parameters  
            Dim filename As String = "temp.dwg"
            Dim args() As Object = New Object(1) {}

            args(0) = filename
            args(1) = False 'read-only=false  

            ' open a drawing  
            Dim AcDoc As Object = AcadDocs.GetType.InvokeMember("Open", Reflection.BindingFlags.InvokeMethod, Nothing, AcadDocs, args, Nothing)
            Dim Util As Object = New Object

            ' Get reference on active document  
            AcDoc = acApp.GetType.InvokeMember("ActiveDocument", Reflection.BindingFlags.GetProperty, Nothing, acApp, Nothing, Nothing)

            ' Get reference of  AcadUtility  
            Util = AcDoc.GetType().InvokeMember("Utility", Reflection.BindingFlags.GetProperty, Nothing, AcDoc, Nothing)

            ' Get reference on ModelSpace  
            Dim oSpace As Object = AcDoc.GetType.InvokeMember("ModelSpace", Reflection.BindingFlags.GetProperty, Nothing, AcDoc, Nothing)

            ''********************************* draw circle ************************** 
            Dim center As Point3d = New Geometry.Point3d(0, 0, 0)
            Dim radius As Double
            radius = (CDbl(Val(rad)))
            DrawCircle(center, radius)

        End If
    End Sub

 

 I have a function defined (IsProcessRunning) that works for this.  It actually checks to see if the process "acad.exe" is actually running.

 

I am launching the dll from an exe currently (for testing) eventually it will be a web app.

I do have another issue though, I was just trying to pass the dll a string (just to see if I could)

Public Shared Sub StartAutoCAD(ByVal rad As String)

 

In the calling .exe:

Module Module1
    Sub Main()
        Dim rad As String = "12.5"
        launchAutoCad.launchAutoCad.StartAutoCAD(rad)
    End Sub
End Module

 I get the following error:

Could not load file or assembly 'acdbmgd, Version=18.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

 

Any help clearing that one up would be greatly appreciated.

Message 6 of 34
fenton.webb
in reply to: mgorecki

By the way, to refect the types without resolving the dependencies... Do this:

 

Assembly.ReflectionOnlyLoadFrom()



Fenton Webb
AutoCAD Engineering
Autodesk

Message 7 of 34


@fenton.webb wrote:

"those namespaces can be using only from  dll-file netloading into AutoCAD"

 

Not necessarily - you can import .NET DLLs that are dependent on another EXE as a reference to its types only (the dependencies will be ignored). This is particularly useful when using reflection.


Hi, Fenton!

Are you saying that I can use the classes / methods of acdbmgd.dll, acmgd.dll, accoremgd.dll from external exe-file??? You're kidding me? 😉

Otherwise I do not see any reason to load these assemblies in the exe-file if I can not use the dll-files (ie to execute code from them)

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 8 of 34


@mgorecki wrote:

... I get the following error:

Could not load file or assembly 'acdbmgd, Version=18.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified...

 

Any help clearing that one up would be greatly appreciated.


That's because you're trying to use the classes / methods from acmgd.dll from external exe-file instead from dll-file loaded into AutoCAD. Point3d is a class defined in acdbmgd.dll

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 9 of 34

Hi Alexander, can you tell me how to resolve this?  I have been writing VB.Net code, but always ran the code in an existing AutoCad session, never like this.  This is all new to me.

 

Thanks

Message 10 of 34
mgorecki
in reply to: fenton.webb

Hello Fenton,

You wrote:

 

By the way, to refect the types without resolving the dependencies... Do this:

 

Assembly.ReflectionOnlyLoadFrom()

 

 

This is going to sound stupid, but, what do I do with that?

Message 11 of 34

I'm not kidding, Alexander!




Fenton Webb
AutoCAD Engineering
Autodesk

Message 12 of 34

I do not have a reference to the acmgd.dll file in the .exe "References".  I do have a reference to the launchAutoCad.dll though.

 After all, I'm just sending a string, not attempting to launch any AutoCad commands.

Message 13 of 34

Hi, Fenton!
Then
please explain what you mean. Preferably with an new example on http://adndevblog.typepad.com/autocad/ and with title: "How to use AutoCAD .NET API assemblies out of acad.exe process"

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 14 of 34


@mgorecki wrote:

I do not have a reference to the acmgd.dll file in the .exe "References".  I do have a reference to the launchAutoCad.dll though.


And launchAutoCad.dll has reference to acdbmgd.dll and/or acmgd.dll? If so - than it is identical that .exe has reference to those.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 15 of 34

Ok, I give.  I removed the reference to launchAutoCad from the references and now the line:

launchAutoCad.launchAutoCad.StartAutoCAD(rad) says "launchAutoCad is not declared...."

 

I've looked all over, Googling everything I can think of that would relate.  I'm not asking for you to write the code, but can you please point me in the right direction?

 

I've looked at declare and DllImport, but either I don't understand, or it just doesn't apply.

Message 16 of 34

Hi Fenton.

 

If I'm not mistaken, there is static initialization occuring in AutoCAD's managed assemblies or native DLLs they link to, and that would mean that code executes at the point when the assembly or one of its dependents is loaded, and would prevent it from being loaded into any process, whcih would be triggered by any attmept to reflect on any contained types.  You can use ReflectionOnlyLoadFrom() to load a DLL as a data file, which allows you to access its metadata, but that's not the same as referencing the assembly in an .exe project.

 

If i'm mistaken, then I'd like to see an example of this.

 

Message 17 of 34

Hello, can you help me out?  I have an exe that is supposed to launch a dll and pass the dll an argument (in this case an array).

 

At first I was just trying to get the exe to run the dll which launches AutoCad.  Now that it works, I want it to send an array of strings to the dll so that after AutoCad launches it can execute the program and create my drawing (using the info from the array).

 

Here is the .exe.  I've doinked around with it a bunch and this is it's present condition:

Imports System.Runtime.InteropServices

Module Module1
    Declare Sub test Lib "C:\_svn\launchAutoCad\bin\Debug\launchAutoCad.dll" Alias "StartAutoCAD" (ByVal rad As String)

    Sub Main()
        Dim rad As String = "12.5"
        test(rad)
        'launchAutoCad.launchAutoCad.StartAutoCAD(rad)
    End Sub
End Module

 It used to just be the commented out line, but when I wanted to pass an array, it choked on a reference to an AutoCad dll (one of the reference dlls that get loaded into the program in References).  Since the exe didn't have any of those references, it was choking because it did have a reference to my program .dll that did have them.

I removed the reference to my program dll from References in the exe, but am now facing more errors that are over my head.

My dll looks like this:

Public Class launchAutoCad
    Public Shared Sub StartAutoCAD(ByVal rad As String)

 

I have written a number of programs in VB.net for AutoCad, but always ran them after loading in an existing AutoCad session.  My company wants to go another route, so I need to be able to do this.  There are no help docs out there that specifically discusss this.

 

Can you help me out?

Thanks

Message 18 of 34
mgorecki
in reply to: mgorecki

I know it says it's passing a string, but I will eventually want to pass an array.  I was just using "string" as it was quick and easy.

Message 19 of 34

Hi, Tony!

So it is not only I see that Fenton kidding? Smiley Happy

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 20 of 34

Hello?  Pointers?  What should I do??  Anything??

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost