Any [oleautomation]
interface (and any [dual]
interface) described in a type library can use the type library marshaler.
Here, you trade the trouble of finding a proxy-stub DLL to that of finding a type library. So, you declare the interface and the type library in your assembly's manifest (directly under the assembly
element) like this:
<comInterfaceExternalProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
tlbid="{TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT}" />
<!-- This also works for a type library embedded in a DLL -->
<file name="FooBar.tlb">
<!-- If you have multiple embedded type libraries, use the resourceid attribute -->
<typelib tlbid="{TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT}"
version="1.0" />
</file>
If your interface were not an [oleautomation]
interface, and you'd want to isolate the proxy-stub DLL, you'd use something like this:
<file name="FooBarPS.dll">
<comInterfaceProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}"
threadingModel="Both" />
</file>
A comInterfaceProxyStub
is much like a comClass
, but focused on proxy/stubs and it gets associated with an interface.
You can accomplish the same effect with a pair of comInterfaceExternalProxyStub
(under an assembly
element level) and comClass
(under a file
element), in case you want to test with and without an isolated proxy/stub DLL, by (un)commenting the proxy/stub file
section:
<comInterfaceExternalProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}" />
<file name="FooBarPS.dll">
<comClass description="PSFactoryBuffer"
clsid="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}"
threadingModel="Both" />
</file>
I'm not sure, but if your standard proxy/stub DLL is used for more than one interface, you must use this approach as well.
EDIT: It seems none of this is new to you. Your problem is that in the session service, even though you activate the dynamically loaded libraries' manifest, that state remains only in the current thread. So, COM worker threads (e.g. RPC threads) will not know about your interfaces, coclasses and proxy/stubs.
The error you see in the broker service (REGDB_E_IIDNOTREG
) might originate in the marshaling back from the session service. You don't get that error in the session service because it happens after your methods return.
However, it might be happening in the broker service, as it's natural: it doesn't load any libraries, much less their manifests.
The approach I suggest you take is to make the session service and the broker service have manifests that depend on the assemblies where you declare the registration-free COM information. This way, it'll all be part of the default activation context and you don't have to do anything regarding activation contexts.
Remember, you have no control over the activation context of a thread you don't own, other than having the default activation context include what you need upfront.
Regarding this part of your question:
I cannot register the proxy/stubs for the DLLs since multiple application may have the same modules, but differing in version, hence the use of registration-free activation.
It's not clear to me what you're trying to say. If your modules are backwards compatible, you don't need to worry. If they're not, use different CLSIDs/ProgIDs.
I hope you don't mean you're using the same IIDs with actually different interfaces, as that is a violation of COM. The best way to solve this problem is to not do it, period. Another way is to have dedicated threads with dedicated activation contexts, both in the session service and in the broker service, which as you've probably seen with only the session service, this is a very brittle approach.
As I see it, you may have no need for COM isolation at all. But if you still want it, you need to do it for both services, broker and session, and do it from their manifests, instead of at runtime.
IDispatch
wrappers via#import
withraw_dispinterfaces
and/orno_dual_interfaces
options, to be used from the client side. – noseratio