C# - EasyHook CoCreateInstance

标签 c# .net com vb6 interop

我正在使用开源库 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/

相关文章:

c - 如何通过CreateInstanceLic获得许可的COM对象?

c# - 解析 HTML/CSS/PHP 文件

c# - 如何找到在多边形内放置标签的最佳位置

c# - EF Core Linq 使用方法语法加入 OR 条件

.net - .NET 中具有超过 2^31 个键的大数组的选项

c++ - 我如何知道一个 COM 对象与不同的 COM UUIDS 兼容?

c# - where 子句的正则表达式?

c# - UNC 路径不适用于 .NET?

c# - 如何列出在 Windows 中运行的所有进程?

c# - 使用 C# 中的动态 com 互操作处理来自 Word 的事件