【问题标题】:Replacing a C++ ActiveX component with a .NET implementation?用 .NET 实现替换 C++ ActiveX 组件?
【发布时间】:2011-03-03 21:33:17
【问题描述】:

我现有的托管和非托管软件使用第三方提供的 ActiveX 组件来执行某些通信,但现在需要通过我的应用程序路由此通信。

理想情况下,我应该能够安装一个 .NET 组件,该组件将公开完全相同的界面,并可用作替代品。

但是,我对 COM 的理解已经到了极限,诚然这是非常少的。

  • 如何最好地确保我的接口实现与现有对象 100% 二进制兼容?

  • 如何确保应用程序使用我的接口实现而不是旧实现?是否只是注册我的实现并取消注册旧版的问题?

  • 如何确保它是“直接”替换,并且不需要对现有软件进行任何更改?

  • 如何确保非托管代码可以毫无问题地使用它?

注意:我可以要求使用 .NET 4.0,如果这样会使事情变得更简单的话。

编辑:赏金将在 2 天后移至此处How to debug why a VB6 application using my .NET ActiveX control does not register for events?

【问题讨论】:

    标签: c# com interop


    【解决方案1】:
    1. 使用 ActiveX 组件的类型库。使用 Tlbimp.exe 导入它以获得互操作库,如果您自己使用此组件,您可能已经拥有它。通过继承该类型库中的接口来实现您自己的代码。

    2. 您的实现必须使用与 ActiveX 组件完全相同的 GUID 和 ProgID。使用 OleView.exe、File + View Typelib 并选择 ActiveX DLL 以查看 GUID。 ProgID 比较困难,最好的办法是在您使用 Regsvr32.exe 注册 ActiveX DLL 时,观察注册表是如何使用 SysInternals 的 ProcMon 实用程序修改的。最终,当您注册替代品时,Regasm.exe 需要进行完全相同的更改。

    3. 如第 2 点。

    4. 同样,注册会获得非托管代码来使用您的代码。

    要使这项工作顺利进行,您真的必须知道接口的作用。如果 ActiveX 组件实际上是进程外服务器(EXE),则无法进行此操作。

    【讨论】:

    • 谢谢,这正是我所希望的回应。碰巧,该组件以 .ocx 的形式提供。有趣的是,进程外服务器使使用 .NET 实施变得困难/不可能,这有什么不同?
    • 封送处理是个问题,您无法让 .NET 生成您需要的代理/存根。再说一次,如果你做得完全正确,那么你可以使用原始组件中的那些。 .ocx 不是问题
    【解决方案2】:

    嗯,我在这方面已经取得了很多进展,但我似乎遇到了一个棘手的问题。

    我要替换的对象使用 COM 事件。当其中一个客户端应用程序(我相信是 VB6,正如 depends.exe 告诉我它使用 msvbvm60.dll)实例化并使用我的替换时,它不会注册任何事件,不幸的是,它的工作方式是在特定方法调用已完成,客户端应用程序在事件触发之前什么都不做。

    注意:我的替换 ActiveX 控件继承自 System.Windows.Forms.Control,并按照 http://ondotnet.com/pub/a/dotnet/2003/01/20/winformshosting.html 的建议在 coclass 注册表项上设置了 131457 的 MiscOptions,原因是我要替换的东西是一个诚实的 ActiveX 控件,在我从 WinForms 控件继承之前,我无法让这些现有客户端成功实例化我的对象而无需任何代码更改。

    我已经尝试过我的 coclass 声明与ComSourceInterfaces 指定的接口同名的公共事件的方法,这在使用 AxHost 的 C# 应用程序中 100% 有效,事件被触发。

    我也尝试在我的替换控件上实现IConnectionPointContainer 和所有支持接口,这在 C# 应用程序中 100% 有效,但在 VB 应用程序中,它实际上从未尝试到 Advise() 的连接点要调用的客户端接收器接口,它只调用Unadvise(),cookie值为0。

    我注意到的 typelib 的一个问题是,我无法让 tlbexp.exe 将 coclass 接口上的属性之一导出为 OLE_HANDLE,它最终在从程序集生成的 TLB 中变成了一个 long (此 TLB 由注册表中的 TypeLib 条目引用)。这会导致事件发生问题吗?

    任何想法如何调试这个?

    【讨论】:

    • 您应该将此作为一个不同的问题提出,而不是作为一个答案。否则人们很难回答。
    猜你喜欢
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多