Как заставить COM без регистрации работать в управляемом / неуправляемом взаимодействии

У меня есть неуправляемый внутрипроцессный COM-объект C ++ / ATL (в Unmanaged.dll), который я пытаюсь использовать из управляемой библиотеки C # DLL (Managed.dll). Однако я хочу использовать COM без регистрации. У меня есть следующие шаги:

  • Зарегистрируйте COM-объект на машине разработки. Внутрипроцессный сервер должен иметь правильно зарегистрированную библиотеку типов.
  • Добавьте ссылку на COM-объект в проект C #, а затем установите для свойств ссылки значение Isolated = True.

Это создает Unmanaged.dll, Managed.dll и Native.Managed.manifest. Открыв манифест, довольно ясно, как система использует его для загрузки COM-объекта без регистрации.

Вот в чем загвоздка. У меня есть управляемый EXE (Managed.exe), который динамически загружает Managed.dll для доступа к общедоступным типам. Под «динамически» я подразумеваю то, что он использует Assembly.LoadFrom («Managed.dll»). Когда код внутри Managed.dll пытается создать COM-объект, он получает исключение «класс не зарегистрирован». Похоже, контекст активации не настраивается правильно при загрузке Managed.dll.

Есть ли способ получить бесплатную регистрацию COM для работы в этом сценарии?


person Charles    schedule 22.03.2011    source источник


Ответы (1)


Два дня без ответа, вот что я придумал за это время ...

Действительно, похоже, что контекст активации настраивается ОС при запуске процесса на основе манифеста, связанного с основным EXE. Это означает, что все не требующие регистрации элементы, связанные с COM, должны находиться в файле Main.exe.manifest во время запуска процесса. Это нарушает изоляцию между EXE и DLL. Если DLL отвечает за создание COM-объектов, вы не ожидаете, что EXE-манифест должен содержать информацию о COM без регистрации. Вы могли ожидать, что манифест, связанный с DLL, будет объединен с контекстом активации процесса во время загрузки DLL, но этого не произошло.

Чтобы обойти это, DLL должна настроить новый контекст активации перед созданием COM-объекта. Что еще хуже, в настоящее время (начиная с .NET 4.0) нет управляемого способа сделать это. Таким образом, DLL должна будет выполнить PInvoke для следующих функций Win32:

Я заключил эти вызовы в управляемый класс, который вызывает CreateActCtx и ActivationActCtx в конструкторе, а DeativateActCtx и ReleaseActCtx - в IDisposable :: Dispose.

person Charles    schedule 24.03.2011
comment
И ты заставил это работать? У меня очень похожая проблема: Regfree ActiveX используется из управляемой библиотеки DLL, которая загружается и запускается nUnit, поэтому я не могу взломать манифест приложения. А вот функции ActCtx у меня работать отказываются, наверное чего-то простого не хватает ... - person Spike0xff; 31.08.2011