如何通过C#外部应用程序访问AutoCAD应用程序的特定实例

时间:2013-07-25 10:36:58

标签: c# com autocad

我正在尝试通过其与C#外部应用程序的COM接口获取有关所有正在运行的AutoCAD 2007实例的信息(列出已打开文档的全名)。这是一个代码:

…
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);
}

结果,它找到了与所有ACAD运行实例相对应的正确数量的标记,但仅从“最早”实例中检索文档的名称。看起来所有的标记都引用了单个AutoCAD.AcadApplication对象。有没有办法为每个实例做到这一点?

2 个答案:

答案 0 :(得分:1)

这是“重型”程序(如AutoCAD)的典型行为。 MS Word是另一个例子。它们是单实例应用程序。如果已经运行AutoCAD,那么第二次启动它时,会将命令行传递给第一个实例,要求它打开文档。退出。

所以真的只有一个进程,它打开了多个文档。使用Taskmgr.exe,进程选项卡验证这一点。

答案 1 :(得分:1)

AutoCAD无论如何都只在运行对象表中注册一次,所以沿着这条路走下去无处可去。几年前我就在同一个地方,甚至与Kean Walmsley讨论过这个问题。他向我指出了一种技术,它需要从VBA中的每个AutoCAD会话中对自定义服务运行pseduo-registration,然后让.NET应用程序查看自定义注册。马虎?当然。然而,如果你真的需要让它发挥作用,那么这个概念就是合理的。