C#写的COM组件注册问题兼论微软Regasm注册的BUG
工作中自己用C#写了专门读写EXCEL(不需要OFFICE环境,直接读原始文件,速度快)的COM组件,在使用过程中,发现原先的注册程序是有问题的。网上也有同样的网友碰到这个问题,但都没找到合适的解决办法。现在我把问题和解决方法都写出来,供读者参考。
其实问题都是出在COM组件的注册上,根本的原因就是REGASM /u 命令有些时候是无效的! 我这边提供的注册过程是先卸载,然后注册。原先的注册过程是: (1) regasm /u XLSRW.dll (2) regasm XLSRW.dll (/codebase) 实际上,上述反注册命令是有问题的,具体例子如下: (XLSRW.dll 的CLSID 是61D993F1-CB5E-444d-BB3D-EB2BEA4ACB8D)
上图中我分别用上面的过程注册了1.0.0.2和1.0.0.3版本,然后发现用1.0.0.2版本的XLSRW.dll再注册使用是无效的,因为程序默认仍然去找1.0.0.3版本的XLSRW.dll(因为注册表项中仍然存在1.0.0.3项)。程序搜索XLSRW.dll的过程是先查找注册时的路径下的XLSRW.dll,如果发现版本不对或者没有,就在程序的当前路径下寻找,找到后就加载该DLL。这无疑对COM组件的版本升级带来了灾难。
解决该问题的办法是修改COM的注册过程,直接删除COM组件对应的注册表项(COM组件的注册路径都为 HKEY_CLASSES_ROOT/CLSID 下):
(1) REG DELETE "HKEY_CLASSES_ROOT/CLSID/{61D993F1-CB5E-444D-BB3D-EB2BEA4ACB8D}" /f
(2) REGASM XLSRW.dll /codebase
写成控制台程序的代码如下:(main.c)
#include <windows.h>
void main()
{
WinExec( "REG DELETE /"HKEY_CLASSES_ROOT//CLSID//{61D993F1-CB5E-444D-BB3D-EB2BEA4ACB8D} /" /f",SW_HIDE);
Sleep(100);
WinExec( "Regasm XLSRW.dll /codebase ",SW_HIDE);
}
至此,问题已经得到了解决。 读者们在更新c#写的COM组件版本时用上面的注册方法就可以解决你们的问题了。更改的地方只有COM组件对应的CLSID和对应的COM组件名字。