【问题标题】:Autocad & System.Addin, FileNotFoundException for Autocads basic dllsAutocad 和 System.Addin,Autocads 基本 dll 的 FileNotFoundException
【发布时间】:2016-09-16 12:22:38
【问题描述】:

我刚开始为 AutoCAD 2016 开发应用程序。我想将我的 DLL 加载到单独的 AppDomain 中,这样我就不必一直重新启动 ACAD。

经过大量研究和尝试,我最终得到了一个管道解决方案 使用 System.Addin 和 System.Addin.Contract。

我只使用 Views Contract 和 Adapters 的接口和标准类,就像这个例子中的 here

这是我的插件,其中包含一种将 Hello 写入 Acad 编辑器的方法和第二种绘制线条的方法。

using System.AddIn;
using CADAddinView;
using Autodesk.AutoCAD.EditorInput; 
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;

namespace CADAddIn
{
[AddIn("cadAddIn", Version = "1.0.0.0")]
public class CADAddIn : ICADAddinView
{
    public void drawLine()
    {
        Document acDoc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
        Database acCurDb = acDoc.Database;

        using (DocumentLock acLckDoc = acDoc.LockDocument())
        {
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                DBObject blkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead);
                BlockTable acBlkTbl = blkTbl as BlockTable;

                BlockTableRecord acBlkTblRec = (BlockTableRecord)acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                Polyline acPoly = new Polyline();
                acPoly.SetDatabaseDefaults();
                acPoly.AddVertexAt(0, new Point2d(0, 0), 0, 0, 0);
                acPoly.AddVertexAt(0, new Point2d(100, 100), 0, 0, 0);

                acBlkTblRec.AppendEntity(acPoly);
                acTrans.AddNewlyCreatedDBObject(acPoly, true);

            acTrans.Commit();
            }
        }
    }

    public void sayHello()
    {
        Editor ed = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument.Editor;
        ed.WriteMessage("Hello");
    }
}

}

这是我的主机应用程序:

using System.AddIn.Hosting;
using System.Windows.Forms;
using CADHostView;
using System;
using System.Collections.ObjectModel;
using Autodesk.AutoCAD.Runtime;

namespace CADHost
{
public class CADHost
{
    [CommandMethod("sayHello")]
    public static void sayHello()
    {
        string addInPath = Environment.CurrentDirectory + "\\Pipeline";
        string[] warnings = AddInStore.Update(addInPath);
        foreach (string warning in warnings)
        {
            MessageBox.Show(warning);
        }

        Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(ICADHostView), addInPath);

        if (tokens.Count == 0)
        {
            MessageBox.Show("No AddIn found.");
        }
        else
        {
            AddInToken cadToken = tokens[0];
            ICADHostView cadApp = cadToken.Activate<ICADHostView>(AddInSecurityLevel.Host);

            cadApp.sayHello();
        }
    }

    [CommandMethod("drawLine")]
    public static void drawLine()
    {
        string addInPath = Environment.CurrentDirectory + "\\Pipeline";

        string[] warnings = AddInStore.Update(addInPath);
        foreach (string warning in warnings)
        {
            MessageBox.Show(warning);
        }

        Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(ICADHostView), addInPath);

        if (tokens.Count == 0)
        {
            MessageBox.Show("No AddIn found.");
        }
        else
        {
            AddInToken cadToken = tokens[0];
            ICADHostView cadApp = cadToken.Activate<ICADHostView>(AddInSecurityLevel.Host);

            cadApp.drawLine();
        }
    }
}

}

这两个应用程序都引用了来自 Acad 的三个标准 Dll: accremgd.dll、acdbmgd.dll、acmgd.dll。

在这两个项目中,这些 dll 都具有选项 local copy false。 如果我开始然后我得到一个异常,程序找不到文件“accoremgd.dll”并且Acad崩溃。

所以我尝试为插件设置选项本地副本为真。 现在它适用于“sayHello”-Methode。

但是当 acBlkTbl 被初始化时,我得到了一个无效转换异常。

如果有人能帮我完成这项工作,那就太好了。 同样很棒的是不能使用 Addinsystem 制作一个工作示例 我只想让这项工作不要一直重新启动 acad^^

感谢您的帮助 马蒂亚斯

【问题讨论】:

  • 如果有人感兴趣,我也可以通过邮件发送孔项目进行测试。

标签: c# .net dll autocad


【解决方案1】:

我放弃了解决这个问题的尝试。我目前的“最佳”解决方案是在 AutoCAD 启动时加载 dll。至少我不必对每个 dll 进行网络加载。 如果有人有更好的解决方案,请随时告诉我^^ 感谢所有回答。马蒂亚斯

【讨论】:

    【解决方案2】:

    不支持。 AutoCAD 是一个非常古老且复杂的程序,大多数 AutoCAD API 对象不能远程使用。

    请阅读:

    1. http://through-the-interface.typepad.com/through_the_interface/2008/09/tired-of-not-be.html
    2. http://forums.autodesk.com/t5/net/netload-is-there-a-net-unload-command/td-p/2404002
    3. https://www.theswamp.org/index.php?topic=38675.0

    在#3 中,您可以看到 AutoCAD 开发团队确认有一些全局变量会阻止以这种方式工作。

    【讨论】:

    • 我也遇到过这个问题,并且已经放弃了使用 C# 寻找解决方案的尝试。自动取款机。我正在研究一个 autolisp 程序,在那里我可以达到与卸载 dll 类似的效果。在星期一进行一些测试后,我会及时通知您
    【解决方案3】:

    我不相信单独的 AppDomain 会起作用,当您调用 AutoCAD 对象类型时,它会转到主 AppDomain 并搞砸......

    由于只想编辑您的代码而不重新启动,您最好使用Edit & Continue feature(我相信自 AutoCAD 2015 上的 VC2013 起可用)。

    【讨论】:

    • 我会试试这个,但我想尝试完成这个。我又测试了一些东西,看起来我必须做一些事情才能从 Acad 获取信息。一切正常,直到我“询问”图纸中的信息。 (getObject ...)
    • 确实是这个问题,第二个AppDomain不会和主AppDomain(AutoCAD主)通信。事实上,我们尝试了许多不同的方法来从 AutoCAD 中卸载 .DLL(程序集),但找不到方法……抱歉……
    • 好的,但也许你可以告诉我,只是为了理解,为什么 sayHello - Methode 可以工作,而 addin-dll 在调用 sayHello 后是“免费的”...
    • 可能是因为您没有调用“真正的”AutoCAD 对象...事实上,大多数 API 都是 C++ API 之上的薄层,用于访问深度 acad 对象,但还有一些其他部分(如命令方法) 在 .NET 中完全实现
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多