cominteropcreateinstancercwiunknown

How to manage .Net's RCW COM object creation paramets (namely requested interface)?


I'm using an external native COM component in my C# .NET application.

This COM DLL doesn't have a type library, so I had to write the interop code myself, and having include/idl files I did it like TlbImp does. But the worst thing is that the object creation fails with:

Creating an instance of the COM component with CLSID {40700425-0080-11D2-851F-00C04FC21759} from the IClassFactory failed due to the following error: 80040111

The class is finally created if I use the native CoCreateInstance and specify class_id and one of the implemented interface IIDs.

As it turned out the problem lies in that the COM object's IClassFactory::CreateInstance doesn't support IID_IUnknown passed as the riid parameter, and therefore returns CLASS_E_CLASSNOTAVAILABLE (I identified it with disassembler and debugger). The component is MS SQL VDI.

Is there any way to force the .NET RCW to pass a different interface ID into the CreateInstance method rather than IID_IUnknown? I searched the net a lot, but didn't find a solution for this.

As a workaround I'm using C++/CLI now to create the object, requesting the proper interface instead of IID_IUnknown for this purpose now; but I would like to have code in C#, because C++/CLI requires me to build a different DLL for each platform.

Thanks


Solution

  • I repro. Brr, painful. You could pinvoke CoCreateInstance:

    [return: MarshalAs(UnmanagedType.Interface)]
    [DllImport("ole32.dll", ExactSpelling=true, PreserveSig=false)]
    public static extern object CoCreateInstance(ref Guid clsid, 
        [MarshalAs(UnmanagedType.Interface)] object punkOuter, int context, ref Guid iid);