Windows客户端开发

【Windows】同时支持32位和64位的插件开发注意事项

2016-12-17  本文已影响384人  mercurygear

首先说下为什么会有这种需求,这是因为64位windows下可以运行32位和64位的程序,所以我们为一些系统程序做插件或扩展时,就需要同时支持32位版本和64位版本,比如说给IE做ActiveX插件,因为64位windows下同时存在32位和64位版本的IE。

一般情况下,32位版本和64位版本的插件,我们的COM组件都会使用相同的CLSID、APPID、LIBID等等,那么这里就有几个地方需要我们注意了。因为虽然32位和64位代码会有各自的注册表视图,以保证隔离开而不发生冲突;但是有部分注册表项并没有做这种分隔的,这里列举下COM相关的注册表项如果32位和64位同时注册之后,会存在的一些情况,以供参考。

HKCR其实是由HKLM\Software\Classes映射过去的,其中64位注册表视图和HKLM\Software\Classes一样,32位注册表视图是由HKLM\Software\Wow6432Node\Classes叠加在HKLM\Software\Classes上形成的,所以32位注册表视图其实是一个混合视图,它覆盖下图中显示这些部分:


注册表的32位隔离部分

所以像CLSID这样的,32和64注册表各有一份,互不影响;但是ProgID和VersionIndependentProgID这种因为是直接在HKCR下的项,所以只在HKLM\Software\Classes存在一份,这就会出现这么个问题:
假如我们为32和64位的IE都做了个插件,并且在机器针对32位和64位版本都进行了一次注册,那么我们的页面这么来创建一个ActiceX对象 new ActiveXObject("MyIEPlugin"),无论在32位还是64位版本的IE下都是正常工作的。
但是一旦我们对其中一个插件进行了反注册,由于ProgID只有一份,一旦反注册,就会被移除,所以此时虽然机器上还有另外一个版本的插件,不论是在哪个版本的IE下,上述代码都无法创建出我们的ActiveX对象了。(直接使用C++代码通过CLSID还是能创建出来剩下的那个对象)

这种特性看似有点和直觉违背,毕竟我们所理解的32位和64位的隔离会是彻底的隔离,单独反注册掉一个应该不会影响另外一个。所以如果真的要解决上上面描述的问题,或许我们在使用的时候,尽量避免使用ProgID,而是使用CLSID来代替。

补充:虽然TypeLib是32位和64位的注册表视图都有,但是有点不一样的地方就是,无论哪个视图下,COM组件的TypeLib都是一样的,会同时存在32位组件和64位组件的信息,如下图所示:

COM组件的TypeLib
上一篇下一篇

猜你喜欢

热点阅读