Using COM Exe Server w/o Registry in Win7

6

I have an existing COM Exe Server, and VBA or .NET code calling it. We'd like to make it work w/o needing to install or modify the registry so that other users that are not admins on their machines can use it.

Let's assume changing/modifying the COM Exe Server is not possible (expensive).

Question 1: From what I undertand in Registering a Running EXE Server, the EXE server can call CoRegisterClassObject to register the CLSID in the class table. Does that mean clients should be able to CoGetClassObject from there? (even w/o registry entries for that type/class?)

Question 2: If the above is correct, my EXE Server uses CComModule (deprecated, yes) and I can see is is indeed calling CoRegisterClassObject. Is there a way to verify the class table so see that is is done correctly?

Question 3:
This is the snippet I am using. clsid and iid refer to the coresponding clsid and iid guids. It fails with Interface not registered (Exception from HRESULT: 0x80040155) in the call to CreateInstance. This makes me sad, any idea on what might be wrong?

            var factory = UnsafeNativeMethods.CoGetClassObject(
            clsid,
            RegistrationClassContext.LocalServer,
            IntPtr.Zero,
            typeof(UnsafeNativeMethods.IClassFactory).GUID)
                      as UnsafeNativeMethods.IClassFactory;

            factory.CreateInstance(null, ref iid, out obj);
.net
windows
windows-7
com
asked on Stack Overflow Feb 20, 2014 by moogs • edited Feb 20, 2014 by moogs

1 Answer

8

Question 1: From what I undertand in Registering a Running EXE Server, the EXE server can call CoRegisterClassObject to register the CLSID in the class table. Does that mean clients should be able to CoGetClassObject from there? (even w/o registry entries for that type/class?)

Yes. CoRegisterClassObject will be enough (without registry) to make your out-of-proc object available to any client which calls CoCreateInstance with CLSCTX_LOCAL_SERVER. However, you may have problems with marshaling calls, because the COM proxy/stub DLL and/or type library are not registered. So, a well-know interfaces like IDispatch, IOleCommandTarget etc will be marshaled without problems, but any custom interfaces will fail.

There are other ways to make you EXE server available to the clients, though. To name a few: RegisterActiveObject, IRunningObjectTable.

Question 2: If the above is correct, my EXE Server uses CComModule (deprecated, yes) and I can see is is indeed calling CoRegisterClassObject. Is there a way to verify the class table so see that is is done correctly?

I can only think of calling CoGetClassObject or CoCreateInstance (either needs CLSCTX_LOCAL_SERVER flag) to verify that.

Question 3: This is the snippet I am using. clsid and iid refer to the coresponding clsid and iid guids. It fails with Interface not registered (Exception from HRESULT: 0x80040155) in the call to CreateInstance. This makes me sad, any idea on what might be wrong?

That's weird. The COM standard marshaler returns 0x80040155 (REGDB_E_IIDNOTREG) if it can't find a proxy/stub factory for an interface, but IClassFactory doesn't require a custom proxy. Are you sure you have a correct GUID in your C# definition of IClassFactory? That should be Guid("00000001-0000-0000-C000-000000000046").

answered on Stack Overflow Feb 20, 2014 by noseratio

User contributions licensed under CC BY-SA 3.0