0

I need to implement an out-ofproc server in C#. The basic server part is done and the server is accessible by progid like this: "someNamespace.someClassname".

But now i want something like this: "progid:Application(set=somevalue)".

Is there any way to do this in C#?

Up to now I register a factory and this factory returns the com object.

        Guid appClsId = new Guid(ComCst.ApplicationId);

        int hRes = ComNtv.CoRegisterClassObject(ref appClsId, new ApplicationFac(), 
            CLSCTX.LOCAL_SERVER, REGCLS.MULTIPLEUSE | REGCLS.SUSPENDED, out cokAppObj);
        if (hRes != 0)
        {
            throw new ApplicationException(
                "CoRegisterClassObject failed w/err 0x" + hRes .ToString("X"));
        }

        hRes = ComNtv.CoResumeClassObjects();
        if (hRes != 0)
        {
            if (cokAppObj!= 0)
            {
                ComNtv.CoRevokeClassObject(cokAppObj);
            }

            throw new ApplicationException(
                "CoResumeClassObjects failed w/err 0x" + hRes .ToString("X"));
        }

And this is the CreateInstance Method in the factory.

public int CreateInstance(IntPtr pUnkOuter, ref Guid riid,
        out IntPtr ppvObject)
    {
        ppvObject = IntPtr.Zero;

        if (pUnkOuter != IntPtr.Zero)
        {
            Marshal.ThrowExceptionForHR(ComCst.CLASS_E_NOAGGREGATION);
        }

        if (riid == new Guid(ComCst.ApplicationId) ||
            riid == new Guid(ComCst.IID_IDispatch) ||
            riid == new Guid(ComCst.IID_IUnknown))
        {
            IntPtr ptr = Marshal.GetComInterfaceForObject(
               new Application(), typeof(IApplication));

            ppvObject = ptr;
        }
        else
        {
            Marshal.ThrowExceptionForHR(ComCst.E_NOINTERFACE);
        }

        return 0;
    }

Info: There is an already implemented c++ in-proc com server, which is creating an object and register it in the running object table. This server than returns a moniker to the client. Is it possible to accomblish this in C#?

Tony
  • 1
  • 1
  • There is no programming language where "progid:Application(set=somevalue)" is a sensible statement. Makes it pretty hard to help you, I would have to guess that you want to pass an argument to the constructor. You can't, COM only supports a default constructor. – Hans Passant Feb 19 '16 at 10:40
  • But the implementation in c++ is registered with a progid in the registry only. And the com factory returns a moniker. And the parsedisplayname returns a moniker which is bind to an object in the running object table i think. So this statement works there. The constructor is a default constructor. – Tony Feb 19 '16 at 11:16
  • In an c# Client the com object can be reached via Marshal.BindtoMoniker("progid:Application(set=somevalue)"). This invokes the CreateInstance method of my factory but than it throws this exception: HRESULT: 0x800401E4 (MK_E_SYNTAX) – Tony Feb 19 '16 at 11:25

0 Answers0