Method 1: x86 target platform
I have a .NET class library that is intended for use with both 32-bit and 64-bit clients, some of which are .NET projects and some of which are C++ MFC projects. I can get the library to work with the 32-bit clients, but the 64-bit clients get a "Class not registered" exception. Poking around the registry, it looks like only the win32 key is being set (HKEY_CLASSES_ROOT\Wow6432Node\TypeLib{GUID}\1.0\0\win32).
Some notes on a few of my settings:
- "Register for COM interop" is checked.
- "Make assembly COM-Visible" is checked.
- The "Platform target" is x86.
- The library contains a 32-bit unmanaged DLL that loads methods with DLLImport.
- The C++ MFC clients use
#import "MyLibrary.tlb"
to marshall the interop code. - I have not made any changes to the code to support COM. (E.g., I have not overridden System.Configuration.Install.Installer.Install.)
In an effort to resolve this, I have tried several things based on some research and investigation.
Method 2: "Any CPU" target platform
First, I tried setting the Platform target to "Any CPU". In this case, both the win32 and win64 keys are set in the registry, and the 64-bit client can talk to the COM server. However, when I do this, I get the error "An attempt was made to load a program with the incorrect format." This is due to the 32-bit unmanaged DLL, which requires that I build the project with x86.
Method 3: Obtain a 64-bit build of my library's unmanaged DLL dependency
To work around this, I could potentially get a hold of the 64-bit build of the unmanaged DLL. However, we have purchased this DLL from a third party, and for whatever reason, they charge a large, additional fee for the 64-bit build of the DLL. On top of the explicit cost, I would also have to implement DLLImport calls for each and call according to whether it's 32-bit or 64-bit, which would triple the number of methods in my wrapper class. Thus, while this is a possible solution, it's far from desirable, and from what I understand about COM, this shouldn't be necessary.
Method 4: regsvr32.exe
The most common solution I find online for this is to use regsvr32.exe to manually register an application for both 32-bit and 64-bit interop. However, I need the TLB file for interoperability with my MFC clients, and apparently regsvr32 doesn't support this.
Method 5: regasm.exe
To get the TLB file and hopefully register for both 32-bit and 64-bit interop, I have also tried using regasm.exe to register the assembly manually. I used the following command to do this.
"%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\regasm.exe" "D:\Path\To\MyLibrary.dll" /tlb /nologo
However, this registers only the 64-bit COM server and the win32 COM registry key is missing. Now my 32-bit client can't find the COM server and says "Class not registered." Furthermore, for the 64-bit client, I get the same error that I saw when I selected "Any CPU": "An attempt was made to load a program with an incorrect format."
TL;DR How do I register a 32-bit COM server for use with both 32-bit and 64-bit client applications? (Noting that I need the TLB file, and that the server needs to load an unmanaged, 32-bit DLL.)
I think I should clarify the architecture here. Here's a diagram that demonstrates how I want these components to function.
As you can see, I need 64-bit code to interact with 32-bit code by means of a COM server, which, as @MC-ND notes, is supposed to work. How should I configure my COM server to support this?
From MSDN: Process Interoperability
Your best option seems to compile your component as a 32bit out of process COM server.