【发布时间】:2018-06-05 00:20:10
【问题描述】:
我有两个 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方法上,因为有帖子提示线程放在 此对象正在运行的无权访问类型信息 按照 Why cannot I cast my COM object to the interface it implements in C#?
b.更改应用配置文件如下
<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
c。我尝试了 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("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
f。在 agentInfoClass 上实现 IProvideClassInfo 和 IProvideClassInfo2 接口[使用 ComImport 属性导入它们]
在所有这些尝试之后,我想知道是否可以从 COM 接口或运行对象表返回 COM CoClass,而不是 COM 接口。
另外,另一个问题是,根据消息,AgentInfo 是否被视为 C# /dot 网络类型而不是 COM 类型。真的是这样吗?在这种情况下,演员表会失败。
我知道返回 CoClass 而不是接口可能不是一个好习惯,但我需要能够监听来自 AgentInfo 对象的事件,而这似乎无法通过接口实现。
【问题讨论】: