lundi 16 mars 2020

Handle COM events in C# using Reflection

I have a COM object with the main interface and the events interface (from the IDL file):

[
    uuid(<interfaceId>,
    helpstring("AxBitViewerWidget Interface")
]
dispinterface IAxBitViewerWidget
{
    ...
};

[
    uuid(<eventsId>),
    helpstring("AxBitViewerWidget Events Interface")
]
dispinterface IAxBitViewerWidgetEvents
{
    ...
};

[
    aggregatable,
    helpstring("AxBitViewerWidget Class"),
    uuid(<mainClassId>), 
    control
]
coclass AxBitViewerWidget
{
    [default] dispinterface IAxBitViewerWidget;
    [default, source] dispinterface IAxBitViewerWidgetEvents;
};

It was automatically created by Active Qt. Then in C# (in another dll) I want to connect to this COM object and handle its events. The C# class is inherited from AxHost. All COM types are dynamic in my example and used via Reflection. Here is the snippet:

public class BitViewerEx : AxHost
{
    public BitViewerEx()
      : base(<mainClassId>)
    {
    }

    private void Initialize()
    {
        try
        {
            object ocx = GetOcx();
            if (ocx != null)
            {
                Type ocxType = ocx.GetType();
                Guid eventsGuid = new Guid(<eventsId>);
                Type eventsType = Type.GetTypeFromCLSID(eventsGuid);                
                var sinkEventsInterfaceObj = CreateInstanceCore(eventsGuid);

                // runtime error here
                var cookie = new ConnectionPointCookie(ocx, sinkEventsInterfaceObj, eventsType);
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(ex.ToString());
        }
    }
}

When calling ConnectionPointCookie from the above - an error occurs (approximately translated from localized message): "Cannot execute Advise() for the event interface '__ComObject'".

Is my code correct? How to correctly connect AxBase to the COM object events? (for dynamic types case, cannot use IAxBitViewerWidgetEvents etc. in C# code)

P.S.: class methods (not events) are called without an issue, like:

ocx.GetType().InvokeMember("initialize", System.Reflection.BindingFlags.InvokeMethod,
                                                null, ocx, new object[] { this.argum1, this.argum2 });

P.S.2: The following code returns an empty array:

System.Reflection.EventInfo[] arr = ocx.GetType().GetEvents();




Aucun commentaire:

Enregistrer un commentaire