Я знаком с процессом регистрации COM Interop. Например:
Пока я запускаю Visual Studio с правами администратора, эта DLL C# COM будет компилироваться и регистрироваться для взаимодействия. TLB
создан. Так что есть проблемы с этим процессом. И у меня нет проблем (технически) с использованием DLL во время выполнения моего приложения.
Вот проблема:
regasm
. Итак, после установки я могу без проблем запустить установленное приложение.Класс не зарегистрирован
Я понимаю проблему, я думаю. Установщик производит регистрацию:
2024-04-11 15:01:09.874 -- Run entry --
2024-04-11 15:01:09.874 Run as: Current user
2024-04-11 15:01:09.874 Type: Exec
2024-04-11 15:01:09.889 Filename: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe
2024-04-11 15:01:09.889 Parameters: MyFile_x64.dll /codebase
2024-04-11 15:01:10.108 Process exit code: 0
Но версия этой DLL для Visual Studio, хранящаяся в папке выпуска исходных кодов, не зарегистрирована. И поэтому путь к этой DLL не найден в реестре. Итак, я получаю эту ошибку:
Класс не зарегистрирован
Поскольку это DLL и она используется из приложения Visual C++, я импортирую файл TLB следующим образом:
#ifdef _WIN64
#import "..\\..\\xxx\\yyy\\bin\\x64\\Release\\MyFile.tlb" raw_interfaces_only named_guids
#else
#import "..\\..\\xxx\\yyy\\bin\\x86\\Release\\MyFile.tlb" raw_interfaces_only named_guids
#endif
Не знаю, поможет ли это. Использование DLL соответствует ожиданиям:
void CFoo::Init()
{
throw_if_fail(m_pInterface.CreateInstance(__uuidof(XXX::XXXClass)));
}
Какой шаг мне здесь не хватает как для установленных версий, так и для компилируемых версий?
Я могу это подтвердить:
Две соответствующие сборки DLL настроены на регистрацию параметра COM-взаимодействия. Итак, создайте те TLB, которые нам нужны.
Мой установщик правильно регистрирует соответствующие библиотеки DLL:
Filename: "{dotnet40}\regasm.exe"; \
Parameters: "MSAToolsLibrary_x86.dll /codebase"; \
WorkingDir: "{app}\MSAToolsLibrary"; \
Flags: runhidden; \
Check: not Is64BitInstallMode
Filename: "{dotnet40}\regasm.exe"; \
Parameters: "MSAToolsGMailLibrary_x86.dll /codebase"; \
WorkingDir: "{app}\MSAToolsGMailLibrary"; \
Flags: runhidden; \
Check: not Is64BitInstallMode
Filename: "{dotnet4064}\regasm.exe"; \
Parameters: "MSAToolsLibrary_x64.dll /codebase"; \
WorkingDir: "{app}\MSAToolsLibrary"; \
Flags: runhidden; \
Check: Is64BitInstallMode
Filename: "{dotnet4064}\regasm.exe"; \
Parameters: "MSAToolsGMailLibrary_x64.dll /codebase"; \
WorkingDir: "{app}\MSAToolsGMailLibrary"; \
Flags: runhidden; Check: Is64BitInstallMode
Они регистрируются с правильным regasm
, и после установки я могу запустить любое приложение. Это я знаю.
Я просто не могу запустить основное локальное приложение.
Если я вручную скопирую свой exe-файл выпуска x64 в установленную папку C PF, щелкните по нему - это сработает.
@SimonMourier Сортировано. Добавлен ответ.
Проблема, по-видимому, заключалась в том, что я добавил событие после сборки в свой проект DLL, чтобы скопировать файлы DLL в подпапку моего исходного проекта C++. Так:
Теперь все хорошо. Библиотеки DLL появляются в одном из трех мест:
Прежде всего, может быть только один COM-сервер (dll или exe), обслуживающий данный classId/progId. Затем, если COM-сервер является dll, регистрация разрядности его клиента должна совпадать (например, если клиент x86, он будет искать в части реестра x86, если клиент x64, он будет искать в части реестра x64). «Класс не зарегистрирован» означает, что клиент не может найти здесь зарегистрированный сервер по идентификатору класса (или progid) при просмотре соответствующего реестра. Итак, сначала проверьте, где вы прописываете COM-сервер и соответствует ли разрядность клиента. Обратите внимание: ничего из того, что я сказал, не зависит от Visual Studio, это только COM.