How to get access to specific instance of AutoCAD application via C# external application

StackOverflow https://stackoverflow.com/questions/17855665

  •  04-06-2022
  •  | 
  •  

Question

I’m trying to get information (list full names of opened documents) about all running instances of AutoCAD 2007 through its COM interface with C# external application. Here’s a code:

…
using AutoCAD = Autodesk.AutoCAD.Interop;
using System.Runtime.InteropServices.ComTypes;
…
[DllImport("ole32.dll")]
extern static IntPtr CreateBindCtx(IntPtr reserved, out IBindCtx ppbc);
…
static void ListACADDocs()
{
    IntPtr HRESULT;
    IBindCtx objCtx = null;

    HRESULT = CreateBindCtx(new IntPtr(0), out objCtx);

    IRunningObjectTable objRot = null;
    objCtx.GetRunningObjectTable(out objRot);

    IEnumMoniker RunningMonikers = null;
    objRot.EnumRunning(out RunningMonikers);

    RunningMonikers.Reset();

    IntPtr pointerFetchedMonikers = IntPtr.Zero;
    IMoniker[] monikerContainer = new IMoniker[1];
    String strDisplayName;

    Object COMObject = null;
    List<Object> colACADInstances = new List<Object>();

    while (RunningMonikers.Next(1, monikerContainer, pointerFetchedMonikers) == 0)
    {
        monikerContainer[0].GetDisplayName(objCtx, null, out strDisplayName);
        objRot.GetObject(monikerContainer[0], out COMObject);

        //AutoCAD.Application.17 class ID: {28B7AA99-C0F9-4C47-995E-8A8D729603A1}

        if (strDisplayName == "!{28B7AA99-C0F9-4C47-995E-8A8D729603A1}")
            colACADInstances.Add(COMObject);
    }

    foreach (Object obj in colACADInstances)
        foreach(AutoCAD.AcadDocument doc in
            ((AutoCAD.AcadApplication)obj).Documents)
            Console.WriteLine(doc.FullName);
}

In result, it finds correct number of monikers that corresponds to all ACAD running instances, but retrieves documents’ names from the “earliest” instance only. It looks like all monikers refer to single AutoCAD.AcadApplication object. Is there any way to do that for every instance?

Was it helpful?

Solution

AutoCAD only registers once in the Running Object Table anyway, so going down that road gets you nowhere. I was in this exact same spot a few years ago, and even opened up a discussion with Kean Walmsley about it. He pointed me to a technique that required running a pseduo-registration to a custom service from inside each AutoCAD session from VBA, and then having your .NET application look to that custom registration. Sloppy? Definitely. However the concept is sound if you really need to get it to work.

OTHER TIPS

This is typical behavior for "heavy" programs, like AutoCAD. MS Word is another example. They are single-instance apps. If you already have AutoCAD running then the second time you start it, it passes the command line to the first instance to ask it to open the document. And exits.

So there really is only one process, it has multiple documents opened. Use Taskmgr.exe, Processes tab to verify this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top