2010-06-15 82 views
4

我有现成的托管和非托管软件使用由第三方提供的ActiveX组件来执行一些通信,但现在需要通过我的应用程序路由此通信。用.NET实现替换C++ ActiveX组件?

理想情况下,我可以安装一个.NET组件,它将公开完全相同的接口,并且可以用作插入式替换件。

但是,我遇到了我对COM的理解的限制,这种理解确实很少。

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

  • 如何确保应用程序使用我的接口实现而不是传统的实现?这仅仅是注册我的实现,并注销旧版本的问题吗?

  • 我该如何确保它是“插入式”的替代品,并且不需要更改现有软件?

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

注:我能够要求.NET 4.0中使用,如果这会让事情变得更简单。

编辑:赏金将在两天后移到这里How to debug why a VB6 application using my .NET ActiveX control does not register for events?

回答

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

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

  3. As点2.

  4. 相同,登记得到非托管代码使用你的代替。

为了使这项工作顺利,你真的知道什么接口做。如果ActiveX组件实际上是一个进程外服务器(EXE),则无法进行此项工作。

+0

谢谢,这正是我期待的回应。碰巧,组件以.ocx的形式出货。 作为一个感兴趣的问题,使得使用.NET实现难以/不可能实现的进程外服务器有什么不同? – 2010-06-15 10:45:00

+0

编组是一个问题,你不能让.NET生成你需要的代理/存根。再次,如果你完全正确地做,那么你可以使用原始组件中的那些。不是.ocx – 2010-06-15 10:47:02

1

那么,我已经得到了很多进一步的,但我似乎遇到了棘手的问题。

我正在更换的对象使用COM事件。当其中一个客户端应用程序(VB6我相信,因为depends.exe告诉我它使用msvbvm60.dll)实例化并使用我的替代品,它不会注册任何事件,不幸的是,它的工作方式是在特定方法调用后完成后,客户端应用程序不会做任何事情,直到事件触发。

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

我已经尝试过我的coclass声明公共事件的方法,其名称与ComSourceInterfaces指定的接口名称相同,这可以在使用AxHost的C#应用​​程序中100%工作,触发事件。

我也试图代替实施IConnectionPointContainer和我改写控制所有支持接口,而这个工程100%,从C#应用程序,但在VB应用程序,它从来没有真正试图Advise()的客户端接收器的连接点接口调用,它仅适用于带我注意到类型库0

一个问题的一个无效的cookie值调用Unadvise()的是,我不能让tlbexp.exe至共类接口的输出特性之一,因为OLE_HANDLE,它只是最终在程序集生成的TLB中很长(该TLB由注册表中的TypeLib条目引用)。这是否会导致事件发生问题?

任何想法如何调试?

+1

问题你应该问这是一个不同的问题,而不是一个答案。否则,人们很难回答。 – Amnon 2010-07-18 10:24:14

+0

好主意,会做。 – 2010-07-19 10:28:56