您基本上必须从外部 C# 进程打开 AutoCAD,即 is discused here 和 here。我建议你制作一个单例,它处理 AutoCAD 进程的打开和关闭,并负责打开/插入/保存/关闭文档(块)。挂钩到 selectionChanged 下拉事件,如果不是,则生成 Autocad。此外,您必须调用 Insert() 或 WblockCloneObjects() 方法才能将块插入当前文档。
private object SpawnCadApplication(string appProgId)
{
var acadType = Type.GetTypeFromProgID(appProgId);
return Activator.CreateInstance(acadType);
}
private bool ApplicationIsInstalled(string appProgId)
{
return Type.GetTypeFromProgID(appProgId) != null;
}
private bool GetRunninApplication(string appProgId, out object cadApp)
{
cadApp = null;
try
{
cadApp = Marshal.GetActiveObject(appProgId);
}
catch (Exception e)
{
}
return cadApp != null;
}
private void ReleaseObject(object obj)
{
try
{
Marshal.FinalReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
}
}
一旦你控制了 AutoCAD,你就可以做出你想要的一切
public void OpenSaveCloseFile(string filePath)
{
object cadApp;
if (!GetRunninApplication(AutoCadProgId, out cadApp))
{
cadApp = SpawnCadApplication(AutoCadProgId);
}
var cadDocuments = cadApp.GetType().InvokeMember("Documents", BindingFlags.GetProperty, null, cadApp, null);
// open a file
var openArgs = new object[2];
openArgs[0] = filePath; // Name
openArgs[1] = false; // ReadOnly
var acDoc = cadDocuments.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, cadDocuments, openArgs, null);
// save the file
acDoc.GetType().InvokeMember("Save", BindingFlags.InvokeMethod, null, acDoc, null);
// close the file
var closeArgs = new object[2];
closeArgs[0] = true; //Save changes
closeArgs[1] = filePath; // Document Name
acDoc.GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, acDoc, closeArgs);
ReleaseObject(acDoc);
}
在当前文档中插入块应该是这样的:
var activeDocument = cadApp.GetType().InvokeMember("ActiveDocument", BindingFlags.GetProperty, null, cadApp, null);
var database = activeDocument.GetType().InvokeMember("Database", BindingFlags.GetProperty, null, activeDocument, null);
var insertArgs = new object[3];
insertArgs[0]=*Objects*;
insertArgs[1]=*Owner*;
insertArgs[2]=*IdPairs*;
database.GetType().InvokeMember("CopyObjects", BindingFlags.InvokeMethod, null, database, insertArgs, null);
但是你必须弄清楚如何填充参数数组。看附图。
Interop 接口中的 CloneObjects 必须对应于 WBlockCloneObjects。
很酷的是,您不必添加任何 Acad 库作为参考。