Question

I have been a passive user on stackoverflow for a long time and found a lot of helpful information, but this is my first question here. I'm afraid that my first question is a little vague, because I don't show code, but rather describe the problem. I'm not looking for a direct solution, but rather for some hints about further readings that will allow my to understand the cause of my problem.

My problem is about a C# WPF application (.NET 4.0), that is using the TPL to make parallel calls to an out-of-process COM server. The out-of-process COM server is a quite expensive commercial application used in mechanical engineering - let's call it MechEngApp. The COM server is a 64 bit executable. My C# WPF application is an interactive program used to automate some computations in the MechEngApp. It connects to the MechEngApp, reads some input from it, makes some computation on its own and writes to results back to MechEngApp. We are currently preparing to switch to a new version of MechEngApp. While in version X everything worked fine, we are having a strange problem in the new version Y.

My C# WPF app works like this:

  • the MechEngApp (out-of-process COM server) is already running (only one instance running)
  • from the main thread my C# WPF app connects to the COM server calling Marshal.GetActiveObject("MechEngApp.Application"). This object is used through the whole program.
  • the user selects interactively some input elements (still in the main WPF thread)
  • after the input is the done, the main computation is performed with a backgroundworker thread.
  • in the backgroundworker I use TPL's Parallel.For, Parallel.ForEach or Parallel.Invoke to make something inside the MechEngApp (calling the COM server)

With the current version X of the MechEngApp this has been working for years without any problems. In the new version Y of the MechEngApp we have a problem in a certain configuration:

  1. If my C# app is build as a 32 bit application, I can call the COM server of the MechEngApp with sequential or parallel calls - everything is fine.
  2. If my C# app is build as a 64 bit application, I can call the COM server of the MechEngApp with sequential calls without any problems.
  3. If my C# app is build as a 64 bit application and if I use parallel calls from the TPL, I get an COMException of the type TYPE_E_LIBNOTREGISTERED.

After that we started investigating and found out that the TypeLibs of the MechEngApp had only registry entries for win32 (HKCR\TypeLib, HKCR\Wow6432Node\TypeLib, HKLM\SOFTWARE\Classes\TypeLib, HKLM\SOFTWARE\Classes\Wow6432Node\TypeLib). We tried to duplicate them as win64 entries and suddenly the case no. 3 worked as well.

So I have a solution for my problem, but I don't understand why and how it works. I have read a lot in the past weeks to increase my knowledge about the use of out-of-process COM, but I still can't answer some questions:

A) For out-of-process COM mixing 32 and 64 bit clients and servers shouldn't really matter, should it?

B) I have read that for in-process COM the ThreadingModel is important, but for out-of-process it shouldn't matter. Right?

C) When are win64 TypeLib entries in the registry important? Only if the COM server offers different typelibs for 32 bit and 64 bit clients?

D) What's the difference in the inter process communication, when the win64 entries exist? Why is my case no. 3 behaving different when the win64 entries exist?

E) Related to D: Why does building my C# app as 32 or 64 bit program influence the behaviour of the out-of-process COM server?

F) The version X of the MechEngApp, that we used for years without any problems, is also an 64 bit application that doesn't have the win64 entries. If the win64 entries are important, why did it work in the past?

Was it helpful?

Solution

A) For out-of-process COM mixing 32 and 64 bit clients and servers shouldn't really matter, should it?

COM takes care of this, but it's always good to have the matching bit-ness.

B), C), E), F)

See below.

D) What's the difference in the inter process communication, when the win64 entries exist? Why is my case no. 3 behaving different when the win64 entries exist?

We don't know for sure what's going on inside that 3rd party out-of-proc server process (e.g. whether it uses an MTA apartment with multiple threads, a single STA thread or multiple STA threads), so I can only speculate.

That said, I imagine there was no cross-thread COM marshalling inside MechEngApp COM server process, until you introduced concurrency on the client side. Once you did that, you probably also introduced multi-threading inside MechEngApp process. Apparently, MechEngApp relies on the COM typelib marshaller, when it marshals COM objects between its own threads (e.g., with CoMarshalInterface). This would be in-process marshalling as it takes place inside the MechEngApp process. For that to work correctly, the proper 64-bit registry keys must be present for the 64-bit app.

You could have also got it working by running MechEngApp.exe /RegServer with admin rights, probably.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top