无法转换类型为' System .__ ComObject'的COM对象。到类类型AgentInfo

时间:2017-12-22 10:28:17

标签: c# casting com coclass

我有两个C#项目,一个是dll,另一个是Windows窗体应用程序。

我在dll中定义了一个CoClass,如下所示。'

    [ComVisible(true),
    Guid("1620BE13-A68F-4FA3-B5C8-31092D626CDA"),
    ProgId("AgentDLLServer.AgentInfo"),
    ClassInterface(ClassInterfaceType.AutoDispatch),
            ComSourceInterfaces(typeof(IAgentInfoEvents))
    ]
    public class AgentInfo : _IAgentInfo {}

它实现了接口_IAgentInfo,其定义如下

 [
     ComVisible(true),
     Guid("CF803265-AE9D-4308-B790-560FCF63DD4C"),
     InterfaceType(ComInterfaceType.InterfaceIsDual)
    ]
    public interface _IAgentInfo{}

两者都在dll中定义,使用

成功注册
regasm /tlb

在另一个C#windows客户端应用程序中,我尝试通过强制转换从运行对象表获取的对象或从另一个接口获取AgentInfo,如下所示。

_IAgentInfo info =(_IAgentInfo) RotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");`.

上面的代码从ROT中检索对象 或者,我有另一个从ROT获得的接口,定义如下

    [ 
    ComVisible(true),
    Guid("9B539A5F-5671-48AD-BF9B-7A9AF150CE39"),
    InterfaceType(ComInterfaceType.InterfaceIsDual)
    ]
    public interface _IAgentDLLServer
    { AgentInfo GetAgentInfo();}

我从ROT获得对接口_IAgentDLLServer的引用,然后在其上调用方法GetAgentInfo()

`_IAgentDLLServer server=  (_IAgentDLLServer)RotNativeMethods.GetObject("BizBrainAgentService.AgentServer") `AgentInfo info=server.GetAgentInfo();

我可以将它转换为_IAgentInfo,但是当我尝试将返回的对象强制转换为AgentInfo时,如下所示

 AgentInfo info =(_IAgentInfo) rotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");

我收到以下错误

Unable to cast COM object of type 'System.__ComObject' to class type 'AgentDLLService.AgentInfo'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

我尝试了以下解决方案

一个。关于main方法的STAThread,因为帖子提示该帖子就行了 该对象运行的对象无法访问类型信息 按照 Why cannot I cast my COM object to the interface it implements in C#?

湾更改了应用配置文件,如下所示

    <configuration>
     <startup>
         <supportedRuntime version="v4.0.30319" sku=".NETFramework,Version=v4.5"/>
   </startup>
</configuration>

,版本与注册表的InProcServer32中的版本匹配

HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{1620BE13-A68F-4FA3-B5C8-31092D626CDA}\InprocServer32\1.0.0.0\RuntimeVersion, 

按照

.NET Framework 4.5 is default and .NET Framework 3.5 is optional The strange case of System.InvalidCastException (“Unable to cast COM object of type ‘System.__ComObject’ to class type System.Windows.Forms.UserControl”) showing toolwindow

℃。我尝试了ComImport方法

[ComImport,
    Guid("1620BE13-A68F-4FA3-B5C8-31092D626CDA")]
    public class AgentInfo { } 

在我要使用此对象的类中,按照 A lean method for invoking COM in C#

d。双重投射对象

AgentInfo info =(AgentInfo)(object)rotNativeMethods.GetObject(&#34; BizBrainAgentService.AgentInfo&#34;);

按照 Why can't I cast this interface to a concrete class?

使用as运算符

object obj=rotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");
AgentInfo info=obj as AgentInfo

F。在agentInfoClass上实现IProvideClassInfo和IProvideClassInfo2接口[使用ComImport属性导入它们]

在所有这些尝试之后,我想知道是否可以从COM接口或运行对象表返回COM CoClass,而不是COM接口。

另外,另一个问题是,根据消息,AgentInfo被视为C#/点网类型而不是COM类型。这真的是这样吗?在这种情况下,演员会失败。

我知道返回一个CoClass而不是一个接口可能不是一个好习惯,但我需要能够从AgentInfo对象中侦听事件,而这似乎不可能来自接口。

1 个答案:

答案 0 :(得分:0)

如何定义BizBrainAgentService.AgentInfo?您需要访问哪些AgentInfo方法和_IAgentInfo中不可用的方法?

AgentInfo info =(_IAgentInfo) rotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");

您似乎将BizBrainAgentService.AgentInfo转换为接口_IAgentInfo,只要BizBrainAgentService.AgentInfo实现它就可以了。

您无法将其强制转换回AgentInfo,因为对象类型仍然存在 BizBrainAgentService.AgentInfo。

在COM中,QueryInterface用于导航到不同的接口https://docs.microsoft.com/en-us/cpp/atl/queryinterface

您看到的错误解释了这一点 -

Unable to cast COM object of type 'System.__ComObject' to class type 'AgentDLLService.AgentInfo'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

COM事件是否会使用连接点帮助实现接收?