VisualStudio2010 VB.NET COM类解决Regasm注册失败及注册后不能用等疑难杂症(RegAsm注册覆盖32位和64位)(Regsvr32 和Regasm 怎么选)

1、工具选择

1.1 Com组件工具选择Regsvr32 还是 Regasm

Regsvr32用来将非托管代码控件注册为COM组件,Regasm则是.NET下的注册COM组件的工具

1.11 Regsvr32 工具

regsvr32是windows上注册 OLE 控件(DLL 或 ActiveX )的常用命令。注册 OLE 控件可更新 Windows 注册表中文件的位置和功能,从而使程序正常运行。32位系统注册32位控件,64位系统注册64位控件,一般都没有问题。一般容易出问题的是在64位操作系统上注册32位控件。

注意:64 位版本的 Windows 操作系统上有两个版本的 Regsv32.exe 文件。
64 位版本是 %systemroot%\System32\regsvr32.exe
32 位版本是 %systemroot%\SysWoW64\regsvr32.exe

SysWoW64中的“WoW”正是“Windows on Windows”的缩写,表示一个运行在64位操作系统环境下的32位子系统

要在64位操作系统上正确注册一个32位的OLE控件,要确保以下步骤:

  • 管理员身份运行%systemroot%\SysWoW64\regsvr32.exe o.ocx

批处理脚本推荐

reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT
if %OS%==32BIT %windir%\system32\regsvr32.exe "%~dp0Example.ocx"
if %OS%==64BIT %windir%\syswow64\regsvr32.exe "%~dp0Example.ocx"

1.12 Regasm 工具

功能: Regasm.exe(程序集注册工具)读取程序集中的元数据,并将所需的项注册到注册表中

1.121 执行规则

Regasm.exe所在的路径是没有被加载到PATH环境变量中,因此在Dos命令行中输入regasms是无法被识别的。
所以执行规则是:

对于 x86,使用如下路径:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe
C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe

对于 x64,使用如下路径:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe

系统的版本不同,运路径中的数字可能会有一些差异。

1.122 常用的控制开关

语法: RegAsm 程序集名称 [选项]

选项描述
/unregister注销类型
/tlb[:文件名]将程序集导出到指定类型库并注册它
/regfile[:文件名]生成具有指定名称的 reg 文件而不是注册类型。此选项不能与 /u 或 /tlb 选项一起使用
/codebase设置注册表中的基本代码
/registered只引用已注册的类型库
/asmpath:目录在此处查找程序集引用
/nologo禁止 RegAsm 显示徽标
/si lent静态模式。禁止显示成功消息
/verbose显示额外的信息
/? or /help显示此用法消息
1.123 批处理

将批处理bat文件与dll ,dlt放在一块, 管理员权限运行批处理。

@Echo off
REM 切换到bat脚本路径
cd /d %~dp0
REM 取消注册
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe  /unregister %windir%\SysWOW64\ComDltTuningHelper.dll /tlb:%windir%\SysWOW64\ComDltTuningHelper.tlb
C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe  /unregister %windir%\System32\ComDltTuningHelper.dll /tlb:%windir%\System32\ComDltTuningHelper.tlb 
REM 删除文件
del %windir%\SysWOW64\ComDltTuningHelper.dll /q /f /s
del %windir%\SysWOW64\ComDltTuningHelper.tlb /q /f /s
del %windir%\System32\ComDltTuningHelper.dll /q /f /s
del %windir%\System32\ComDltTuningHelper.tlb /q /f /s
REM 复制文件
xcopy /y ComDltTuningHelper.dll %windir%\SysWOW64\
xcopy /y ComDltTuningHelper.tlb %windir%\SysWOW64\
xcopy /y ComDltTuningHelper.dll %windir%\System32\
xcopy /y ComDltTuningHelper.tlb %windir%\System32\
REM 注册Com
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe  %windir%\SysWOW64\ComDltTuningHelper.dll /tlb:%windir%\SysWOW64\ComDltTuningHelper.tlb /codebase
C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe  %windir%\System32\ComDltTuningHelper.dll /tlb:%windir%\System32\ComDltTuningHelper.tlb /codebase
REM 判断反馈
if errorlevel 1 goto err
Echo.
Echo Reg Com Lib Success
goto end
:err
Echo.
Echo Reg Com Lib Failed ,run with admin.
:end
Pause>nul
  1. 首先操作系统不论是32位还是64位,上述批处理都涉及
  2. 先取消注册,如果是首次注册也无所谓,如果是更改后的dll dlt 那么直接用这个也可以,更改后的dll dlt重复注册会提示错误的,要先取消注册
  3. 删除路径下的Com类dll dlt文件
  4. 复制当前路径下的Com类dll dlt文件
  5. 那么就是注册了,/codebase 并指定/tlb:
  6. 剩下的就是判断了,判断注册过程中为何失败。
  7. dll dlt换成你自己的dll名字
  8. Framework版本根据需求自己更换成自己的

2、如何检查DLL文件是否已注册

可以肯定的是,一定是下面的方式!如果结果不符合,那么你的注册是有问题的。

2.1 x64检查

如果你知道COM dll的CLSID
打开注册表的方法: win+r 键入regedit,检查 HKEY_CLASSES_ROOT\CLSID\{CLSID-of-your-COM-component}
在这里插入图片描述

2.2 x86检查

如果你知道COM dll的CLSID
打开注册表的方法: win+r 键入regedit,检查HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{CLSID-of-your-COM-component}
在这里插入图片描述

3、踩坑日记

如果对上面的操作不了解的,可以看看我的踩坑日历,真的是心酸,心酸,阅读了无数的文档,逛了无数的论坛,Debug了无数次,两台电脑反复的测试,注册,取消注册,查看注册表等等等等,只化作了SysWOW64 System32 Framework Framework64

3.1 项目经历

我的项目是通过VB Class Library,然后添加了Com类,添加了注册互操作,然后生成了Com类的dll文件和tlb文件
VB.NET编写Com类注册用到的工具就说Regasm

COM组件与普通的DLL区别在于:

1. COM组件需要注册才能使用,而普通的DLL不需要注册,直接LoadLibrary使用;
2. COM组件通过暴露接口指针被调用,而普通DLL是暴露函数地址被调用。

先说说表现把:
A 电脑编译了 VB Com dll tlb Any CPU 工程,执行了互操作注册
A 电脑编译了MFC调用VB dll的MFC x64工程
A 电脑的操作均为Release
A 电脑Excel引用了%windir%\SysWOW64\ComDltTuningHelper.tlb但是不能正常工作
A 电脑MFC调用了Com dll可以正常工作
将上述内容拷贝到B电脑
B 电脑在执行了3.12的脚本后,注册了Com
B 电脑Excel引用%windir%\SysWOW64\ComDltTuningHelper.tlb能正常工作
B 电脑MFC客户端调用了Com dll不可以工作
A 电脑取消勾选执行互操作注册后,重新编译,发现A电脑MFC也无法正常使用
B 电脑Excel引用tlb的路径必须是SysWow64下面的tlb,System32下的无法引用
A 电脑拷贝B电脑的Excel过来后发现Declare要加上PtrSafe(32位不用加,但是64位要加)(这也是灵感突现的地方)

当没有人能够指引你正向前进的时候,那么反向推理也未尝不可一试!
下面灵魂拷问篇会给你我上面所有犯的错误,和理解盲区

3.1 灵魂拷问

3.11 注册后的Com类dll,我把文件删除了,还能取消注册吗

Com类的注册和取消注册的信息是写在你的dll里面的,所以最好的是取消注册后再删除!从我上面的bat脚本可以看出,我的第一步是取消注册,然后删除文件,再拷贝过去,再注册,这个好处就是,哪怕我没注册,我取消注册也无伤大雅,但是我注册过的话,那么我取消注册再注册的操作一定是合情合理的!

3.12 Com类注册成功后,我的Excel可以正常引用Com的tlb,但是MFC却不能

这里要小心的就是操作系统的位数,可能的是你电脑是64位的操作系统,但是Excel是32位的
在这里我曾经犯了一个很严重的错误,该错误导致我为该错误买单了3天,整整三天,无数次的失败Debug

  1. 我通过VB Class Library(类库工程),加载Com类,然后生成了dll tlb文件(这里注意:执行Com互操作才会生成tlb)
  2. 我通过以下一个错误的脚本,执行了注册
    @Echo off
    cd /d %~dp0
    C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe  /u %windir%\SysWOW64\ComDltTuningHelper.dll /tlb:%windir%\SysWOW64\ComDltTuningHelper.tlb 
    C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe  /u %windir%\System32\ComDltTuningHelper.dll /tlb:%windir%\System32\ComDltTuningHelper.tlb 
    
    del %windir%\SysWOW64\ComDltTuningHelper.dll /q /f /s
    del %windir%\SysWOW64\ComDltTuningHelper.tlb /q /f /s
    del %windir%\System32\ComDltTuningHelper.dll /q /f /s
    del %windir%\System32\ComDltTuningHelper.tlb /q /f /s
    
    xcopy /y ComDltTningHelper.dll %windir%\SysWOW64\
    xcopy /y ComDltTuningHelper.tlb %windir%\SysWOW64\
    xcopy /y ComDltTuningHelper.dll %windir%\System32\
    xcopy /y ComDltTuningHelper.tlb %windir%\System32\
    
    C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe  %windir%\SysWOW64\ComDltTuningHelper.dll /tlb:%windir%\SysWOW64\ComDltTuningHelper.tlb /codebase
    C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe  %windir%\System32\ComDltTuningHelper.dll /tlb:%windir%\System32\ComDltTuningHelper.tlb /codebase
    
    以上的错误是
    1. 关键是对于初学者来说上述错误是很难发现的,尤其是在你发现上述脚本在另一台电脑注册后可以在Excel中使用(x64系统,但是Excel确是32位的),但是在另一台电脑的MFC中无法使用(MFC通过x64 Release后拷贝过去的),但是在本机电脑(也就是生成工程的电脑)MFC中可以使用,但是在本机电脑Excel工程中无法使用(此时Excel中加载的是SysWOW64下的dll tlb,加载system32下的加载不了),这种给人的感觉就是你说我注册不成功吧,但是我在另一台电脑Excel能引用用,你说我注册成功吧,但是我的MFC客户端却不能用
    2. 没搞明白工程勾选互操作Com其实就是正确注册了x64的Com
    3. 没搞明白SysWOW64 System32 究竟哪个是x64 哪个是x86
    4. 没搞明白C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe 不可以注册 64
    5. 错误以为只需要改变路径就可以分别注册32 64位系统

3.13 在排查问题的时候,HKEY_CLASSES_ROOT\CLSID\{CLSID-of-your-COM-component}没有找到内容,就没有怀疑过没有注册成功吗?

如果你再给我一次机会的话,我一定告诉你,HKEY_CLASSES_ROOT\CLSID\{CLSID-of-your-COM-component}找不到你的CLSID,一定是x64位下的Com没注册好!但是这些问题在我逛论坛的时候可没有一个人告诉我,明确的告诉我,它一定是这样子的。那么现在我告诉你,这就是你能节省的时间,为了这个错误,我损失了三天,无疑是误导了我的判断方向。

3.14 Com工程:勾选互操作注册Com本质是什么

勾选互操作注册Com本质就是他能正确注册Com,其实也就是工程能判断到底用Framework 还是 Framework64

3.15 Com类 dll tlb文件放那里注册合适?

推荐将Com类的dll tlb文件放入下列路径,以方便后续维护(移动到该位置及删除是需要管理员权限的)

对于 x86,使用如下路径: C:\Windows\SysWOW64
对于 x64,使用如下路径:C:\Windows\System32

SysWow64文件夹,是64位Windows,用来存放32位Windows系统文件的地方

至于为什么x64 文件夹是System32?

很多朋友在运行某个软件,特别是一些游戏的时候经常会遇到缺少xxx.dll文件,辛辛苦苦从网上下载了这个文件后,到底放到哪个文件夹中呢?特别是在64位操作系统中,到底是放到SystemSystem32还是Syswow64
32位的Windows操作系统可以同时运行32位和16位代码,而64位Windows操作系统可以直接运行64位代码,同时通过使用WoW64(Windows on Windows 64)也能运行32位代码。
32位版本的Windows在如何允许32为和16位代码并肩运行方面有着很复杂的机制,然而64位版本的Windows就不同了,32位代码与64位代码单独运行,有着两个Program Files,有着system32和syswow64两个DLL文件夹,甚至两个注册表。
在32位操作系统的Windows文件夹中,SYSTEM和SYSTEM32两个文件夹,分别用来存放16位和32位的DLL文件。如果按照这个规律,存放64位系统的DLL文件的文件夹应该叫:System64,但实际上存放64位DLL的文件夹依然叫:System32,同时又多了一个SysWow64文件夹现在的软件大多是32位软件,所以默认会将DLL文件放到System32文件夹中,而微软为了保障兼容性,所以无论是32位还是64位的DLL文件都是放到了System32文件夹中。
那SysWoW64文件夹又是干什么用的呢?这是因为32位软件并不能在64位系统中直接运行,所以微软设计了WoW64(Windows-on-Windows 64-bit),通过Wow64.dll、Wow64win.dll、Wow64cpu.dl三个DLL文件进行32位和64位系统的切换来运行32位软件。所以在64位系统中,DLL复制到System32文件夹中即可。

3.16 x64位的系统用的Excel一定是64位的吗

不一定!可能是32位的,所以你Com注册完成后,Excel能用,但是MFC的*.exe(x64)不能用可能就是注册的错误导致的,也就是你单纯的把32位的注册了,但是64位的没有。

两台电脑之间的Excel一个是x86的一个是x64的,那么指定表现效果不同,所以一定确保注册成功!

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CDamogu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值