Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ COM dll注销问题_C++_Windows_Com_Atl_Dcom - Fatal编程技术网

C++ COM dll注销问题

C++ COM dll注销问题,c++,windows,com,atl,dcom,C++,Windows,Com,Atl,Dcom,我有一个有很多COM Dll的项目,为了满足要求,我必须注销COM Dll,我通过调用Regsvr32-u选项来注销Dll 此取消注册操作似乎删除了一个接口,例如ICommon接口,这使得其他COM对象不可用 这个ICommon接口是由所有其他COM组件实现的,在未注册COM Dll的注册表脚本中,我没有看到任何代码从注册表中删除这个ICommon接口,这是如何删除的 给定的CoClass的接口信息是如何删除的,BEGIN\u COM\u映射和COM\u interface\u条目是否起作用?是

我有一个有很多COM Dll的项目,为了满足要求,我必须注销COM Dll,我通过调用
Regsvr32-u
选项来注销Dll

此取消注册操作似乎删除了一个接口,例如
ICommon
接口,这使得其他COM对象不可用

这个
ICommon
接口是由所有其他COM组件实现的,在未注册COM Dll的注册表脚本中,我没有看到任何代码从注册表中删除这个
ICommon
接口,这是如何删除的


给定的
CoClass
的接口信息是如何删除的,BEGIN\u COM\u映射和
COM\u interface\u条目
是否起作用?

是的,这些元素确实起作用,由
regsvr32
使用的类型库也起作用

如果通过查看COM组件的typelib可以看到
ICommon
接口,则该类型被视为该组件“拥有”,并且
regsvr32
进程将该组件添加为该接口的位置。移除时,应用相反的方法。因此,尽管仍然使用
ICommon
接口,但由于被视为接口“所有者”的组件被删除,因此接口的注册也被删除。新的“所有者”不会自动安装(或注册),这必须通过再次注册合适的组件来完成

我建议将
ICommon
接口与单个typelib(COM组件)隔离,并在需要接口的地方导入该typelib,从而确保接口的单个“所有者”


注意:根据一些继承代码的经验(关于这个问题),我必须修复,在导入或尝试重新声明系统接口(例如,
ISerializable
等)时要非常小心,因为
regsvr32
也可以从注册表中删除这些接口;造成痛苦的世界。在这种情况下,卸载几乎破坏了整个系统。

COM充斥着DLL地狱问题。此处的故障模式是,卸载服务器也会从HKLM\Software\Classes\Interface中删除密钥。它告诉COM应该使用哪个代理/存根实现跨单元边界封送接口。接口的ProxyStubClsId32键标识代理

因此,如果任何客户端程序使用实现该接口的其他COM服务器,它们将无法再封送该接口,并且它们将在运行时与E_NOINTERFACE一起消亡。这本身就是一个令人困惑的错误代码,您可以假设接口不知何故消失了,但它实际上抱怨COM对象没有实现IMarshal。COM在注册表中找不到注册表项时的最后关头

这并不是说通常很难修复,您只需重新注册发生故障的COM服务器,它就会将密钥放回


对于这种丢失没有真正的防御措施,您必须实现一个复杂的引用计数方案,该方案记录有多少COM服务器依赖于代理,并且只有在其计数为零时才删除密钥(以及DLL,如果它是自定义代理)。这项工作已经完成,但是只需要一个不接受该方案的安装程序,或者像您那样从命令行执行一个不明智的Regsvr32.exe/u,就可以使其失败。

当您查看类型库时,
ICommon
接口是否在所有使用
ICommon
的COM组件DLL中可见?您可能在2+类型库(典型问题)上有此接口,然后注销任何删除的接口注册。如果是此问题,快速修复方法可能是使用此接口重新注册任何剩余的库。一个合适的修复方法是消除类型库上的重复。谢谢Roman…如果这是可行的,我会的。当然,这都是真的,但是防御非常简单-在2+类型库上永远没有接口。那么就不存在这样的情况:一件东西已经消失,而另一件东西仍在使用消失的东西。IDL
importlib
是相互引用类型库的工具。+1我正要逐字逐句地写下这篇文章。出于这个原因,我从不为多个PE之间共享的接口合并代理存根信息,选择一个单独的类型库,如果需要,选择一个独立的封送器(我也尽量避免)。这正是我看到的错误…感谢您抽出时间回答这个问题