COM dll注销问题
COM dll unregister issue
我有一个有许多COM Dll的项目,对于一个要求,我必须取消注册一个COM Dll,我通过调用Regsvr32 -u
选项和Dll是未注册的。
这个注销操作似乎删除了一个接口,比如ICommon
接口,它使其他COM对象无法使用。
这个ICommon
接口是由所有其他COM组件实现的,在未注册的COM Dll的注册表脚本中,我没有看到任何从注册表中删除这个ICommon
接口的代码,这是如何被删除的。
如何为给定的CoClass
删除接口信息,是否BEGIN_COM_MAP和COM_INTERFACE_ENTRY
发挥任何作用?
COM充斥着DLL Hell问题。这里的失败模式是卸载服务器也会从HKLMSoftwareClassesInterface中删除密钥。它告诉COM应该使用哪个代理/存根实现来跨单元边界封送接口。接口的ProxyStubClsId32键标识代理。
所以这会破坏任何使用其他COM服务器实现接口的客户端程序,它们不能再封送接口,并且它们将在运行时死于E_NOINTERFACE。它本身就是一个令人困惑的错误代码,你会认为接口不知怎么消失了,但它实际上是在抱怨COM对象没有实现immarshal。COM在注册表中找不到键时的最后喘息。
这通常不是很难修复,你只需要重新注册失败的COM服务器,它会把密钥放回去。
没有真正的防御这种损失,你必须实现一个详细的引用计数方案,记录有多少COM服务器依赖于代理,只有当它计数到零时才删除键(和DLL,如果它是一个自定义代理)。这已经完成了,但是只需要一个不购买方案的单个安装程序,或者像您一样从命令行执行不明智的Regsvr32.exe/u,就可以使其失败。是的,这些元素确实发挥了作用,regsvr32
使用的typelib也是如此。
如果ICommon
接口是可见的,通过查看COM组件的typelib可以看到,该类型被视为由组件"拥有",并且regsvr32
进程将该组件添加为该接口的位置。在移除时,情况正好相反。因此,虽然仍然使用ICommon
接口,但由于被视为接口的"所有者"的组件被删除,接口的注册也被删除。新的"所有者"不会自动安装(或注册),这必须通过再次注册合适的组件来完成。
我建议将ICommon
接口隔离为单个typelib (COM组件),并在需要接口的任何地方导入该typelib,从而确保接口的单个"所有者"。
注意:基于一些继承代码的经验(有这个问题)我不得不修复,导入或试图重新声明系统接口(例如ISerializable
等)时要非常小心,因为regsvr32
也可以从注册表中删除这些;造成了世界的痛苦。在这种情况下,卸载几乎破坏了整个系统。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- C++格式化输出问题
- COM dll注销问题