我有两个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对象中侦听事件,而这似乎不可能来自接口。
答案 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事件是否会使用连接点帮助实现接收?