For development, I use an out-of-process COM server contained in an EXE file without registering it. This works fine as long as the clients only use late binding and I start the server EXE before starting one single client. (The server registers a class factory, which then is used by the client.)
I know that this is a hack, and I know this can stop working with the next update of any OS component. I'm only doing this for development, not for testing, and definitely not for anything related to production.
However, using events doesn't work: The client reports a CONNECT_E_CANNOTCONNECT in the call to IConnectionPoint.Advise, i.e. when "subscribing" to the event.
How can I make this work?
Some details:
I have an interface
IFooEventswith GUID{111blah...}, and the client (according to Procmon) tries to look upHKCR\Interfaces\{111blah...}. If this key was present, it would contain:[HKEY_CLASSES_ROOT\Interface\{111blah...}] @="IFooEvents" [HKEY_CLASSES_ROOT\Interface\{111blah...}\ProxyStubClsid32] @="{00020420-0000-0000-C000-000000000046}" <-- PSDispatch? [HKEY_CLASSES_ROOT\Interface\{111blah...}\TypeLib] @="{GUID of the server assembly}" "Version"="1.0"What's relevant here? Is it the
PSDispatch, and if yes, is there a way I can provide this information at runtime?
My test client happens to be .NET, and uses dynamic to make sure late binding is used.
Stack trace:
System.Runtime.InteropServices.COMException: 'No such interface supported at System.Runtime.InteropServices.ComTypes.IConnectionPoint.Advise(Object pUnkSink, Int32& pdwCookie) at System.Dynamic.ComEventSink.Initialize(Object rcw, Guid sourceIid) at System.Dynamic.ComEventSink..ctor(Object rcw, Guid sourceIid) at System.Dynamic.ComEventSink.FromRuntimeCallableWrapper(Object rcw, Guid sourceIid, Boolean createIfNotFound) at System.Dynamic.BoundDispEvent.InPlaceAdd(Object handler) at System.Dynamic.BoundDispEvent.TryBinaryOperation(BinaryOperationBinder binder, Object handler, Object& result) at CallSite.Target(Closure , CallSite , Object , SomethingHappenedEventHandler ) at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1) at Program.Main().NET framework stepping fails, VS reports that it can't find
Binder.cs, and I wasn't able to step through the code. Moreover, I couldn't find the source of any of the code in the stack trace.For the sake of completeness: Everything works fine when the COM server EXE file is registered.
If it's not possible, I'd appreciate to know why, simply to learn more about COM.