无法转换类型'...'的接口类型的COM对象'...',而使用ExeCOMServer [英] Unable to cast COM object of type '...' to interface type '...' while using an ExeCOMServer

查看:279
本文介绍了无法转换类型'...'的接口类型的COM对象'...',而使用ExeCOMServer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用这个EXE COM服务器:

I'm using this exe com server:

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


  • 我PROG是一个COM应用程序

  • 内搭另一COM对象我的COM方法是无效初始化( AppsScriptRunningContext RC);在这种方式

  • 我试着读出的属性和得到这个错误

无法转换类型
'AppsScriptLib.AppsScriptRunningContextClass'的COM对象的接口类型
'AppsScriptLib.IAppsScriptRunningContext。此操作失败的
,因为该接口
IID为{4D2E5723-87C2-49C1-AA28-ED2D88275100}'的COM组件调用QueryInterface失败,原因是以下错误
:没有这样的接口支持(从HRESULT异常:
0x80004002(E_NOINTERFACE))

Unable to cast COM object of type 'AppsScriptLib.AppsScriptRunningContextClass' to interface type 'AppsScriptLib.IAppsScriptRunningContext'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{4D2E5723-87C2-49C1-AA28-ED2D88275100}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))

如果我的应用程序不是一个COM服务器,而是一个正常的COM应用程序没有错误。
这就是为什么我认为错误是由EXE COM服务器产生的。

If my app is not a com server but a normal com app there is no error. Thats why I think the error is produced by the exe com server.

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

问候,克里斯 -

推荐答案

这是一个非常遗憾的代码示例中,与它有成功的几率是非常接近于零。这是MSDN论坛支持团队的产品,他们的工作不被微软的同行评审。一位团队成员后来承认这,是不是这样做的正确方法

That's a very regrettable code sample, the odds of having success with it are very close to zero. It is a product of the MSDN forums support group and their work isn't being peer-reviewed at Microsoft. One team member later acknowledged that this is not the correct way to do it.

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

An issue with that code is that it completely ignores the Remark in the MSDN documentation for RegistrationServices.RegisterTypeForComClients() method:

请注意,使用平台调用调用非托管CoRegisterClassObject和CoDisconnectObject方法,登记和COM的对象注销不支持。

Note that using platform invoke to call the unmanaged CoRegisterClassObject and CoDisconnectObject methods for registration and unregistration of COM objects is not supported.

不幸的是没有解释为什么它不支持。关键的问题是,一个COM接口,总是需要过程外的激活情况进行编组。这是通过创建一个代理的在客户端,接口的实例具有所有的相同的方法,原来的界面,但其实现的方法发送方法的参数通过RPC其他进程完成。在服务器侧,存根执行相同但相反的作用,构建与方法参数的堆栈帧并在实际的方法调用。

Unfortunately without explaining why it isn't supported. The key problem is that a COM interface always needs to be marshaled in an out-of-process activation case. This is done by creating a proxy at the client side, an instance of the interface that has all the same methods as the original interface but whose implemented methods send the arguments of the method to the other process through RPC. At the server side, a stub performs the same but opposite role, building a stack frame with the method arguments and making the actual method call.

创建代理和存根在.NET相当容易,反射变得非常简单。通过远程处理管道建成框架完成。它是但不容易在COM中,它不具有类似于反射任何东西。有两种基本方式它能够完成,首先由IDL语言编写COM接口定义和MIDL.EXE编译它。它可以自动生成C源代码,不会从中你可以建立一个DLL的编组。然后,该DLL必须在HKCR\Interface注册表项中正确注册,以便COM可以找到并加载每当接口需要编组的DLL。如果您的接口是从IDispatch接口和限制自身OLE自动化兼容的参数类型派生的第二种方法是可用的。然后,您可以生成一个类型库,并使用标准编组。这需要类型库在HKCR\Interface注册,以及适当的键,以便COM知道它。

Creating the proxy and the stub is pretty easy in .NET, reflection makes it simple. Done by the Remoting plumbing built into the framework. It is however not easy in COM, it doesn't have anything similar to reflection. There are two basic ways it gets done, firstly by writing the COM interface definitions in the IDL language and compiling it with midl.exe. Which can automatically generate the C source code that does the marshaling from which you can build a DLL. That DLL then needs to be registered properly in the HKCR\Interface registry key so that COM can find and load the DLL whenever the interface needs to be marshaled. A second way is available if your interface is derived from IDispatch and limits itself to OLE Automation compatible argument types. You can then generate a type library and use the standard marshaller. This requires the type library to be registered, along with appropriate keys in HKCR\Interface so COM knows about it.

这是不以发生的部分。 NET进程外的服务器。你不必MIDL.EXE帮你生成代理/存根DLL和你没有得到注册帮助使用标准编组。这是什么错误消息实际上是说,这里真的E_NOINTERFACE意味着它找不到任何方法来封送的接口。是的,蹩脚的错误消息。

That's the part that doesn't happen in a .NET out-of-process server. You don't have midl.exe to help you generate the proxy/stub DLL and you don't get the registration help to use the standard marshaller. Which is what the error message is really saying, E_NOINTERFACE here really means that it couldn't find any way to marshal the interface. Yes, crappy error message.

在.NET中正式支持的方式来创建进程外的一个COM服务器与COM +进行注册。使用System.EnterpriseServices.ServicedComponent类作为基类。 MSDN库文章是这里

The officially supported way in .NET to create an out-of-process COM server is to register it with COM+. Using the System.EnterpriseServices.ServicedComponent class as a base class. The MSDN library article is here.

这篇关于无法转换类型'...'的接口类型的COM对象'...',而使用ExeCOMServer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆