Я работаю над двумя разными DLL-проектами на C ++, которые используют большую часть своего кода. Итак, у меня есть один базовый проект, который компилируется в Base.lib, и два "производных" проекта, которые компилируются в Derived1.dll и Derived2.dll и связываются с Base.lib. Эти производные библиотеки DLL должны быть отправлены независимо. Пользователь даже не знает, что они связаны.

Теперь я хочу, чтобы обе мои библиотеки DLL были поставщиками событий Windows.. Все события, которые я хочу регистрировать, происходят в Base.lib. Итак, я добавил Instrumentation.man в этот проект и сделал его частью сборки. Его содержимое выглядит примерно так:

<?xml version="1.0" encoding="UTF-16"?>
<instrumentationManifest xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd" xmlns="http://schemas.microsoft.com/win/2004/08/events" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:trace="http://schemas.microsoft.com/win/2004/08/events/trace">
  <instrumentation>
    <events>
      <provider name="Company-Provider-Base" guid="{12345678-1234-1234-1234-1234567890ABCD}" symbol="provider" resourceFileName="some/path/to.dll" messageFileName="some/path/to.dll" message="$(string.provider.message)">
        <events>
            ...
        </events>
      </provider>
    </events>
  </instrumentation>
  <localization>
    <resources culture="en-US">
      <stringTable>  
        <string id="provider.message" value="Base Provider" />
        ...
      </stringTable>
    </resources>
  </localization>
</instrumentationManifest>

Я использую mc.exe, чтобы скомпилировать это в файл ресурсов и файл заголовка. Заголовочный файл включается в другие исходные файлы моего базового проекта.

Теперь это работает на удивление хорошо! Все события регистрируются правильно для обеих библиотек DLL.

Однако, конечно, теперь обе библиотеки DLL используют одного и того же поставщика с одинаковым именем, идентификатором и сообщением.

Итак, мой настоящий вопрос таков: Как сделать элемент provider в Instrumentation.man настраиваемым таким образом, чтобы мои проекты DLL могли заполнять свои собственные атрибуты name, guid и message ?

Я использую WiX для создания своих установочных комплектов. WiX позволяет мне настраивать атрибуты resourceFileName и messageFileName элемента provider (оба указывают на фиктивные элементы в исходном файле) только тогда, когда библиотеки DLL развертываются в целевой системе, чтобы они могли ссылаться правильно. Однако WIX не предлагает аналогичного способа (по крайней мере, я его не вижу) для столь же плавного изменения других атрибутов, что было бы именно тем, что я хочу.

Я также заметил, что WiX предлагает настроить атрибут parameterFileName. К сожалению, я не могу найти никакой информации о том, как работают эти параметры. Я понимаю, что могу поместить %%n в строки в манифесте, и тогда будет вставлен параметр с идентификатором n. Но я не понимаю, где и как объявлять эти параметры, плюс я не знаю, могу ли я использовать их в атрибутах, которые я хочу настроить, чтобы они мне вообще не помогли.

2
sebrockm 20 Ноя 2018 в 16:44

1 ответ

Лучший ответ

В итоге я написал свой собственный инструмент для модификации XML (на C #, как описано здесь, но любой другой язык тоже подойдет), который берет файл манифеста и имя решения и соответственно заменяет значения атрибутов.

Чтобы это работало автоматически, я добавил событие предварительной сборки в базовый проект, которое вызывает этот инструмент и передает ему файл манифеста и $(SolutionName).

Это решение нельзя назвать ни красивым, ни легко масштабируемым, но оно работает.

0
sebrockm 7 Дек 2018 в 11:21