在C#的AutoCAD二次开发中,通过以下技巧可以极大提升调试效率,避免频繁重启AutoCAD。
核心技巧:实现不重启调试
.NET的DLL一旦被AutoCAD加载便无法卸载,这是导致修改代码后必须重启AutoCAD的根本原因。解决此问题的核心思路是将业务逻辑与命令注册分离 ,或使用内存加载技术。
方法一:分离命令注册与业务逻辑(LoadX模式)
此方法通过创建一个稳定的"加载器"DLL来注册命令,而将实际业务代码放在另一个可动态重新编译和加载的DLL中。
-
创建稳定的命令加载器项目 (如
MyCommandsLoader)该项目引用
acdbmgd.dll、acmgd.dll等,并包含一个用于初始化注册的类。其代码编译后生成的DLL(如MyCommandsLoader.dll)只需通过NETLOAD命令加载一次。csharpusing Autodesk.AutoCAD.Runtime;
using System.Reflection;
namespace MyCommandsLoader
{
public class Loader
{
[CommandMethod("LoadMyTools")]
public void LoadMyTools()
{
// 动态加载包含实际命令的业务DLL string assemblyPath = @"C:\YourProjectPath\MyBusinessLogic.dll";
Assembly.LoadFrom(assemblyPath);
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("
业务模块加载成功!");
}
}
}
```
-
创建业务逻辑项目 (如
MyBusinessLogic)该项目包含所有具体的功能命令。开发时,修改此项目的代码,重新编译生成新的
MyBusinessLogic.dll。csharpusing Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; namespace MyBusinessLogic { public class MyCommands { [CommandMethod("MyTestCommand")] public void MyTestCommand() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; ed.WriteMessage("
这是动态加载的业务命令!");
// 在此处编写你的核心业务逻辑 }
}
}
```
- 调试流程:
- 首次启动AutoCAD,使用
NETLOAD加载MyCommandsLoader.dll。
* 在AutoCAD中执行LoadMyTools命令,它会动态加载当前版本的MyBusinessLogic.dll。
* 在Visual Studio中修改MyBusinessLogic项目的代码。
* 无需关闭AutoCAD ,直接在VS中重新编译MyBusinessLogic项目,生成新的DLL。
* 回到AutoCAD,再次执行LoadMyTools命令。此时,新的Assembly.LoadFrom会加载新版本的业务DLL,旧版本会被新版本覆盖(从文件系统角度),从而实现代码更新。
* 现在可以测试新的MyTestCommand命令。
方法二:使用专用的不重启调试工具
社区存在一些开源工具,利用Assembly.Load(byte[])进行内存加载等高级技术,封装了上述流程,提供更便捷的体验。
| 工具/方案 | 核心原理 | 优点 | 参考来源 |
|---|---|---|---|
| 自定义 LoadX 类库 | 将命令注册与功能实现分离,通过动态加载更新业务DLL。 | 实现简单,无需第三方工具,概念清晰。 | |
| 开源不重启调试工具 | 采用内存加载技术,可能包含自动重载、调试器附着等增强功能。 | 自动化程度高,可能提供VS插件,进一步提升效率。 |
其他关键调试技巧
-
正确配置Visual Studio调试
- 在项目属性中,将调试启动操作 设置为"启动外部程序",并指向
acad.exe的路径。 - 在"调试"->"选项"中,确保**启用.NET Framework源代码步进** 和启用源服务器支持被取消勾选,以避免调试时跳入.NET框架代码。
- 在"工具"->"选项"->"调试"->"常规"中,勾选"使用托管兼容模式"。
- 在项目属性中,将调试启动操作 设置为"启动外部程序",并指向
-
利用
Editor.WriteMessage进行快速输出调试在无法使用断点时,这是最直接的输出调试信息方式。
csharped.WriteMessage($"
调试信息:变量x的值为 {x}");
```
-
处理
Interop引用问题早期开发中直接引用
Interop.AutoCAD.dll可能导致编译错误和调试不便。更可靠的方式是通过.NET的Marshal.GetActiveObject方法获取正在运行的AutoCAD实例。csharp// ... object acadApp = Marshal.GetActiveObject("AutoCAD.Application"); AcadApplication acadApplication = (AcadApplication)acadApp; // 通过acadApplication对象进行操作 ``` -
使用
try-catch块并输出异常到命令行AutoCAD插件中的未处理异常可能导致CAD无响应或崩溃。务必捕获异常并输出详细信息。
csharp{ // 你的代码 } catch (System.Exception ex) { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage($"
错误:{ex.Message}
堆栈:{ex.StackTrace}");
}
```
总结 :最有效的避免重启技巧是采用**"稳定加载器+动态业务模块"的架构**(方法一),或集成开源的不重启调试工具(方法二)。结合Visual Studio的正确调试配置和代码中的输出调试语句,可以构建一个高效的AutoCAD二次开发调试环境。