C# – 挂钩到现有的COM对象

假设我们有一个现有的进程(或应用程序)从ocx文件调用COM对象,例如“MyCOMLibrary.ocx”。

有没有办法编写一个C#库来完全复制ocx文件? 这样原始应用程序可以调用您的C#代码而不是原始COM对象?

当然,您必须使用相同的CLSID和ProgID作为原始ocx。 假设没有涉及签名,例如.Net世界中的SNK。

此外,是否有任何工具可以实现自动化? 接受ocx的东西并使用要实现的方法吐出C#文件。

编辑:我想补充说原始应用程序是VB6,并且根本不使用.Net。 他们最有可能将ocx加载为VB6 app(ProgId或Guid)。 这会导致任何问题吗?

完全重写ocx我们也没有问题 – 我们很可能只返回所有方法的成功错误代码,并且只使用我们的情况所需的方法/事件。

编辑:你会认为这不会太难实现。 我们可以创建一个可以替换旧ocx的VB6 ocx文件,并将所有调用传递给.Net程序集吗?

编辑:我尝试使用以下开源库: EasyHook

但似乎这个问题应该仍然可行。 VB6似乎以防止挂钩的方式加载COM对象。 我没有看到使用EasyHook在类/接口或类的构造函数上挂钩实例方法的方法。

您可以使用ActiveX Import AxImp导入OCX,创建一个包装类然后调用它。 该程序在此处描述: http : //msdn.microsoft.com/en-us/library/8ccdh774( VS.80) .aspx基本上,您需要做的是在命令提示符上执行以下命令:

c:/>AxImp MyControl.ocx 

结果是MyControl.dll和AxMyControl.dll。 第一个可以用作项目中的普通.NET DLL(即,没有图形用户界面),第二个可以用于在表单上绘制,就像通常使用任何其他控件(如TextBoxLabel

要使用它,请转到Visual Studio,右键单击您的项目并选择Add Reference。 浏览到新创建的DLL并添加它。 就这样。

我们的Deviare Hook库可用于挂钩COM对象。 您可以在我们的博客中看到与此主题相关的文章: 使用Deviare挂钩Outlook COM对象

显然VBMigration Partner 可以自动将VB6 COM组件升级到与原始VB6组件具有二进制兼容性的VB.Net组件 。 我不知道它是否支持OCX。 如果确实如此,我建议先使用它,然后再尝试转到C#(如有必要)。

对这个问题不是一个完整的答案,但我认为可能有用。 如果在要替换的对象的CLSID下添加名为“TreatAs”的键,并将默认值设置为要创建的对象的CLSID,则会指示COM运行时创建对象而不是原始对象。 然后无需强制您的新替换对象具有与旧对象相同的CLSID和ProgID。

例如,如果您的原始对象具有ProgID“MyComLibrary.Object”和CLSID“{ABC}”,并且您的新对象具有ProgID“MyDotNet.Object”和CLSID“{123}”,则在HKLM / CLSID / {ABC}下添加名为TreatAs的密钥,默认值为{123}。 然后,对“MyComLibrary.Object”或“MyDotNet.Object”的任何请求都将获得新对象的副本(假设它们实现相同的接口)。