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);
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")
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With