tet*_*ete 3 com registry wix dllregistration heat
我们在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的子键,在我的理解中是将TypeLib链接到dll的方式(但为什么仍然有效)当我把tlb和dll放到同一个文件夹中?)因为在MyApp中它只知道我们通过引用MyLib.tlb添加了一个引用.
我不清楚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},这些只是我课程的ProgIDs
第四,HKCR\Typelib\{LibID},其中包含来自tlb文件的信息,此ID来自COM组件项目的程序集GUID.
最后,HKEY_CLASSES_ROOT\Interface\{InterfaceID},有名为ProxyStubClsid32的子键,值为{00020424-0000-0000-C000-000000000046},名为TypeLib的子键值为my 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存在权限问题(我可能错了),因为它位于我的安装程序创建的文件夹中.
我不清楚COM引用究竟是如何用于Access应用程序的,
因为这些东西出现在1990年,所以com对象如何适用于windows.所以我们谈论的是一个已经存在了22年的肉和土豆主流或技术(并且很久以前它就是如何在.net中创建对象的).
那么com的工作方式与Access,Delphi,FoxPro或VB6或任何能够使用com对象的系统相同.
接下来,重要的是要记住,对于这样的com对象,计算机上的这些对象的注册表本质上是GLOBAL.
没有接近放置在.net中的同一文件夹中的对象的动态链接的概念.
因此,way.net的工作方式不需要全局注册(实际上您不需要任何注册!).
但是在in.net中,如果愿意,可以在全局程序集中注册一个对象(GAC).所以这是你的选择,但这样的选择不是标准的windows com对象,而是.net对象的选择.所以那些对象与我们22年来的标准windows com对象有零和零.
因此.net中的大多数对象实际上是dir的本地对象,但这不是标准窗口com对象的选择.
因此,要正确地将.net对象或程序集转换为可用且正常工作的Windows com对象,则该对象必须将GLOBAL注册到计算机.这意味着你不使用regsvr32,但事实上它将使用名为regasm的.net注册工具(实际上,在为你构建com对象桥后,它最终会为你做一个regsvr32).另请注意,您需要在此处编译正确的位版本.
如果您部署到其他计算机,然后将项目设置为生成2.0对象,以便您很有可能在目标计算机上安装.net库.因此,在部署期间,您必须使用regasm:
这一个:C:\ Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe
最重要的是不要忘记将/ codebase添加到regasm.exe的命令行使用,因为您必须在GAC(全局程序集缓存)中注册.net对象.如果不这样做,那么支持windows com对象的非.net应用程序将不会看到noir能够将程序集用作标准的Windows com对象.
因此,当谈论非.net对象时,没有概念在文件夹基础上注册ActiveX或通常被称为windows com对象的文件夹 - 它本质上总是全局的.
因此,将.dll放入哪个目录或文件夹是没有意义的.一旦您正确注册.dll,它将可用于支持com对象的所有系统.
这也意味着在.net中的注册过程中,您必须使用全局程序集注册表选项(否则它将无法工作).