views:

831

answers:

4

I currently have a .NET class library written in C# that exposes its functionaility via COM to a C++ program (pre-.NET).

We now want to move the library out-of-process to free up address space in the main application (it is an image-processing application, and large images eat up address space). I remember from my VB6 days that one could create an "OLE automation server". The OS would automatically start and stop the server .exe as objects were created/destroyed. This looks like the perfect fit for us: as far as I can see nothing would change in the client except it would call CoCreateInstance with CLSCTX_LOCAL_SERVER instead of CLSCTX_INPROC_SERVER.

How would I create such an out-of-process server in C#? Either there is no information online about it, or my terminology is off/out of date!

A: 

There's certainly no supported way of doing it. The .net framework just doesn't support OLE automation servers.

IIRC, one of my colleages managed something very similar by constructing a very thin VB6 OLE automation server which makes calls to .net code via com. So you have;

  1. C++ client starts VB6 shim via com; you have a running ole automation server.
  2. VB6 exposes methods which delegate straight to the .net library code.

So your C++ is written against VB6 com objects, and the VB6 ole automation server is the thing which calls the .net code. It's more work that I think you were hoping for.

Steve Cooper
+2  A: 

You could always expose your .NET class as COM classes using InteropServices and then configure the library as a COM+ application. The .NET library would run out-of-process and be hosted by a DLLHOST.EXE instance.

Tim Lowes
+2  A: 

You can actually do this in .NET (I've done it before as a proof-of-concept), but it's a bit of work to get everything working right (process lifetime, registration, etc).

Create a new Windows application. In the Main method, call RegistrationServices.RegisterTypeForComClients- this is a managed wrapper around CoRegisterClassObject that takes care of the class factory for you. Pass it the Type of the managed ComVisible class (the one you actually want to create- .NET supplies the class factory automatically) along with RegistrationClassContext.LocalServer and RegistrationConnectionType.SingleUse. Now you have a very basic exe that can be registered as a LocalServer32 for COM activation. You'll still have to work out the lifetime of the process (implement refcounts on the managed objects with constructors/finalizers- when you hit zero, call UnregisterTypeForComClients and exit)- you can't let Main exit until all your objects are dead.

The registration isn't too bad: create a ComRegisterFunction attributed method that adds a LocalServer32 key under HKLM\CLSID(yourclsidhere), whose default value is the path to your exe. Run regasm yourexe.exe /codebase /tlb, and you're good to go.

nitzmahone
Thank you: turns out that lifetime management wasn't an issue: we just start the out-of-process server when the main app starts and shut it down when it finishes. So the only trick was to call RegistrationServices.RegisterTypeForComClients - easy!
Groky
A: 

Here is an article in MSDN that covers all aspects of how to create COM localserver in c# (.net): link

Nedko