This topic has been raised a few times, and Adam Nagy, from our DevTech EMEA team, sent a technical response recently with code that I decided to use as the basis for this post.
Developers typically want to either integrate functionality into AutoCAD (using its plug-in architecture to add commands, user-interface elements, objects, etc.), or to drive it, automating common tasks. Clearly the line can get blurred between these two areas, but today I’m going to focus on the second category.
To help with later explanations, I’d like to introduce two types of application interaction:
In this situation we have two separate executables trying to communicate. Imagine you have an EXE and you want to drive AutoCAD. You need to find some way to launch AutoCAD and communicate with it – typically using COM or, before that, DDE. The communication is, by definition, done via Inter-Process Communication (IPC), which is a very inefficient way to send large chunks of data. This is why old ADS and external VB applications ran (or run) so slowly.
When your code is packaged inside a DLL (whether an ActiveX DLL defined in VB6, an ObjectARX module or a .NET assembly), the communication with the host process (AutoCAD) is much more efficient – data structures can be passed by pointer or reference rather than squirting the information through the inefficient marshalling of IPC.
Most of AutoCAD’s current APIs are designed to be used “in-process” – this includes LISP, ObjectARX and AutoCAD’s .NET API. Given the availability of .NET Remoting, people often hope or expect AutoCAD to be drivable via .NET “out-of-process”, but this is not how the managed API was designed: it is really a wrapper on top of ObjectARX, whose performance is based on direct access to objects via pointers, and this simply does not extend to work across process boundaries. One of the great features of COM Automation is that it was designed to work either out-of-process (from an external EXE) or in-process (from VBA or by calling GetInterfaceObject() to load a VB6 ActiveX DLL). This is still the best way to drive AutoCAD from an external executable.
I generally recommend not trying to pass too much information across the process boundary: if you need to drive AutoCAD from an external executable, simply launch it (or connect to a running instance, if that’s an option) and then load an in-process module to do the heavy lifting from within AutoCAD’s process space.
The following code shows how to do just that, using C#. It tries to connect to a running instance of AutoCAD (this is optional – you can easily adjust the code only to launch AutoCAD), and failing that launches it. Once there’s a running instance we make it visible and run a custom command. My recommendation is to set up demand-loading for your application – either to load it on AutoCAD startup or when a command is invoked – and then to run a command defined in your module.
You will need to add a reference to the “AutoCAD Type Library” from your application, as well as including these assembly references:
This C# code can be added to an “on-click” event handler for a button (for example) or another function that makes sense in the context of your application.
// "AutoCAD.Application.17" uses 2007 or 2008,
// whichever was most recently run
// "AutoCAD.Application.17.1" uses 2008, specifically
const string progID = "AutoCAD.Application.17.1";
AcadApplication acApp = null;
Type acType =
"Cannot create object of type \"" +
progID + "\""
if (acApp != null)
// By the time this is reached AutoCAD is fully
// functional and can be interacted with through code
acApp.Visible = true;