Com Server Inproc passing Clas instead of interface. Server mode not working

-1

So I am trying to get a com server working. It is very basic. Just printing a string. The Full code is:

    namespace ComServer
    {
        // Since the .NET Framework interface and coclass have to behave as 
        // COM objects, we have to give them guids.
        [ComImport]
        [Guid("2bfa05b5-5615-45f2-97b1-79fff6ff97d5"), ComVisible(true), Description("Print string interface")]
        public interface IManagedInterface
        {
            [DispId(0), Description("Print name")]
            int PrintHi(string name);
        }

        [Guid("61ab17b3-6e61-4942-b353-70b74f8aec1a")]
        [ComVisible(true), ClassInterface(ClassInterfaceType.None), Description("Print string")]
        [ComDefaultInterface(typeof(IManagedInterface))]
        public class InterfaceImplementation : IManagedInterface
        {
            public int PrintHi(string name)
            {
                Console.WriteLine("Hello, {0}!", name);
                return 33;
            }
        }
    }

I do have register for COM interop ticked. And as far as I can tell it is getting registered.

Registrey values

If I try using the CoCreateInstance call in the client as a CLSCTX_INPROC_SERVER I get back the class implmentation(InterfaceImplementation) not the interface. I I try calling it with the CLSCTX_LOCAL_SERVER I get the E_CLASSNOTREG error.

I am not quite sure what I am doing wrong. I am very new to COM and C# in general.

Here is my client code:

    namespace ComClient
    {
        class Program
        {
            public const string ComSvrInterface_GUID = "2bfa05b5-5615-45f2-97b1-79fff6ff97d5";
            public const string ComSvrClass_GUID = "61ab17b3-6e61-4942-b353-70b74f8aec1a";




            [STAThread]
            static void Main(string[] args)
            {
                Ole32Methods.CoInitialize((IntPtr)0); // Sets up com library

                object instance1 = null;
                string sErr1;
                bool b1;
                IManagedInterface cCom = null;

                b1 = Ole32Methods.CreateComObject(ComSvrClass_GUID, ComSvrInterface_GUID, out instance1, out sErr1);

                if (b1)
                {
                    cCom = instance1 as IManagedInterface;
                }

                if (cCom != null)
                {
                    cCom.PrintHi("Santa Claus");
                    Console.WriteLine("Should have just printed Santa Claus");
                }

            }
        }

        // -------------------------------------------

        // Reproduce the interface here so we can cast to it
        [Guid("2bfa05b5-5615-45f2-97b1-79fff6ff97d5")]
        public interface IManagedInterface
        {
            int PrintHi(string name);
        }

        // -------------------------------------------

        public class Ole32Methods
        {
            [DllImport("ole32.Dll")]
            static public extern uint CoCreateInstance(ref Guid clsid,
                [MarshalAs(UnmanagedType.IUnknown)] object inner,
                uint context,
                ref Guid uuid,
                [MarshalAs(UnmanagedType.IUnknown)] out object rReturnedComObject);

            [DllImport("ole32.dll")]
            public static extern int CoInitialize(IntPtr pvReserved);

            // ------------------------

            public static bool CreateComObject(string sClassGuid, string sInterfaceGuid, out object instance, out string sErr)
            {
                const uint CLSCTX_INPROC_SERVER = 1;
                const uint CLSCTX_LOCAL_SERVER = 4;

                // CLSID of the COM object
                Guid clsid = new Guid(sClassGuid);

                // GUID of the required interface
                //Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
                Guid IID_Interface = new Guid(sInterfaceGuid);

                instance = null;

                uint hResult = Ole32Methods.CoCreateInstance(ref clsid, null,
                                CLSCTX_LOCAL_SERVER, ref IID_Interface, out instance);


                // Some error codes. See 'winerror.h for more, and use the following to convert the debug value to Hex: http://www.rapidtables.com/convert/number/decimal-to-hex.htm

                const uint S_OK = 0x00000000;       //Operation successful
                const uint E_NOTIMPL = 0x80004001;       //Not implemented
                const uint E_NOINTERFACE = 0x80004002;       //No such interface supported
                const uint E_POINTER = 0x80004003;       //Pointer that is not valid
                const uint E_ABORT = 0x80004004;       //Operation aborted
                const uint E_FAIL = 0x80004005;       //Unspecified failure
                const uint E_UNEXPECTED = 0x8000FFFF;       //Unexpected failure
                const uint E_ACCESSDENIED = 0x80070005;       //General access denied error
                const uint E_HANDLE = 0x80070006;       //Handle that is not valid
                const uint E_OUTOFMEMORY = 0x8007000E;       //Failed to allocate necessary memory
                const uint E_INVALIDARG = 0x80070057;       //One or more arguments are not valid

                const uint E_CLASSNOTREG = 0x80040154;      // Class not registered

                sErr = "";
                switch (hResult)
                {
                    case S_OK:
                        sErr = "";
                        break;
                    case E_NOTIMPL:
                        sErr = "E_NOTIMPL: Not implemented";
                        break;
                    case E_NOINTERFACE:
                        sErr = "E_NOINTERFACE: No such interface supported";
                        break;
                    case E_POINTER:
                        sErr = "E_POINTER: Pointer that is not valid";
                        break;
                    case E_ABORT:
                        sErr = "E_ABORT: Operation aborted";
                        break;
                    case E_FAIL:
                        sErr = "E_FAIL: Unspecified failure";
                        break;
                    case E_UNEXPECTED:
                        sErr = "E_UNEXPECTED: Unexpected failure";
                        break;
                    case E_ACCESSDENIED:
                        sErr = "E_ACCESSDENIED: General access denied error";
                        break;
                    case E_HANDLE:
                        sErr = "E_HANDLE: Handle that is not valid";
                        break;
                    case E_OUTOFMEMORY:
                        sErr = "E_OUTOFMEMORY: Failed to allocate necessary memory";
                        break;
                    case E_INVALIDARG:
                        sErr = "E_INVALIDARG: One or more arguments are not valid";
                        break;

                    case E_CLASSNOTREG:
                        sErr = "E_CLASSNOTREG: Class not registered";
                        break;
                }

                return hResult == 0;

            }

        }
    }

Thanks

c#
com
com-server
comclass
asked on Stack Overflow Mar 16, 2020 by bulb • edited Mar 17, 2020 by bulb

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0