简体   繁体   English

64 位 C# 与 32 位 VB6 COM ZA8CFDE6331BD59EB2AC96F8911C4B6

[英]64 bit C# with a 32 bit VB6 COM object

I have a 32 bit in-proc STA VB6 dll.我有一个 32 位进程内 STA VB6 dll。 I sadly cannot do anything about this.很遗憾,我对此无能为力。 My C# component greatly benefits from being 64 bit.我的 C# 组件极大地受益于 64 位。 Is there anyway to call/interface with this 32-bit dll from my 64 bit process?无论如何从我的 64 位进程调用/接口这个 32 位 dll 吗? Any sort of wrapper or anything?任何形式的包装或任何东西?

There's no direct way you can do this.没有直接的方法可以做到这一点。

Since you can't port the VB6 inproc dll I'd suggest you write a 32bit out of process server that implements the same interfaces and have it delegate down to the VB6 code.由于您无法移植 VB6 inproc dll,我建议您编写一个 32 位进程外服务器来实现相同的接口,并将其委托给 Z84F2272A2A8E44C41B1D0ED9A3E0FEC 代码。 Then, your 64bit app can call the out of process server as COM will take care of marshaling the types between the processes.然后,您的 64 位应用程序可以调用进程外服务器,因为 COM 将负责在进程之间编组类型。

It ain't pretty, bit it will work!它不漂亮,它会工作!

This article Dealing with Legacy 32-bit Components in 64-bit Windows help you:本文在 64 位 Windows 中处理旧版 32 位组件可帮助您:

I have found this solution, see in article :我找到了这个解决方案,请参阅文章
• Converting a project type from in-process to out-of-process • 将项目类型从进程内转换为进程外
• Using COM+ as a host (this work for me) • 使用 COM+ 作为主机(这对我有用)
• Using dllhost as a surrogate host • 使用 dllhost 作为代理主机

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.您可以在代理中加载(例如)仅 32 位 DLL,并通过以下方式从 64 位进程访问它。

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.如果 object 因为不存在 64 位版本而需要自定义代理/存根,它将无法工作,或者您一开始就不会遇到这个问题。

How to register a third-party 32-bit component for use from a 64-bit client如何注册第三方 32 位组件以供 64 位客户端使用

First you need an AppID.首先你需要一个 AppID。 If the DLL already has an AppID, you should use that.如果 DLL 已经有一个 AppID,你应该使用它。 You can find out by checking under the CLSID key for the CoClass you are interested in.您可以通过检查您感兴趣的 CoClass 的 CLSID 键来查找。

The example used here is the Capicom.HashedData and Capicom.EncryptedData classes.这里使用的示例是Capicom.HashedDataCapicom.EncryptedData类。 Capicom is 32-bit only. Capicom 只有 32 位。

  • AppID: CAPICOM does not have an AppID, so for the AppID I have just used the CLSID of the EncryptedData class. AppID: CAPICOM 没有 AppID,所以对于 AppID,我刚刚使用了 EncryptedData class 的 CLSID。

  • CLSID: You need a list of the CLSID of each class you want to be able to create from 64-bit clients. CLSID:您需要一个您希望能够从 64 位客户端创建的每个 class 的 CLSID 列表。 In this example, it is just EncryptedData and HashedData.在这个例子中,它只是 EncryptedData 和 HashedData。

  • Registration: Create a registry file containing the details, as per the example, and load it into the registry.注册:根据示例创建一个包含详细信息的注册表文件,并将其加载到注册表中。

You should use the 32-bit version of Regedit to do this, as it is a 32-bit component.您应该使用 32 位版本的 Regedit 来执行此操作,因为它是一个 32 位组件。 If you have a 64-bit component you want to access from 32-bits, use the other one.如果您想要从 32 位访问 64 位组件,请使用另一个。 (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). (这是因为 32 位兼容层的注册表虚拟化 - 使用匹配的 regedit 位数版本可以为您解决这个问题,确保您编辑正确的注册表虚拟化版本)。

Windows Registry Editor Version 5.00


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

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

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

Save to a myComponent-dllhost.reg file, and away you go.保存到myComponent-dllhost.reg文件,然后将 go 移走。

c:\windows\sysWow64\regedit.exe "myComponent-dllhost.reg"

You should now be able to access Capicom.HashedData and Capicom.EncryptedData from 64-bit script/COM hosts.您现在应该能够从 64 位脚本/COM 主机访问 Capicom.HashedData 和 Capicom.EncryptedData。

Notes:笔记:

  • This only works for basic OLE Automation types.这仅适用于基本的 OLE 自动化类型。 Any object compatible with Windows Scripting Host scripts in VBScript or JavaScript should be OK. VBScript 或 Z686155AF75A60A0F36E9D80C1F7 中与 Windows 脚本主机脚本兼容的任何 object 都应该是 OKEZD。
  • You only have to add the AppID to directly creatable objects.您只需将 AppID 添加到可直接创建的对象。 That's basically those with an InprocServer32 entry.那基本上是那些有 InprocServer32 条目的。 Objects which are generated from factories or which are only available as child objects do not have to have an AppID added.从工厂生成的对象或仅作为子对象可用的对象不必添加 AppID。
  • If there is already an AppID all you need to do is add the empty-string "DllSurrogate" entry.如果已经有 AppID,您只需添加空字符串"DllSurrogate"条目。 That's it!而已!
  • this will NOT affect normal clients of the DLL.不会影响 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.唯一不同的是,它可以从不同位数的客户端在进程外实例化它。

The 32bit COM component will have to run out of process. 32 位 COM 组件将不得不耗尽进程。

Before embarking on creating a wrapper, check out whether COM+ (Object Services) will host it.在着手创建包装器之前,请检查 COM+(对象服务)是否会承载它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM