我使用由第三方提供的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?。
答案 0 :(得分:4)
使用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),则无法使其工作。
答案 1 :(得分:1)
嗯,我已经得到了更多,但我似乎遇到了一个棘手的问题。
我要替换的对象使用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
指定的接口同名的公共事件,这100%来自使用AxHost的C#应用程序,事件被触发。
我还尝试在我的替换控件上实现IConnectionPointContainer
和所有支持接口,这100%来自C#应用程序,但在VB应用程序中,它实际上从未尝试Advise()
客户端接收器接口与呼叫的连接点,它仅使用无效的cookie值0调用Unadvise()
。
我注意到的typelib的一个问题是我无法让tlbexp.exe
将coclass接口上的一个属性导出为OLE_HANDLE
,它最终只是在生成的TLB中长了一个来自程序集(此TLB由注册表中的TypeLib条目引用)。这会导致事件发生问题吗?
任何想法如何调试?