2

我有两个 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.

我尝试了以下解决方案

一个。STAThread 在 main 方法上,因为一篇文章建议运行此对象的线程没有访问类型信息的权限,按照 为什么我不能将我的 COM 对象转换为它在 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 是默认的,.NET Framework 3.5 是可选 的 ,System.InvalidCastException 的奇怪情况(“无法将类型为'System.__ComObject' 的 COM 对象转换为类类型 System.Windows.Forms.UserControl”)显示工具窗口

C。我尝试了 ComImport 方法

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

在我想使用这个对象的类中,按照 在 C# 中调用 COM 的精益方法

d。双重铸造对象

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

根据 为什么我不能将此接口转换为具体类?

e 使用 as 运算符

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

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

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

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

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

4

1 回答 1

0

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

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

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

由于对象类型仍然是 BizBrainAgentService.AgentInfo,因此无法将其转换回 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 事件接收器会有所帮助吗?

于 2017-12-22T12:22:21.643 回答