gsteven 发表于 2010-6-1 11:47:00

再试COM与.NET结合(测试源码)

本帖最后由 作者 于 2010-6-2 11:15:24 编辑 <br /><br /> <p>.NET就只能做dll嵌入CAD使用,也学习了kean的专题,为了在我目前的CS程序中能够实现多版本,并且使用.NET技术。</p>
<p>总结如下:</p>
<p>1 C#无法做标准COM组件</p>
<p>2 用.net开发的dll(假设叫<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>)必须位于CAD安装目录内,如<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009,因为.net的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">acdbmgd</font>,<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">acmgd</font>不允许复制本地,而且要被<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>引用。</font></p>
<p>3 <font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>必须在注册表中注册,使用<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">RegAsm.exe</font>注册,在<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727</font>内,其中codebase项,如果CS程序也放在<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009</font>,则不比填写,否则必填。不管CS程序目录内是否有<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll。</font></p>
<p>3 调用<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>的CS程序必须通过<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">app.GetInterfaceObject(ProgID),app就是CAD应用程序,为了实现多版本,建立app建议使用反射,而不要去引用com库。</font></p>
<p>4 <font style="BACKGROUND-COLOR: #ffffff" face="Verdana">app.GetInterfaceObject(ProgID)可以返回object,然后全部使用反射实现<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>的每一个方法,如object <font style="BACKGROUND-COLOR: #ffffff" face="Verdana">ox.GetType().InvokeMember("AddNumbers", BindingFlags.InvokeMethod, null, ox, args);</font>;也可以将<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>引用到CS程序,并且复制本地,<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">app.GetInterfaceObject(ProgID)</font>返回一个接口或者一个类,如返回接口,则类必须继承于该接口,如<font style="BACKGROUND-COLOR: #ffffff" face="Verdana"><font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.</font>class.AddNumbers(i, j)或者<font style="BACKGROUND-COLOR: #ffffff" face="Verdana"><font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.</font><font style="BACKGROUND-COLOR: #ffffff" face="Verdana">interface</font>.AddNumbers(i, j),</font></font></font></p>
<p>5 步骤4的后种方法实际上是,对象建立是用的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009</font>的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll,而定义则使用复制本地的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll,注意这两个dll一模一样的</font></font></p>
<p>6 CS程序安装的时候,可以将CS程序目录全部放在<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009</font>,这样不需要注册codebase项,但这样不好吧,谁的程序不是单独建文件夹;</p>
<p>或者CS放其他文件夹,将其中的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>复制到<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009</font>,注册表可以自己往里面写,别忘了加上codebase项,也可以通过<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">System.Diagnostics</font>的process类使用<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">RegAsm.exe</font>来注册(方法网上可查)</p>
<p>7 本来想把<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>做成强名放入GAC,(这样不需要注册codebase)发现不行,因为<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">acdbmgd</font>,<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">acmgd</font>没有强名。即使做成了也不行,因为.net的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">acdbmgd</font>,<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">acmgd</font>不允许复制本地,运行时肯定会出现加载<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">acdbmgd</font>,<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">acmgd失败</font>。</p>
<p>8 <font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>作为工具性的类库,负责处理由CS程序发送的参数,并实现成图形。而不是只能作为dll导入cad,应该让他被其他程序应用,实现它的价值。</p>
<p><font color="#ff0000">希望有人能够补充一下,我觉得这样开发.net太麻烦了,希望有好的方法。</font></p>
<p><font color="#ff0000">刚才试验了一下,codebase不必填写(前提是CS程序中有它),只要<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009有<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font>即可,没有就报错,这样也许会简单一些。</font></font>&nbsp;</p>
<p>9 通过监视运行时的已加载程序集,发现在开始就加载了CS程序中的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll,在通过反射建立CAD应用程序后加载了GAC的CAD<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">Autodesk.AutoCAD.Interop,</font></font></p>
<p>始终未加载<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009</font>的任何程序集,但是<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009必须有</font><font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll</font></p>
<p>10 同时查看发现<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">C:\Program Files\AutoCAD 2009</font>的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1.dll被CAD给占用了,因为CAD不关闭,就不能删除它,而且只要一打开AutoCAD 2009,这个文件就不能删除了</font></p>
<p><font color="#ff0000">11 附件是源代码,发现如果<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">AutoCADCom1的<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">Commands</font>类继承了<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">INumberAddition</font>或者<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">INumberAddition2</font>接口,在运行接口对应的那个方法时就会报错,无法将COM_OBJECT转为接口!但是如果这个类的这个方法是自己的,不是继承接口的,就不会报错。</font></font></p>
<p>&nbsp;</p>
<p>&nbsp;</p>

雪山飞狐_lzh 发表于 2010-6-1 20:39:00

<p>总结的不错,呵呵</p>
<p>当然,能附上测试的项目最好</p>
<p>不过,总的感觉,用C#做Com调用,也许真的很复杂,用VBNet也许会方便点?</p>

gsteven 发表于 2010-6-1 21:47:00

本帖最后由 作者 于 2010-6-2 9:14:11 编辑 <br /><br /> <p>毕竟C#更加专业一些。</p>
<p>最近通过反射我已经实现了AutoCAD和Excel的com调用,我的CS程序直接引用我做的Tools.Acad.dll和Tools.Excel.dll就可以了,不再需要引用Excel和CAD的COM了,只要本机安装了CAD2000到2011的任何一个版本和Excel2000到2010的任何一个版本,都可以用。Tools.Acad.dll和Tools.Excel.dll就像Excel和CAD的使用方法就和com一样。目前只是实现了我常用的功能,还有大部分功能基本不用,就没去管它。都是因为客户版本从2004到2009都有人用,没办法,只能这么干,要不早就用.NET了。</p>

wylong 发表于 2010-6-3 10:14:00

能否提供Tools.Acad.dll和Tools.Excel.dll

gsteven 发表于 2010-6-4 00:03:00

<p>Tools.Acad.dll和Tools.Excel.dll 是作为商业产品的一部分,无法提供。也是我辛苦2个星期才想到和作出来的。</p>
<p>思路很简单的:仿照excel的一个com库,cad的两个com库,对照excel和cad对象模型图,逐个的反射所有类的方法,属性,索引器。</p>
<p>excel简单一些,cad复杂一些。</p>

wylong 发表于 2010-6-4 08:26:00

<font color="#61b713" face="Verdana"><b>感谢gsteven提供思路</b></font>

游天居士 发表于 2010-6-7 21:43:00

<p>支持了。我向楼主学习</p>

zhengjian211 发表于 2011-10-31 20:31:23

谢谢提供思路!

陈词滥调的爱 发表于 2014-3-5 16:39:20

对于第2条有些疑问,好像C#的dll不必放到AutoCAD的安装目录中吧,因为当CAD加载了DLL后,这个dll的当前运行目录应该就是cad的目录了,它可以自动找到所引用的dll的。

SWAYWOOD 发表于 2014-3-9 14:28:03

可以肯定的是,楼主的这种做法在全世界也算是先进的。
我查了Autodesk Developer Network DevBlog,kean's blog, theswamp forum都没有 这么搞的。
页: [1] 2
查看完整版本: 再试COM与.NET结合(测试源码)