2
votes

I created outproc COM server, it implements ClassA and ClassB. Factories of both classes are registered with CoRegisterClassObject(REGCLS_SINGLEUSE, CLSCTX_LOCAL_SERVER).

When client app calls CoCreateInstance(ClassA) system creates process of my COM server. When client app calls CoCreateInstance(ClassA) again system creates additional process of my COM server. But when client app call CoCreateInstance(ClassB) system does not create new process, it uses already created. So two classes work in the same process.

Is there a way to force system to create new process for every class of COM server?

Solution (thanks to Hans Passant):

During registration of COM server I just add additional parameter to process path. Now it looks like this:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CLSID\{ClassX_CLSID}\LocalServer32]
@="C:\\Path\\Server.exe -ClassX"

And when process starts I look for -ClassX params in command line and call CoRegisterClassObject only when it present.

1
Technically you could call CoRevokeClassObject in the factory for ClassA to remove the factory for ClassB. It is racy however and bound to go wrong sooner or later, you appear to have multiple clients. Consider that you could provide your server with a command line argument that indicates that either the factory for ClassA or ClassB needs to be created. And modify the two LocalServer32 registry keys to provide that argument. - Hans Passant
@HansPassant Method with LocalServer32 registry key works great. Thanks! Please create "official" answer so that I can accept it. - Denis Anisimov
Just tell us what you did in your own post and accept it as the answer. - Hans Passant

1 Answers

0
votes

The problem is that your COM server starts and registers ALL class factories that it supports. So the application start and registers class factories for ClassA AND ClassB.

If you create an object of type ClassA, the registration for this class factory in this process is discarded. If you make another request for ClassA a new process must be started.

But ClassB may have still a valid registration for the factory of first launched process.

So REGCLS_SINGLEUSE means single use for one class. If you have more registered classes each class may be used once.

You my unregister the other classes with CoRevokeClassObject when one object was created.