我刚刚开始为AutoCAD 2016开发应用程序。我想把我的all加载到一个单独的AppDomain中,这样我就不必一直重启ACAD了。
经过大量的研究和尝试,我最终得到了一个使用System.Addin和System.Addin.Contract的管道解决方案。
对于视图、协定和适配器,我只使用了接口和标准类,如本例中的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");
}
}}
这是我的HostApplication:
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的三个标准Dlls: accoremgd.dll、acdbmgd.dll、acmgd.dll。
在这两个项目中,这些dll都有选项local copy false。如果我启动,我会得到一个异常,程序员找不到文件"accoremgd.dll“,Acad崩溃。
因此,我尝试将选项local copy设置为true,仅用于外接程序。现在它适用于"sayHello"-Methode。
但是当acBlkTbl被初始化时,我得到了一个无效的强制转换异常。
这将是伟大的,如果有人有我的最后一步,使这项工作。同样伟大的是一个工作的例子一定不能用Addinsystem做,我只想做这个工作,而不是一直重新启动acad ^^
谢谢你的帮助,马蒂亚斯
发布于 2016-05-19 22:42:14
我不相信单独的AppDomain会起作用,当你调用AutoCAD对象类型时,它会转到主AppDomain并被搞乱……
因为只想编辑代码而不是重启,你会更好地使用Edit & Continue feature (我相信从2015年AutoCAD上的VC2013开始就可以使用)。
发布于 2016-05-21 00:35:38
这不受支持。AutoCAD是一个非常古老和复杂的程序,并且大多数AutoCAD应用编程接口对象不能以远程方式使用。
请阅读:
在#3中,您可以看到AutoCAD开发团队确认有一些全局变量将阻止这种工作方式。
发布于 2016-05-27 21:05:44
我放弃了解决这个问题的尝试。我目前的“最佳”解决方案是在AutoCAD开始时加载dll。至少我不必通过网络加载每一个dll。如果有人有更好的解决方案,请随时告诉我^^,感谢所有人的回答。马蒂亚斯
https://stackoverflow.com/questions/37326304
复制相似问题