Search code examples
comstaticactivexvstoout-of-process

.NET out-of-process COM objects sharing static instances in API calls


It's hard to explain our situaction.

We have a 3-tier application. The engine is a DLL coded in C++, then we have a VB6 ActiveX EXE that access to the engine via API calls, and at the top level we have a Excel Addin (in C# using VSTO framework) calling the middle layer with an interop DLL. At this time, each "connection" from the Addin to the engine creates a new EXE (VB6 uses API calls to access to the engine) and all works fine. Now we are moving the middle layer to .NET, it works 'presumably' fine (it pass all our Unit test) but, we found an error when we open 2 "connections" at same time (ups, no unit test check this situation because it's a new behavour). The DLL have static objects that it's shared over all instances in the same process and we have interactions between "connections". In our old version each "connection" creates a new EXE with no memory sharing between processes, now it's the same process and they share memory and the static objects.

Following the tips from this question. We tried to build a COM EXE in C# to do an out-of-process objects in the middle layer but we have the same result. They share the static objects, at the end, each connection not creates a independent process.

It's clear, but not affordable at this time, moving API calls to ATL or changing the static objects to instanciable references with a handle and change all the API calls to get/set this handlers. I reviewed all examples in MS All-in-one but I didn't find any solution. Neither it's possible to keep only one connection at time, each workbook can have one connection and in the future we want to explore a Web application with multiple connections at same time.

Any suggestion?

Thanks in advance,


Solution

  • Whether COM starts new EXE per each COM object, or uses single EXE to instantiate all the object is controlled by flags parameters passed to CoRegisterClassObject. See

    http://msdn.microsoft.com/en-us/library/ms693407(v=vs.85).aspx, and

    http://msdn.microsoft.com/en-us/library/ms679697(v=vs.85).aspx

    You need to pass REGCLS_SINGLEUSE or REGCLS_MULTI_SEPARATE flags.

    Now, the trick is to pass this flag, as you might not call this method directly - the details depend on how you implemented the COM EXE.