2010-10-19 2 views
10

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

App.exe -----> COM сервер/клиент длл (зарегистрированный или нет) --------> COM сервера DLL (не зарегистрирован)

Мои вопросы, можно создать манифест для второй dll (COM-сервер/клиентская dll)? Я не контролирую исполняемый файл, но если это так, это работает, если я создаю манифест клиента для исполняемого файла и манифест сервера для 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> 

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

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

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

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

+0

Почему вы называете сборку 'comser.dll'? Является ли информация о манифесте сборки объединенной? Гораздо проще развернуть сборку с описательным именем, например. «Microsoft.VC90.CRT», который содержит dll с разными именами: «msvcr90.dll». При работе с dll-сборками сложнее отлаживать, поскольку один манифест теперь служит двум целям: описать содержимое сборки для потребителей и описать зависимости DLL в сборке. –

+0

Имена были изменены, чтобы защитить невинных! Это не настоящие имена. Это родные COM-библиотеки DLL, а не сборки .NET. – Steve

+0

Кроме того, что означает «не работает»? Загружает ли exe и 2-й DLL и просто не создает экземпляр третьего, или exe или 2-й dll не могут полностью загрузиться? Невозможность загрузки на самом деле - хороший шаг, так как это означает, что система видит манифест и регистрирует ошибку в системном или прикладном журнале событий как минимум. Если его просто не удается вызвать вызов CoCreateInstance, то он, вероятно, просто не увидит манифест вообще. –

ответ

5

Просто добавьте зависимость сборки на сервере/манифеста клиента библиотеки 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 как бесплатная регистрация.
  • serv.dll - который может или не может, в свою очередь, показывать манифесты еще более зависимых сборок.

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


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

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

Путь переопределить это вручную создать свой собственный контекст активации, используя Activation Context API

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

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

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

+0

У меня нет app.exe.manifest (он не нужен, так как зарегистрирован средний com dll). Я попытался добавить манифест в среднюю dll, но безрезультатно. – Steve

+0

Вы открыли среднюю dll в редакторе ресурсов (например, для визуальной студии) и видели, есть ли у него ресурс RT_MANIFEST и что в нем? VS всегда отображает RT_MANIFESTS как hex, поэтому вам нужно экспортировать его, чтобы просмотреть его как текст. –

+0

Хорошо, сделал это. У dll есть два RT_Manifests, один из которых, я полагаю, был поставлен там компилятором (Delphi), обозначающим общие элементы управления Windows в качестве зависимости, а другой 1, который я добавил, который показан выше. – Steve