第三方组件的 COM 代理 [英] COM surrogate for third party component

查看:36
本文介绍了第三方组件的 COM 代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小的 DLL 组件,它需要访问两个第三方组件来合并数据,其中一个只有 32 位,另一个只有 64 位.两者都注册到 TypeLib 并且与自动化兼容,因此编组应该不是问题.

I'm writing a small DLL component that needs to access two third party components to combine data, one of which is 32 bit only and the other is 64 bit only. Both are registered with a TypeLib and are Automation compatible, so marshalling should not be an issue.

如果我正确理解了文档,那么除非组件也有 AppID 和 DllSurrogate 键,否则无法强制加载代理;由于两者都是第三方组件,我有点不愿意修改它们的注册.

If I understood the documentation correctly, then there is no way to force loading in a surrogate unless the component also has an AppID and the DllSurrogate key; since both are third party components, I'm somewhat reluctant to modify their registration.

有没有办法在代理进程中从一个理想情况下没有任何额外依赖项的 DLL 组件中激活没有 AppID 的组件中的对象,或者任何人都可以向我解释为什么这会是个坏主意?

Is there a way to activate an object in a component without an AppID in a surrogate process from a DLL component that ideally does not have any extra dependencies, or can anyone explain to me why this would be a bad idea?

推荐答案

是的,您可以通过以下方式在代理中加载(例如)仅 32 位的 DLL,并从 64 位进程访问它.如果有可用的编组器,这将起作用,通常对于具有 typelib 的组件会有此功能,因为它们通常使用标准编组器.如果对象需要自定义代理/存根,它将无法工作,因为 64 位版本不存在,否则您首先不会遇到此问题.

Yes, you can load a (for example) 32-bit only DLL in a surrogate, and access it from a 64-bit process, in the following manner. This will work provided there is a marshaller available, which there generally will be for a component with a typelib because they usually use the standard marshaller. It will not work if the object requries a custom prox/stub because 64 bit versions won't exist, or you wouldn't have this problem in the first place.

首先你需要一个 AppID.如果 DLL 已经有一个 AppID,你应该使用它.您可以通过检查您感兴趣的 CoClass 的 CLSID 键来找到.

First you need an AppID. If the DLL already has an AppID, you should use that. You can find out by checking under the CLSID key for the CoClass you are interested in.

此处使用的示例是 Capicom.HashedDataCapicom.EncryptedData 类.Capicom 仅支持 32 位.

The example used here is the Capicom.HashedData and Capicom.EncryptedData classes. Capicom is 32-bit only.

您应该使用 32 位版本的 Regedit 来执行此操作,因为它是一个 32 位组件.如果您想从 32 位访问 64 位组件,请使用另一个.(这是因为 32 位兼容层的注册表虚拟化 - 使用匹配的 regedit 位版本可以为您解决这个问题,确保您编辑正确的注册表虚拟化版本).

You should use the 32-bit version of Regedit to do this, as it is a 32-bit component. If you have a 64-bit component you want to access from 32-bits, use the other one. (This is because of the registry virtualisation for the 32-bit compatibility layer- using the the matching bitness version of regedit takes care of this issue for you, by making sure you edit the correct virtualised version of the registry).

Windows Registry Editor Version 5.00


;;; Capicom AppID - just using the Capicom.EncryptedData CLSID
;;; Use default surrogate = empty string
[HKEY_CLASSES_ROOTAppID{A440BD76-CFE1-4D46-AB1F-15F238437A3D}]
"DllSurrogate"=""

;;; Capicom.EncryptedData
[HKEY_CLASSES_ROOTCLSID{A440BD76-CFE1-4D46-AB1F-15F238437A3D}]
AppID="{A440BD76-CFE1-4D46-AB1F-15F238437A3D}"

;;; Capicom.HashedData - use same AppID for all!!!!!
[HKEY_CLASSES_ROOTCLSID{CE32ABF6-475D-41F6-BF82-D27F03E3D38B}]
AppID="{A440BD76-CFE1-4D46-AB1F-15F238437A3D}"

保存到 myComponent-dllhost.reg 文件,然后就可以了.

Save to a myComponent-dllhost.reg file, and away you go.

c:windowssysWow64
egedit.exe "myComponent-dllhost.reg"

您现在应该可以从 64 位脚本/COM 主机访问 Capicom.HashedData 和 Capicom.EncryptedData.

You should now be able to access Capicom.HashedData and Capicom.EncryptedData from 64-bit script/COM hosts.

注意事项:

  • 这仅适用于基本的 OLE 自动化类型.任何与 VBScript 或 JavaScript 中的 Windows Scripting Host 脚本兼容的对象都应该没问题.
  • 您只需将 AppID 添加到可直接创建的对象中.这基本上是那些具有 InprocServer32 条目的内容.从工厂生成的对象或仅作为子对象可用的对象不必添加 AppID.
  • 如果已经有 AppID,您只需添加空字符串DllSurrogate"条目.就是这样!
  • 这将不会影响 DLL 的正常客户端.只要位匹配,它们就会像以前一样继续在进程中加载​​.它带来的唯一区别是,可以从不同位数的客户端在进程外实例化它.
  • This only works for basic OLE Automation types. Any object compatible with Windows Scripting Host scripts in VBScript or JavaScript should be OK.
  • You only have to add the AppID to directly creatable objects. That's basically those with an InprocServer32 entry. Objects which are generated from factories or which are only available as child objects do not have to have an AppID added.
  • If there is already an AppID all you need to do is add the empty-string "DllSurrogate" entry. That's it!
  • this will NOT affect normal clients of the DLL. As long as the bit-ness matches, they will continue to be loaded in-process as before. The only difference it will make is that it will become possible to instantiate it out-of-process from a client of a different bitness.

这篇关于第三方组件的 COM 代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆