在AutoCad中,二次开发一般选用c#进行编程,c#语言具备完善、强大的api生态和桌面端系统开发生态,能够满足cad插件系统性、复杂性功能开发的需求。
使用c#进行开发的第一步则是在启动插件时,能够自动打开cad且加载插件程序,也就是插件菜单栏和功能已经完好集成在cad功能中,下面来记录cad插件自动挂载的具体实现,主要有两个关键点。
自动加载cad插件在官方的手册中提供了几种不同的方式,经过比较,推荐选择注册表加载的方式,改方式的自动加载逻辑完全在程序后端掌握,自动化程度最高,一键点击配置即可完成插件注册,然后在打开cad就可以使用插件功能了,该方法实现的关键点如下:
关键点一 、打开本机注册表编辑器,获取cad注册的准确路径
然后将cad注册路径和插件dll程序路径分别复制到代码中
[CommandMethod("RegisterCustomApps")]
public void RegisterCustomApps()
{
// 配置需要注册的多个应用程序信息
var applications = new List<ApplicationInfo>
{
new ApplicationInfo
{
AppName = "CadRibbon",
AssemblyPath = "插件dll在本机的路径"
},
new ApplicationInfo
{
AppName = "CadDesign",
AssemblyPath = "插件dll在本机的路径"
}
// 按需添加更多DLL
};
// AutoCAD 2016注册表路径
string sProdKey = @"SOFTWARE\Autodesk\AutoCAD\R20.1\ACAD-F001:804";
try
{
using (RegistryKey regAcadProdKey = Registry.LocalMachine.OpenSubKey(sProdKey, true))
{
if (regAcadProdKey == null)
{
MessageBox.Show("错误:找不到AutoCAD注册表项!");
return;
}
// 获取或创建Applications子键
using (RegistryKey regAcadAppKey = regAcadProdKey.CreateSubKey("Applications", true))
{
foreach (var app in applications)
{
try
{
// 删除旧注册项(如果存在)
if (regAcadAppKey.GetSubKeyNames().Contains(app.AppName))
{
regAcadAppKey.DeleteSubKeyTree(app.AppName);
}
// 创建新注册项并配置参数
using (RegistryKey regAppAddInKey = regAcadAppKey.CreateSubKey(app.AppName))
{
regAppAddInKey.SetValue("DESCRIPTION", $"{app.AppName} 插件", RegistryValueKind.String);
regAppAddInKey.SetValue("LOADCTRLS", 2, RegistryValueKind.DWord); // 自动加载
regAppAddInKey.SetValue("LOADER", app.AssemblyPath, RegistryValueKind.String);
regAppAddInKey.SetValue("MANAGED", 1, RegistryValueKind.DWord); // 托管程序
regAppAddInKey.SetValue("COMMANDS", app.AppName, RegistryValueKind.String);
regAppAddInKey.SetValue("APPNAME", app.AppName, RegistryValueKind.String);
regAppAddInKey.SetValue("APPMODE", 0, RegistryValueKind.DWord);
}
MessageBox.Show($"成功注册:{app.AppName}");
}
catch (System.Exception ex)
{
MessageBox.Show($"注册 {app.AppName} 失败:{ex.Message}");
}
}
}
}
}
catch (SecurityException)
{
MessageBox.Show("权限不足!请以管理员身份运行AutoCAD。");
}
catch (System.Exception ex)
{
MessageBox.Show($"全局错误:{ex.Message}");
}
}
再然后新建一个winform程序,加一个配置的按钮调用该方法就行了,配置完启动cad插件就自动注册上去了。
关键点二 、打开cad加载插件后,自动挂载插件菜单栏,需注意线程问题,使用AutoCAD的CommandEnded事件,在主线程上触发挂载插件菜单栏操作。
在插件菜单栏的dll程序下新建一个类,继承AutoCAD的IExtensionApplication接口,用于打开cad时自动执行挂载插件菜单栏的代码
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Sedc.AutoCad.Ribbon;
[assembly: ExtensionApplication(typeof(Sedc.AutoCad.Ribbon.AcadNetApp))]
namespace Sedc.AutoCad.Ribbon
{
public class AcadNetApp : IExtensionApplication
{
public void Initialize()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
if (doc != null)
{
doc.Editor.WriteMessage("\n准备加载程序...........\n");
// 监听命令结束事件
doc.CommandEnded += Doc_CommandEnded;
}
}
private void Doc_CommandEnded(object sender, Autodesk.AutoCAD.ApplicationServices.CommandEventArgs e)
{
// 取消事件订阅,确保只执行一次,使用AutoCAD的CommandEnded事件,在主线程上触发
((Document)sender).CommandEnded -= Doc_CommandEnded;
try
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
if (doc != null)
{
doc.Editor.WriteMessage("\n加载程序中...........\n");
RibbonDll.LoadRibbonBar();
doc.Editor.WriteMessage("\n加载完成!\n");
}
}
catch (System.Exception ex)
{
System.IO.File.AppendAllText(@"C:\Temp\AutoCADError.log",
DateTime.Now.ToString() + ": " + ex.ToString() + Environment.NewLine);
}
}
public void Terminate()
{
RibbonDll.LoadRibbonBar();
}
}
}