我正在使用开源库EasyHook。
我正在尝试做的是,当VB6应用程序从特定CLSID上的ole32.dll调用CoCreateInstance时返回,返回我自己的对象而不是真正的COM对象的C#实现。我的C#实现源自tlbimp.exe为我想要替换的COM对象吐出的相同接口。
我的钩子工作,我能够挂钩调用,记录有关调用的数据,然后从C#调用CoCreateInstance以允许VB6应用程序正常运行。
我注意到我要替换的COM对象没有通过我的钩子传递。
有谁知道VB6如何加载ocx文件?我是否正在接听适当的本地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文件?
答案 0 :(得分:3)
一些评论:首先,VB6不对“本地”类使用CoCreateInstance,即来自同一项目的类 - 它直接调用“构造函数”。其次,你必须在每个dll / ocx的导入部分挂钩CoCreateInstance,CLSID可以从中进行处理。
更好的方法是使用相同的coclass CLSID注册“已升级”的COM组件。这样,它将由客户端应用程序自动使用。
编辑:或者查看CoTreatAsClass功能。
答案 1 :(得分:1)
如果您拥有原始组件的源代码,显然是VBMigration Partner can upgrade a VB6 COM component to a VB.Net component that has binary compatibility with the original VB6 component。我不知道它是否支持OCX。