我们有一个用 VB.NET 开发的 COM 组件(我们称之为 MyLib),供我们的 Access 应用程序(我们称之为 MyApp)使用。为此,我们需要使用生成的 MyLib.dll 和 MyLib.tlb 文件进行 COM 注册。当我将这两个文件安装到我们的 MyApp 文件夹中时,一切正常,COM 函数被正确调用。但是,当我将 dll 安装到一个公共文件夹时,我在标题中提到了一个错误 - 我这样做的原因是因为我们希望允许在同一台机器上安装不同版本的 MyApp。所以如果 COM 组件没有改变,我们当然希望在这些不同的版本之间共享它,让 Windows 来做引用计数。
我不确定应该将 MyLib.tlb 文件放在 MyApp 的安装文件夹中,还是与 MyLib.dll 相同的公共文件夹中。但无论如何,我尝试了两个位置,它们都给出了相同的错误。我尝试比较将 MyLib.* 放入 MyApp 文件夹的情况和将 MyLib.dll 放入公共文件夹的情况之间的注册表文件。除了我试图在 HKCR\Wow6432nodes\CLSID{MYCLSID}\InprocServer32 下注册的类的 CodeBase 之外,我看不到任何区别。我不明白的另一件事是在这两种情况下,在 HKCR\Wow6432nodes\CLSID{MYCLSID} 下都没有名为 TypeLib 的子键,
我不完全了解 COM 参考如何用于 Access 应用程序,所以如果我错了,请纠正我。谁能告诉我我做错了什么?注册共享 COM dll 的正确方法是什么(是否将 dll 和 tlb 都放入共享文件夹)?谢谢!
更新:
关于 COM 注册,我使用 WIX 创建 Windows 安装程序和 heat.exe 从 dll 和 tlb 文件中获取信息。生成的文件包括Class、ProgID、TypeLib 和Registry 标签的信息。正如我所提到的,从 WIX 配置的角度来看,我的两种情况之间的唯一区别是我放置 MyLib.dll 文件的位置(我假设将 MyLib.tlb 文件放在 MyApp 安装文件夹中是正确的方法,再次,请更正如果我错了),当我将 dll 和 tlb 文件都放入应用程序的安装文件夹时,它确实有效。这是注册后的一些注册表结构
首先我有 HKCR\CLSID\{MYCLSIDs},它们中的每一个都代表我的一个 COM 类。在名为“InprocServer32”的子项中,我有 Assembly、Class、CodeBase、RuntimeVersion、threadingModel。CodeBase要么是普通文件夹(不工作)要么是MyApp的安装文件夹(工作),这是我放置dll的不同位置。我认为 {MYCLSIDs} 下会有另一个子键 TypeLib,因为 Access 只看到 TypeLib,我认为应该有一些从 TypeLib 到实际 dll 的链接,但是,在这两种情况下,这个子键都丢失了,但在第二种情况它仍然有效。它有问题吗?
其次我有 HKLM\Software\Classes\CLSID\{MYCLSIDs},这个键的结构和上面描述的一样。
第三,HKCR\{MYPROGIDs},这些只是我班级的 ProgID
第四,HKCR\Typelib\{LibID},包含来自tlb文件的信息,这个ID来自COM组件项目的Assembly GUID。
最后是 HKEY_CLASSES_ROOT\Interface\{InterfaceID},有一个名为 ProxyStubClsid32 的子键,其值为 {00020424-0000-0000-C000-000000000046},一个名为 TypeLib 的子键,其值为我的 LibID。
似乎唯一的区别是第一项中的 CodeBase(我可能是错的,但这就是我所看到的)。如果您发现任何问题,请告诉我。谢谢!
第二次更新:
将 MyLib.dll 安装到共享文件夹后,COM 调用失败。但是,如果我将 SHARED_FOLDER\MyLib.dll 的所有 CodeBase 值替换为 INSTALLDIR\MyLib.dll,并将 MyLib.dll 复制到 INSTALLDIR,它实际上可以工作。反之亦然,在我将 MyLib.dll 安装到 INSTALLDIR 后(在这种情况下 COM 正在工作),我将 CodeBase 值从 INSTALLDIR\MyLib.dll 更改为 SHARED_FOLDER\MyLib.dll,并复制到 SHARED_FOLDER,这次它失败了。所以看来,正是安装位置的问题,和我对COM的理解相反。而且我认为 SHARED_FOLDER 没有权限问题(我可能是错的),因为它位于我的安装程序创建的文件夹中。