C# 用.NET实现替换C++ ActiveX组件?

C# 用.NET实现替换C++ ActiveX组件?,c#,com,interop,C#,Com,Interop,我现有的托管和非托管软件使用第三方提供的ActiveX组件来执行某些通信,但现在需要通过我的应用程序路由此通信 理想情况下,我能够安装一个.NET组件,该组件将公开完全相同的接口,并且可以作为替代品使用 然而,我对COM的理解已经到了极限,这是公认的最低限度 如何确保我的接口实现与现有对象100%二进制兼容 如何确保应用程序使用我的接口实现而不是遗留实现?这仅仅是注册我的实现和注销遗留实现的问题吗 我如何确保它是一个替代品,并且不需要更改现有软件 如何确保非托管代码可以毫无问题地使用它 注意:我

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

理想情况下,我能够安装一个.NET组件,该组件将公开完全相同的接口,并且可以作为替代品使用

然而,我对COM的理解已经到了极限,这是公认的最低限度

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

如何确保应用程序使用我的接口实现而不是遗留实现?这仅仅是注册我的实现和注销遗留实现的问题吗

我如何确保它是一个替代品,并且不需要更改现有软件

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

注意:我可以要求使用.NET4.0,如果这能使事情变得更简单的话

编辑:赏金将在2天后移到这里

使用ActiveX组件的类型库。使用Tlbimp.exe导入它以获取互操作库,如果您自己使用此组件,则可能已经拥有了互操作库。通过继承该类型库中的接口来实现您自己的代码

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

作为第2点

同样,注册将获得非托管代码以使用您的代码


要使这一切顺利进行,您必须真正了解接口的功能。如果ActiveX组件实际上是一个进程外服务器和一个EXE,则无法实现此功能。

好吧,我在这方面做了很多工作,但我似乎遇到了一个棘手的问题

我要替换的对象使用COM事件。当一个客户机应用程序VB6(我相信),如depends.exe告诉我的,它使用msvbvm60.dll实例化并使用我的替换,它不会为任何事件注册,不幸的是,它的工作方式是,在特定方法调用完成后,客户机应用程序在触发事件之前不会执行任何操作

注意:我的替换ActiveX控件继承自System.Windows.Forms.control,并根据建议在coclass注册表项上设置MiscOptions 131457,原因是我要替换的是一个诚实的ActiveX控件,在从WinForms控件继承之前,我无法让这些现有客户机在没有任何代码更改的情况下成功实例化我的对象

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

我还尝试在我的替换控件上实现IConnectionPointContainer和所有支持接口,这在C应用程序中100%有效,但在VB应用程序中,它实际上从未尝试建议客户端接收器接口的连接点调用,它只调用带有无效cookie值0的Unadvise

我注意到的typelib的一个问题是,我无法让tlbexp.exe将coclass接口上的一个属性导出为OLE_句柄,它只是从程序集中生成的TLB中的一个long,该TLB被注册表中的typelib项引用。这会导致事件发生问题吗


你知道如何调试吗?

谢谢,这正是我希望得到的回应。碰巧,组件以.ocx的形式发布。有趣的是,进程外服务器与使用.NET实现有什么不同?封送是一个问题,您无法让.NET生成所需的代理/存根。再说一次,如果你做得完全正确,那么你可以使用原始组件中的那些。这不是一个问题。有时你应该把这当作一个不同的问题来问,而不是作为一个答案。否则人们很难回答。