Регистрация Free Com и DLL манифестов - PullRequest
10 голосов
/ 19 октября 2010

Я пытаюсь настроить бесплатный COM для регистрации, но у меня есть небольшая проблема в том, что другим COM-объектом может быть клиент.

App.exe -----> COM Server / Client dll (зарегистрирован или нет) --------> DLL-сервер COM-сервера (НЕ зарегистрирован)

Мои вопросы: возможно ли создать манифест для второй dll (dll COM-сервера / клиента)?У меня нет контроля над исполняемым файлом, но если я это сделал, это работает, если я создаю манифест клиента для исполняемого файла и манифест сервера для dll COM-сервера.

это файл манифеста для средней DLL,Я попытался встроить это и попробовал это внешний.Все еще не работает.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" 
                    name="COMCliSer.dll" 
                    version="1.0.0.0" 
  />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity 
                     name="COMSer.dll" 
                    version="1.0.0.0"                    
      />
    </dependentAssembly>
  </dependency>
</assembly>

При дальнейшем расследовании я могу заставить это все работать, пока средняя dll также бесплатна для регистрации, и у exe есть манифест приложения.Как только я регистрирую среднюю dll и удаляю манифест приложения (я не могу контролировать, какой exe будет использовать мою dll), все это перестает работать.

Если у exe нет манифеста, томанифест dll не принимается во внимание.Я могу доказать это, настроив все на работу.Тогда внесите ошибку в манифест сборки.Появляется обычное сообщение:

Невозможно создать процесс: это приложение не удалось запустить из-за неправильной конфигурации приложения.Переустановка приложения может решить эту проблему.

Если я затем отбрасываю манифест приложения, приложение загружается (хотя CoCreateInstance завершается ошибкой, поскольку зависимости не учитываются)

1 Ответ

5 голосов
/ 19 октября 2010

Просто добавьте зависимость сборки в манифест dll сервера / клиента, который указывает на dll com-сервера.

Помните, что манифесты сборки отличаются от манифестов «приложения»: манифест сборки описывает сборку: дает ей имя и перечисляет ее dll. Манифест приложения - это встроенный ресурс RT_MANIFEST, который описывает текущие зависимости модулей.

Итак, в конечном итоге вы получите:

  • app.exe, с внешним (app.exe.manifest) или встроенным RT_MANIFEST, описывающим зависимость от сборки под названием 'acme.clientserver'
  • acme.clientserver.manifest, описывающий сборку, и перечисление clisrv.dll в качестве бесплатной регистрации.
  • clisrv.dll с внешним (clisrv.dll.2.manifest) или встроенным RT_MANIFEST, описывающим зависимость от сборки с именем acme.server
  • acme.server.manifest, описывающий сборку, перечисляющий serv.dll в качестве бесплатной регистрации dll.
  • serv.dll - который может, а может и не иметь манифеста, перечисляя еще больше зависимых сборок.

Технически возможно вызвать сборку по имени dll и объединить сборку и манифест dll вместе - загрузчик win32 поддерживает это, но некоторые параметры, действительные в манифестах приложения, недопустимы в манифестах сборки, что может привести к невозможности загрузки полученной сборки. Это также затрудняет цифровую подпись.


WRT для exe, имеющего манифест: Обычно манифест exe устанавливает контекст активации процессов по умолчанию. Я не уверен на 100%, как ведут себя окна, когда у exe нет манифеста, но я почти уверен, что манифесты в dll все равно будут обрабатываться.

Это означает, что проблема сводится к отсутствию поддержки изоляции в CoCreateInstance - по какой-то причине - по умолчанию - CoCreateInstance ищет только в контексте активации по умолчанию для обычных записей com.

Способ переопределить его - создать собственный контекст активации вручную, используя API-интерфейс активации

.

Основной метод будет вызывать:

  • CreateActCtx - для создания контекста активации из вашего манифеста dll.
  • ActivateActCtx - для активации контекста
  • CoCreateInstance - теперь будет выполнять поиск в текущем контексте активации для бесплатных записей com.
  • DeactivateActCtx - для восстановления контекста активации по умолчанию.

Вы можете добавить / D ISOLATION_AWARE_ENABLED для переноса большинства вызовов Windows, которые выполняются контекстами активации, по какой-то причине CoCreateInstance не переносится: /

...