我正在使用开源库EasyHook。
我试图做的是,当VB6应用程序在特定的CLSID上从ole32.dll调用CoCreateInstance时,返回我自己的对象的C#实现,而不是真正的COM对象。我的C#实现派生自tlbimp.exe为我要替换的COM对象提供的同一接口。
我的钩子工作正常,我能够钩住调用,记录有关调用的数据,然后从C# p/invoke CoCreateInstance以允许VB6应用程序正常运行。
我注意到我要替换的COM对象并没有通过我的钩子传递。
有人知道VB6是如何在幕后加载ocx文件的吗?我是否连接到了正确的本机api调用?
或者,由于.Net的性质,我尝试做的事情是不可能的吗?
更新:另一种解决方案是编写一个COM对象来替换旧的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文件?
发布于 2009-10-23 03:06:31
几点意见:首先,VB6没有在“本地”类上使用CoCreateInstance,也就是来自同一项目的类--它直接调用“构造函数”。其次,您必须在每个可以共同创建CoCreateInstance的dll/ocx的导入部分挂接CLSID。
更好的方法是使用相同的coclass CLSID注册“升级”的COM组件。这样,客户端应用程序就会自动使用它。
编辑:或者看看CoTreatAsClass函数。
发布于 2009-10-23 04:57:06
如果您有原始组件的源代码,显然是VBMigration Partner can upgrade a VB6 COM component to a VB.Net component that has binary compatibility with the original VB6 component。我不知道它是否支持OCXs。
https://stackoverflow.com/questions/1608707
复制相似问题