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

is there a better way?

6 REPLIES 6
Reply
Message 1 of 7
moabiker31
291 Views, 6 Replies

is there a better way?

VB.net 2005 stand alone exe that communicates with AutoCAD 2002-2007. When our vb.net app starts, it tells AutoCAD to start. Sometimes AutoCAD doesn't load, which causes our app to not load. During those times, sometimes it returns "FATAL ERROR: Unhandled Access Violation Reading"; sometimes there is not an error returned. AutoCAD is being started with the following code:

Public WithEvents ACADApp as AcadApplication

private sub StartAcad()
ACADApp = new AcadApplication
end sub

The app requires that AutoCAD cannot be running when our app starts so I don't need to worry about using the existing AutoCAD process (GetActiveObject("AutoCAD.Application")).

Since this way isn't working 100% of the time, I'm wondering if there's a better way to do it.
6 REPLIES 6
Message 2 of 7
cgay
in reply to: moabiker31

Try This:

'Top of code module
Option Strict Off

'In code module
Sub LaunchAutoCAD()
Dim acadapp As Object
acadapp = CreateObject("AutoCAD.Application")
acadapp.Visible = True
System.Runtime.InteropServices.Marshal.ReleaseComObject(acadapp)
acadapp = Nothing
End Sub

The reason I turned option strict to off is to allow late binding.

Regards,
C
Message 3 of 7
Anonymous
in reply to: moabiker31

Probably the most "straightforward" (and the least error prone) way is
autoloading your managed library into AutoCAD via Registry. Such apporach is
usually tied to installer of some kind, which sets the registry up for the
end-user.

See more at: http://discussion.autodesk.com/thread.jspa?messageID=4531456

This has it's pros and cons, of course, depending on overall deployment
strategy.

Regards,
Maksim Sestic

wrote in message news:5330679@discussion.autodesk.com...
VB.net 2005 stand alone exe that communicates with AutoCAD 2002-2007. When
our vb.net app starts, it tells AutoCAD to start. Sometimes AutoCAD doesn't
load, which causes our app to not load. During those times, sometimes it
returns "FATAL ERROR: Unhandled Access Violation Reading"; sometimes there
is not an error returned. AutoCAD is being started with the following code:

Public WithEvents ACADApp as AcadApplication

private sub StartAcad()
ACADApp = new AcadApplication
end sub

The app requires that AutoCAD cannot be running when our app starts so I
don't need to worry about using the existing AutoCAD process
(GetActiveObject("AutoCAD.Application")).

Since this way isn't working 100% of the time, I'm wondering if there's a
better way to do it.
Message 4 of 7
moabiker31
in reply to: moabiker31

Thanks. I'm going to try it.
Message 5 of 7
cgay
in reply to: moabiker31

Maksim,

I agree that this would be the least error prone method, but the OP is trying to work with AutoCAD 2002-2007. '02 & '04 don't have the capability to load managed extensions to AutoCAD. So that leaves COM interop.

moabiker31,
This is a complex issue. Ideally, you would create a different project for each version so you could reference the COM type libraries for each one. This also means that you need a new version for each service pack that comes out for each version. But the benefit that VB allows is turning Option Strict Off to allow late binding. This means that you also should remove the references to AutoCAD in the project. It also means you will lose intellisense, so do this last.

Alternately, you could use the TlbImp tool that comes with the .NET framework to generate Interop Libraries for all versions of AutoCAD, and give each set (AutoCAD TLB and ObjectDBX TLB) different namespaces
I.E.
AutoDesk.AutoCAD.200x.Interop for the AutoCAD.tlb where x is the version.
and
AutoDesk.AutoCAD.200x.Interop.Common for the AXDBLib.tlb, again where x is the version.

Then reference all of the generated Interop Libraries.

Next, create a class in your project for each version of AutoCAD you need to support.

Define an interface
Public Interface IAcadAutomation
Sub DoWork()
End Interface

Each class should look like so...

'Begin Class File
'x = the version of AutoCAD
Imports AutoDesk.AutoCAD.200x
Imports AutoDesk.AutoCAD.200x.Common

Public Class AutoCAD200x : Implements IAcadAutomation

Private mAcadApp As Autodesk.AutoCAD.200x.Interop.AcadApplication = Nothing

Public Sub New(ByVal AcadApp As Object)
m_Acadapp = directcast(acadApp , Autodesk.AutoCAD.200x.Interop.AcadApplication)
End Sub

Public Sub DoWork() Implements IAcadAutomation.DoWork
'Do the Work here
End Sub
End Class
'End Class File

and in ONE module, turn option strict off, load "AutoCAD.Application", check the version attribute and create an instance of the class that corrosponds with the version string returned. (just like the code i posted before)

You could put all your code that communicates with AutoCAD in the module that loads AutoCAD (Option Strict Off) and add a variable to each function which hold the autocad application as an object (late binding, no intellisense) OR you could but the code in each of the custon class modules (early binding, intellisense) but you will need to update all code in each class every time you make a change to one version.

There may also be a way to load the references of the current AutoCAD version when your App loads, but I don't have any experience there. I'm not even sure if the method I described above will work, but its a starting point.

Let us know how you make out,
C
Message 6 of 7
moabiker31
in reply to: moabiker31

Thanks for the time and effort you put into this reply CougerAC.

We're upgrading our vb6 project vb.net. We currently have our app setup the way you described in the first example by having a project for each version of AutoCAD. I didn't know about using the tlblmp tool to create my own libraries - learn something new every day. I will test the late binding approach since we're experiencing much slower performance times once we send the job to AutoCAD - that interop wrapper to get .net to communicate with activex/com is slow and I've read a couple places that late binding will increase performance so it's worth a try.

Thanks again.
Message 7 of 7
cgay
in reply to: moabiker31

Well, performance issues could be a problem for complex projects. The best way to get performance is to create a managed extension to AutoCAD. Unfortunately, this is only available to versions 2005 and up, but it will load in-process. Also, you could convert your Interop code to use the Managed Extensions to AutoCAD instead of the COM-Interop libraries. This will also provide a speed increase, but is only feasible with 2006 and up. AutoCAD does have a Managed API for 2005, but it is missing many features. Even 2006 may not have everything you need, but a little searching in this group should answer many questions.

Another approach is to use VBA within AutoCAD. This is also in-process, and most of your VB6 code should work.

And finally, you could make your VB6 project a DLL, expose some Public Interface to COM, Reference it in AutoCAD VBA, and create an AutoCAD VBA Macro that instantiates it. Result: In-process VB6 dll. I think you could also do this from a .NET dll, but I've never tried and I am not too sure if there will be a speed increase due to the Interop, but it should be faster than a .NET Exe in any case.

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