我正在使用开源库 EasyHook .
我想做的是,当 VB6 应用程序从特定 CLSID 上的 ole32.dll 调用 CoCreateInstance 时,返回我自己的对象 C# 实现,而不是真正的 COM 对象。我的 C# 实现源自 tlbimp.exe 为我想要替换的 COM 对象吐出的同一接口(interface)。
我的钩子(Hook)有效,我能够钩入调用,记录有关调用的数据,然后从 C# p/invoke CoCreateInstance 以允许 VB6 应用程序正常运行。
我注意到我想要替换的 COM 对象没有通过我的钩子(Hook)传递。
有谁知道 VB6 是如何在后台加载 ocx 文件的?我是否连接到了正确的 native api 调用?
或者由于 .Net 的性质,我想要做的事情是不可能的?
更新:另一种解决方案是编写一个 COM 对象来替换旧的对象,但我们无法让它发挥作用。这是我关闭的关于该主题的旧帖子:Replace COM object
更新:经过进一步检查,我们能够 regsvr32/u 旧的 ocx 文件并使用 regasm 来注册我们的 .Net dll。我们在 COM 对象的构造函数中放置了一个 MessageBox,VB6 应用程序加载并弹出该框,但一旦对该对象进行第一个方法调用,它就会崩溃。
我怀疑我们有一些方法签名错误,而且我们正在使用 tlbimp.exe 在我们想要替换的目标 ocx 上运行时提供的内容。 tlbimp 是否可能对签名进行更改,从而阻止 VB6 应用程序加载我们的程序集?
例如,有时 COM 签名看起来像:
HRESULT MyMethod(IUnknown* ppv);
tlbimp.exe 会给 C# 一些类似的东西:
IUnknown MyMethod();
对于 C# 开发人员来说,这看起来更简洁。有谁知道这一点,或者有一篇好文章可以解释如何从 C# 编写“二进制兼容”COM 程序集来替换 ocx 文件?
最佳答案
几点注释:首先,VB6 不在“本地”类(即来自同一项目的类)上使用 CoCreateInstance,它直接调用“构造函数”。其次,您必须将 CoCreateInstance 挂接到可以共同创建 CLSID 的每个 dll/ocx 的导入部分。
更好的方法是使用相同的组件类 CLSID 注册“升级的”COM 组件。这样客户端应用程序就会自动使用它。
编辑:或者看看CoTreatAsClass功能。
关于C# - EasyHook CoCreateInstance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1608707/