Unable to cast COM object of type 'System.__ComObject' to class type AgentInfo

2.9k Views Asked by At

I have two C# projects, one is a dll and another is a windows forms app.

I have a CoClass defined in the dll as follows` '

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

It implements the interface _IAgentInfo, which is defined as follows

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

Both are defined in a dll, which is registered successfully using

regasm /tlb

In another C# windows client application, I try to access AgentInfo by casting an object obtained from either the Running Object Table, or from another interface as follows`

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

where the above code retrieves the object from the ROT or , I have another interface obtained from the ROT, as defined as follows

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

where I get a reference to the interface _IAgentDLLServer from the ROT, and then call the method GetAgentInfo() on it

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

I can cast it to _IAgentInfo, but when I try to cast the returned object to AgentInfo, as follows

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

I get the following error

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.

I tried the following solutions

a. STAThread on the main method, because a post suggested that the thread on which this object was running did not have access to type information as per Why cannot I cast my COM object to the interface it implements in C#?

b. Changed the app config file as follows

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

and the version matches that in the InProcServer32 of the registry

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

as per

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

c. I tried the ComImport method

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

in the class where I want to use this object, as per A lean method for invoking COM in C#

d. Double casting the object

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

as per Why can't I cast this interface to a concrete class?

e Using the as operator

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

f. Implementing the IProvideClassInfo and IProvideClassInfo2 interfaces [Importing them using the ComImport attribute] on the agentInfoClass

After all these attempts, I wonder whether it is possible to return a COM CoClass from a COM Interface, or the Running Object Table, as opposed to a COM Interface.

Also, another question is, is AgentInfo being treated as a C# /dot net type instead of a COM type, according to the message. Is this really so? In that case, the cast would fail.

I am aware that returning a CoClass rather than an interface may not be good practice, but I need to be able to listen to events from the AgentInfo object, and that does not appear to be possible from interfaces.

1

There are 1 best solutions below

5
On

How is BizBrainAgentService.AgentInfo defined? What methods of AgentInfo you need access to and ones not available in _IAgentInfo?

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

You seem to be casting BizBrainAgentService.AgentInfo to an interface _IAgentInfo which will be fine as long as BizBrainAgentService.AgentInfo implements it.

You can't cast this back to AgentInfo because the object type is still BizBrainAgentService.AgentInfo.

In COM, QueryInterface is used to navigate to a different interface https://learn.microsoft.com/en-us/cpp/atl/queryinterface

The error you see explains this -

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.

Would COM event sink implementation using Connection Points help instead?