使用ExeCOMServer时,无法将类型为"..."的COM对象转换为接口类型"..."

mas*_*_99 3 c# com casting interface

我正在使用这个exe com服务器:

https://cfx.svn.codeplex.com/svn/Visual%20Studio%202008/CSExeCOMServer/ExeCOMServer.cs

  • 我的编程是一个com应用程序
  • 我的com方法采用另一个com对象是 void Init(AppsScriptRunningContext rc);
  • 在这个方法中,我尝试读出一个属性并得到此错误

无法将"AppsScriptLib.AppsScriptRunningContextClass"类型的COM对象强制转换为接口类型"AppsScriptLib.IAppsScriptRunningContext".此操作失败,因为对IID为"{4D2E5723-87C2-49C1-AA28-ED2D88275100}"的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULT异常:0x80004002(E_NOINTERFACE))

如果我的应用程序不是com服务器而是普通的com应用程序,则没有错误.这就是为什么我认为错误是由exe com服务器产生的.

https://cfx.svn.codeplex.com/svn/Visual%20Studio%202008/CSExeCOMServer/ExeCOMServer.cs

问候,克里斯

Han*_*ant 7

这是一个非常令人遗憾的代码示例,成功的可能性非常接近于零.它是MSDN论坛支持小组的产品,他们的工作未在Microsoft进行同行评审.一位团队成员后来承认这不是正确的方法.

该代码的一个问题是它完全忽略了注册服务.RegisterTypeForComClients()方法的MSDN文档中的备注:

请注意,不支持使用平台调用来调用非托管CoRegisterClassObject和CoDisconnectObject方法来注册和取消注册COM对象.

不幸的是,没有解释为什么它不受支持.关键问题是COM接口总是需要在进程外激活情况下进行封送.这是通过在客户端创建代理来完成的,该代理是一个接口实例,它具有与原始接口完全相同的方法,但其实现的方法通过RPC将方法的参数发送给另一个进程.在服务器端,存根执行相同但相反的角色,使用方法参数构建堆栈帧并进行实际的方法调用.

在.NET中创建代理和存根很容易,反射使它变得简单.由构建在框架中的Remoting管道完成.然而,它在COM中并不容易,它没有任何类似于反射的东西.它有两种基本的完成方式,首先是用IDL语言编写COM接口定义并用midl.exe编译它.这可以自动生成执行编组的C源代码,您可以从中构建DLL.然后需要在HKCR\Interface注册表项中正确注册该DLL,以便COM可以在需要封送接口时查找并加载DLL.如果您的接口派生自IDispatch并将其自身限制为OLE自动化兼容的参数类型,则可以使用第二种方法.然后,您可以生成类型库并使用标准编组器.这需要注册类型库,以及HKCR\Interface中的相应键,以便COM知道它.

这是.NET进程外服务器中不会​​发生的部分.您没有midl.exe来帮助您生成代理/存根DLL,并且您没有获得使用标准编组器的注册帮助.这是错误消息的真正含义,E_NOINTERFACE在这里真的意味着它找不到任何方法来编组接口.是的,糟糕的错误消息.

.NET中正式支持的创建进程外COM服务器的方法是将其注册到COM +.使用System.EnterpriseServices.ServicedComponent类作为基类.MSDN库文章在这里.