标签:
CAD.Net | 发表时间:2020-05-15 12:17:24 | 更新时间: 2020-05-15 12:29:02 | 阅读数:1529 | 评论数:1 | 字数:1734
.NET开发AutoCAD测试程序时的效率问题,在2011年我的一篇博客《
VB.Net二次开发AutoCAD程序调试的一个小技巧》里就吐槽过。相对于VBA来说,.NET开发AutoCAD时运行测试过程是很复杂低效的。VBA运行很简单,修改代码后,直接在AutoCAD里面运行宏(或命令)就行了,修改代码和运行几乎互不影响。而.NET开发时,想要测试程序就复杂多了,一般要经过以下过程:(1)编译程序生成dll;(2)启动AutoCAD【所谓的外部程序】;(3)在AutoCAD里使用netload命令手工加载编译好的dll;(4)输入自定义的命令运行程序进行测试。
——因为AutoCAD启动比较慢,加上还要输入CAD命令加载dll,所以测试程序显得很麻烦。然而AutoDesk特别反人类的设计是,AutoCAD只有加载dll的功能,却没有卸载dll的功能。也就是加载dll后,文件一直是被占用的,只有关闭AutoCAD才会释放dll文件。而文件被占用,就不能在修改代码后再次编译。
上面提到的2011年的博客介绍了几种方法加快测试速度,虽然有一定的作用,但总还是不够高效。
接下来介绍的方法特别高效,几乎媲美VBA。除非AutoCAD能够提供原生的卸载dll的方法,那么这个方法是理论上最高效的了。(注:这个方法来源于网络,详见引用来源[1])
这个方法基本的思想是:
用一个dll把实际要测试的dll复制到内存里再加载,就可以避免文件被占用的问题,也就可以避免测试时频繁关闭打开AutoCAD,从而极大的提高测试效率。
来自名经论坛,见引用来源[1]
引用来源[1]详细介绍了使用C#写这个dll的方法,这里我们用VB.NET来实现。用VB.NET来写,核心代码2行即可,代码如下。

核心代码只有2行,第一行是
Dim buffer = System.IO.File.ReadAllBytes(file_dir)
,即将实际要测试的dll读入内存;第二行是
Dim assembly As Assembly = Assembly.Load(buffer)
,我不太理解这句话,作用大概是将内存中的dll加载到AutoCAD,这个时候dll文件被释放了,不再被占用。
引用来源[1]用文件对话框的方式选择实际要测试dll的路径,我想大可不必,因为这个dll路径是相对固定的,不妨将路径直接写在代码里,或者更通用一些的话,写到ini文件里也可以,这里就不深入了。
根据引用来源[1]的说法,上面介绍的方法有个问题,那就是通常情况下VS编译的dll版本号是固定的,而AutoCAD会识别这个版本号,如果是相同的版本号的话,内存中的dll会加载失败。
解决方法是,修改【MyProject】【应用程序】【程序集信息】【程序集版本】,如下:

但是这时候又出现效率问题了:每次编译都要手动改这里,很麻烦。好在是,可以通过修改程序“My Project”文件夹的“AssemblyInfo.vb”文件来解决这个问题,即将
Assembly:AssemblyVersion("1.0.0.0")
修改为
Assembly: AssemblyVersion("1.0.*")

这时候编译dll出现了错误,而错误指向刚修改的
Assembly: AssemblyVersion("1.0.*")
,这个错误在引用来源[1]中并未遇到,引用来源[2]介绍了解决方法,即修改程序根目录下的.vbproj文件的Deterministic修改为false,如下图:

到这里,这个dll就做好了。打开AutoCAD,用netload命令加载此dll,然后输入nnn命令(本文的例子中自定义了nnn命令),就成功加载了实际要测试的dll了,并且可以多次加载而不用关闭AutoCAD也不会占用真正的dll文件,从而极大的提高了测试的效率。
引用来源:
[1]
AutoCAD.net二次开发netload不能卸载问题解决方法(需QQ登录)
[2]
[assembly: AssemblyVersion("1.0.1.*")]指定版本字符串不符合所需格式 - major[.minor[.build[.revision]]]
完成于:2020年04月22日
发表于:2020年05月15日