Какие теги требуются в манифесте для регистрации свободного COM?

TL; DR Делать все записи реестра, созданные regsvr32 нужно присутствовать в манифесте SxS reg-free-COM и наоборот?


Я пытаюсь получить бесплатную регистрацию COM для стороннего компонента.

чтение вверх на Я считаю, что в предмете упоминается несколько элементов, которые можно поместить в манифест:

Из документов, мы можем добавить следующие теги в манифест для описания COM-компонента:

  • assemblyIdentity — который на самом деле просто описывает «абстрактный сборка«насколько я могу судить
  • comClass — описывает класс COM (интерфейс IID). Казалось бы, это всегда нужно.
  • typelib — когда?
  • comInterfaceExternalProxyStub — когда?
  • comInterfaceProxyStub — когда?

Из других документов для HKEY_LOCAL_MACHINE\SOFTWARE\Classes мы можем заметить, что есть несколько категорий для записей реестра COM:

С помощью regsvr42 чтобы извлечь материал, который я пытаюсь освободить DLL дает манифест, который содержит только comClass записей, нет записей typelib или ProxyStub. (И я перепроверил написанные ключи, DLL, о которой идет речь, pdm.dllДиспетчер отладки процессов MS записывает только эти ключи, т. Е. В реестре отсутствует информация о библиотеке типов или заглушки прокси.)

Если реестр содержит только информацию, которая относится к comClass означает ли это, что этой информации будет достаточно в манифесте SxS, или может потребоваться дополнительная информация в манифесте?


Кроме того, я заметил, что реестр содержит VersionIndependentProgId и ProgId в конце которого добавлен номер версии. Манифест имеет только ProgId запись и состояние документов:

ProgID : Зависящий от версии программный идентификатор, связанный с
COM компонент. Формат ProgID — это
<vendor>.<component>.<version>,

Но документы также утверждают

comClass элемент может иметь <progid>...</progid> элементы как
дочерние элементы, в которых перечислены зависимые от версии программы.

а также они говорят что атрибут progid должен быть независимым от версии.

Итак, что здесь поставить? И имеет ли значение, когда клиент не запрашивает конкретную версию?

13

Решение

Элемент assemblyIdentity всегда требуется, часть манифеста сантехника. Вы всегда должны предоставлять элемент comClass, он заменяет HKLM\Software\Classes\CLSID ключ реестра и используется для работы вызова CoCreateInstance () клиента. Элемент file называет исполняемый файл COM-сервера.

Остальные ключи являются необязательными, они необходимы для работы маршалинга. Маршалинг происходит, когда клиентский вызов должен быть выполнен в другом потоке. Что будет всегда Это происходит, когда сервер и клиент находятся в разных процессах, например, для сервера вне процесса или когда сервер работает на другом компьютере. И это может произойти, когда ThreadingModel, указанный в элементе comClass, требует этого. Другими словами, когда COM-объект был создан в одном потоке, но вызывается в другом, а сервер не является потокобезопасным.

RPC реализует маршалинг, но у него есть одна задача, с которой ему нужна помощь. Необходимо знать, каковы аргументы функции, а также тип возвращаемого значения. Так что он может правильно сериализовать их значения в пакет данных, который может быть передан по сети или передан в код в другом потоке, который выполняет вызов. Это работа прокси. Заглушка работает на принимающей стороне и десериализует аргументы для построения стекового фрейма и выполняет вызов. Возвращаемое значение функции, а также любые значения аргументов, переданные по ссылке, затем возвращаются к вызывающей стороне. В противном случае код, который делает вызов, совершенно не осознает, что не вызывал функцию напрямую.

Есть четыре основных случая:

  • COM-сервер вообще не поддерживает такой вызов и должен всегда использоваться из того же потока, в котором он был создан. Остановитесь там, не нужно ничего добавлять к манифесту.

  • COM-сервер реализует IMarshal интерфейс. Автоматически запрашивается COM, когда он не может найти другой способ упорядочить вызов. Это довольно редко, за исключением случая, когда COM-сервер агрегирует маршаллер со свободным потоком. Другими словами, сам по себе полностью поточно-ориентирован, без какой-либо помощи и всегда работает в процессе. ДПМ, скорее всего, будет работать именно так. Остановитесь там, не нужно ничего добавлять к манифесту.

  • Автор COM-сервера начал свой проект, написав описание интерфейса сервера на языке IDL. Который был тогда скомпилирован MIDL. Один из доступных вариантов — автоматическая генерация кода из объявлений IDL, код, который можно использовать для создания отдельной библиотеки DLL, реализующей прокси и заглушку. IDL достаточно богат, чтобы описать детали типов аргументов функции и их использования, чтобы позволить маршалинг выполнять этим автоматически сгенерированным кодом. Иногда атрибутов IDL недостаточно, автор COM затем пишет пользовательский маршаллер. COM загружает эту DLL во время выполнения для автоматического создания объектов прокси и заглушки.

  • Специфично для подмножества COM Automation (интерфейс IDispatch), в Windows есть встроенный маршаллер, который знает, как упорядочить вызовы, отвечающие требованиям подмножества. Очень распространенный. Он использует библиотеку типов для обнаружения объявления функции.

Последние две пули требуют использования HKLM\Software\Classes\Interface, он имеет записи для IID для каждого интерфейса. Вот как COM узнает, как создать прокси и заглушку для интерфейса. Если он не может найти ключ, он возвращается к IMarshal. Вы должны использовать элемент comInterfaceExternalProxyStub для замены раздела реестра. Использование comInterfaceProxyStub является особым случаем, когда прокси-код и заглушка включаются в исполняемый файл COM-сервера, а не в отдельный файл. Например, опция в проектах ATL включена с помощью мастера «Разрешить объединение прокси / заглушки».

В последнем маркере также требуется использование элемента typelib, чтобы встроенный маршаллер мог найти нужную ему библиотеку типов.

ProgId требуется, когда COM-клиент использует позднюю привязку через IDispatch, вспомогательная функция CreateObject () в клиентской библиотеке поддержки времени выполнения является шаблонной. Используется в любом скриптовом хосте, например.

Наличие некоторой внутренней информации о том, как был создан COM-сервер, безусловно, помогает, всегда обращайтесь к поставщику или автору за советом. Однако его можно перепроектировать, посмотрев, какие разделы реестра записываются при регистрации сервера. Инструмент SysInternals ProcMon — лучший способ убедиться в этом. Основные вещи для поиска:

  • Если вы видите, напишите HKLM\Software\Classes\Interface ключ, то вы можете предположить, что вы должны предоставить элемент comInterface | External | ProxyStub

  • Если вы видите его, напишите {00020420-0000-0000-C000-000000000046} для ключа ProxyStubClsid32, тогда вы можете предположить, что он использует стандартный маршаллер, и вы должны использовать элемент comInterfaceExternalProxyStub, а также элемент typelib. Затем вы также должны увидеть, как он записал раздел реестра IID TypeLib, а также запись в разделе реестра HKLM \ Software \ Classes \ Typelib. Последний дает путь к библиотеке типов. Почти всегда так же, как COM-сервер, встраивание библиотеки типов в качестве ресурса очень распространено. Если это отдельный файл (файл .tlb), вы должны его развернуть.

  • Если значение ключа ProxyStubClsid32 является другим guid, то вы можете предположить, что оно использует свою собственную DLL прокси / заглушки. Затем вы также должны увидеть, как он пишет ключ CLSID для прокси, его ключ InProcServer32 дает вам путь к DLL. Если это имя файла совпадает с именем файла сервера, вы можете предположить, что код прокси / заглушки был объединен, и вместо этого вы должны использовать элемент comInterfaceProxyStub. Если нет, то comInterfaceExternalProxyStub требуется, и вы должны развернуть DLL

  • Если вы видите это, напишите ProgID в HKLM\Software\Classes затем используйте элемент progid, в точности как показано на графике.

14

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]