In a previous post I described how to host a COM server in a managed process using RegistrationServices.RegisterTypeForComClients. I’ve been using this approach successfully for a while, but today I hit a snag. I changed my C# server process from 32-bit to 64-bit, and immediately my 32-bit C++ client could no longer connect.
In theory it shouldn’t matter to the client whether the server is 32-bit or 64-bit – everything is out-of-process so there is no compatibility issue. But I could see that COM was refusing to allow my client to connect to the running 64-bit server process, and instead was trying to launch a new server process (which was failing because I don’t allow that).
I have seen this type of problem many times before with COM, and it’s almost always due to security configuration – specifically the ‘run as’ configuration of the server. So I spent a lot of time investigating that, but it turned out to be something much simpler. Since Windows 2003 SP1, COM has a rule on x64 that if a 32-bit client CoCreates an out-of-proc server, COM will try to connect to a 32-bit server. If the client is 64-bit, COM will try to connect to a 64-bit server. So in my case, COM could see that the 64-bit server was running, but because the client was 32-bit it decided to launch a new (hopefully 32-bit) server process to service the request.
Fortunately there are two easy ways around the problem. The first option is to modify the client to specify CLSCTX_ACTIVATE_64_BIT_SERVER in the CoCreateInstance call. The other (probably better) option is to add a PreferredServerBitness flag to the AppID registry entry for the server.
CLSCTX_ACTIVATE_64_BIT_SERVER is described here, and PreferredServerBitness here.