Метод 1. Целевая платформа x86
У меня есть библиотека классов .NET, предназначенная для использования как с 32-разрядными, так и с 64-разрядными клиентами, некоторые из которых являются проектами .NET, а некоторые - проектами C ++ MFC. Я могу заставить библиотеку работать с 32-битными клиентами, но 64-битные клиенты получают исключение «Класс не зарегистрирован». Ковыряться в реестре вроде ставится только ключ win32 (HKEY_CLASSES_ROOT \ Wow6432Node \ TypeLib {GUID} \ 1.0 \ 0 \ win32).
Некоторые примечания к некоторым моим настройкам:
- Проверяется "Зарегистрироваться для COM-взаимодействия".
- Установлен флажок "Сделать сборку COM-видимой".
- «Целевая платформа» - x86.
- Библиотека содержит 32-битную неуправляемую DLL, которая загружает методы с DLLImport.
- Клиенты C ++ MFC используют
#import "MyLibrary.tlb"
для маршалинга кода взаимодействия. - Я не вносил никаких изменений в код для поддержки COM. (Например, я не переопределил System.Configuration.Install.Installer.Install.)
Пытаясь решить эту проблему, я попробовал несколько вещей, основанных на некоторых исследованиях и исследованиях.
Способ 2. Целевая платформа "Любой ЦП"
Сначала я попытался установить для целевой платформы значение «Любой процессор». В этом случае ключи win32 и win64 задаются в реестре, и 64-разрядный клиент может взаимодействовать с COM-сервером. Однако при этом я получаю сообщение об ошибке «Была предпринята попытка загрузить программу с неправильным форматом». Это связано с 32-битной неуправляемой библиотекой DLL, которая требует, чтобы я собирал проект с x86.
Метод 3. Получите 64-разрядную сборку неуправляемой зависимости DLL моей библиотеки
Чтобы обойти это, я потенциально мог бы получить 64-битную сборку неуправляемой DLL. Однако мы приобрели эту DLL у третьей стороны, и по какой-то причине они взимают большую дополнительную плату за 64-битную сборку DLL. Помимо явной стоимости, мне также пришлось бы реализовать вызовы DLLImport для каждого и вызвать в зависимости от того, 32-разрядный он или 64-разрядный, что утроит количество методов в моем классе-оболочке. Таким образом, хотя это возможное решение, оно далеко не желательно, и из того, что я понимаю в отношении COM, в этом не должно быть необходимости.
Метод 4: regsvr32.exe
Наиболее распространенное решение, которое я нахожу в Интернете, - это использовать regsvr32.exe для ручной регистрации приложения как для 32-разрядного, так и для 64-разрядного взаимодействия. Однако мне нужен файл TLB для взаимодействия с моими клиентами MFC и очевидно, что regsvr32 не поддерживает это.
Метод 5: regasm.exe
Чтобы получить файл TLB и, надеюсь, зарегистрироваться как для 32-разрядного, так и для 64-разрядного взаимодействия, я также попытался использовать regasm.exe для регистрации сборки вручную. Для этого я использовал следующую команду.
"%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\regasm.exe" "D:\Path\To\MyLibrary.dll" /tlb /nologo
Однако при этом регистрируется только 64-разрядный COM-сервер, а раздел реестра Win32 COM отсутствует. Теперь мой 32-битный клиент не может найти COM-сервер и говорит: «Класс не зарегистрирован». Более того, для 64-битного клиента я получаю ту же ошибку, что и при выборе «Any CPU»: «Была сделана попытка загрузить программу с неправильным форматом».
TL; DR Как зарегистрировать 32-разрядный COM-сервер для использования как с 32-разрядными, так и с 64-разрядными клиентскими приложениями? (Отметив, что мне нужен файл TLB и что серверу необходимо загрузить неуправляемую 32-разрядную DLL.)
Думаю, мне следует уточнить здесь архитектуру. Вот диаграмма, которая демонстрирует, как я хочу, чтобы эти компоненты работали.
Как видите, мне нужен 64-битный код для взаимодействия с 32-битным кодом через COM-сервер, который, как отмечает @ MC-ND, должен работать. Как мне настроить мой COM-сервер для поддержки этого?