通过COM包装器从托管代码调用COM可见托管组件

sha*_*bee 16 c# com proxy interop marshalling

我有一个第三方组件,让我们说FIPreviewHandler来处理预览,它实现了IPreviewHandler.FIPreviewHandler实现为托管组件,并通过互操作使用IPreviewHandler接口和相关接口.FIPreviewHandler使用regasm.exe作为COM注册.

我有一个客户端应用程序也管理.我想在我的应用程序中创建一个FIPreviewHandler实例作为COM组件.

我有一个interop程序集,定义IPreviewHandler和相关的接口.

当我使用Activator.CreateInstance()创建一个FIPreviewHandler实例时,GetTypeByCLSID()返回的类型使用FIPreviewHandler的正确CLSID,它返回一个托管实例,因为它有实际的程序集可用,并跳过COM .当我尝试QI /将此实例转换为任何接口,例如IPreviewHandler时,它返回null,因为它作为托管对象加载,尽管FIPreviewHandler实现的IPreviewHandler接口与我在interop中的接口相同,但它在一个不同的命名空间/程序集中,因此为null.如果要返回一个COM实例/ RCW(System .__ ComObject),它将不会占用命名空间,并且可以正常转换,并返回一个有效的实例.

FIPreviewHandler是一个32位组件,在64位Win7机器上,如果我将我的客户端应用程序编译为"任何CPU",Activator.CreateInstance()将返回一个COM实例/ RCW(System .__ ComObject),因为它会查找64位实现FIPreviewHandler,因此返回一个代理.在这种情况下,我的应用程序工作正常.但是当我为x86编译它时,它获得32位实现,并返回实际托管类的托管实例,而不是COM实例,因此失败.

我不能使用FIPreviewHandler程序集中定义的接口,因为我必须为IPreviewHandler编写通用客户端,我的应用程序将与任何实现IPreviewHandler的组件一起使用,这对于基于C++的客户端访问FIPreviewHandler作为COM对象非常有用,但是失败了对于托管客户端.

我希望我有意义,我真的很感激任何帮助.

Lyn*_*ing 0

如果我没看错的话,您需要强制它使用 COM。两个想法:

  1. 如果您通过而不是Activator.CreateInstance()获取类型,行为会改变吗?GetTypeFromProgID()GetTypeByCLSID()

  2. 表现如何Microsoft.VisualBasic.Interaction.CreateObject()?是的,我讨厌将 VB 引入其中,但我很好奇它是否返回 COM 对象而不是 .NET 类。