c# - 无法将类型为 'System.__ComObject' 的 COM 对象转换为类类型 AgentInfo

标签 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 {}

它实现了接口(interface)_IAgentInfo,定义如下

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

两者都定义在一个dll中,使用

注册成功
regasm /tlb

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

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

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

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

我从 ROT 获取对接口(interface) _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,因为有帖子提示thread on 该对象正在运行的对象无权访问类型信息 按照 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#

双重类型转换对象

AgentInfo 信息=(AgentInfo)(object)rotNativeMethods.GetObject("BizBrainAgentService.AgentInfo");

根据 Why can't I cast this interface to a concrete class?

e 使用 as 运算符

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

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

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

此外,另一个问题是,根据消息,AgentInfo 是否被视为 C#/dot 网络类型而不是 COM 类型。真的是这样吗?在这种情况下,转换将失败。

我知道返回 CoClass 而不是接口(interface)可能不是好的做法,但我需要能够从 AgentInfo 对象监听事件,而这似乎无法通过接口(interface)实现。

最佳答案

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

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

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

您不能将其转换回 AgentInfo,因为对象类型仍然是 BizBrainAgentService.AgentInfo.

在 COM 中,QueryInterface 用于导航到不同的界面 https://learn.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 事件接收器会有所帮助吗?

关于c# - 无法将类型为 'System.__ComObject' 的 COM 对象转换为类类型 AgentInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47939922/

相关文章:

c# - MVVM ICommand.CanExecute 参数包含以前的值

c# - 将对象列表转换为 csv 的最快方法,每个对象值都在新行中

c++ - 将 VARIANT 转换为字节,反之亦然?

c#.net COM dll 中断了对 vb6 应用程序的引用

.net - 如何从 VBA 查找 .net ArrayList 中的文字数字?

c# - 如何将日期正确转换为 UTC,然后再将其转换回来?

C# WinForms 搞乱了控制位置?

ios - 将特定类型的对象添加到 Swift 中的泛型 Array<Any>?

casting - 在 SICP 中创建强制程序

c# - 使用接口(interface)的隐式运算符