自定义 "base" 个项目的事件检测清单以满足 "derived" 个项目的需求
Customize the event instrumentation manifest of a "base" project to match the needs of "derived" projects
我正在处理两个共享大部分代码的不同 C++ DLL 项目。
因此,我有一个编译为 Base.lib
的基础项目和两个编译为 Derived1.dll
和 Derived2.dll
以及 link 和 Base.lib
的 "derived" 项目。这些派生的 DLL 应独立运送。用户甚至不知道他们是相关的。
现在我希望我的两个 DLL 都是 windows event providers。我想要记录的所有事件都发生在 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
把它编译成一个资源文件和一个头文件。我的 Base 项目的其他源文件正在包含头文件。
现在效果出奇的好!两个 DLL 的所有事件都已正确记录。
但是,当然,这两个 DLL 现在共享具有相同名称、GUID 和消息的相同提供程序。
所以,我的实际问题是:
如何使 Instrumentation.man
中的 provider
元素以我的 DLL 项目可以填充它们自己的 name
、guid
和 message
属性的方式进行自定义?
我正在使用 WiX 创建我的安装包。 WiX 允许我在 DLL 部署到目标系统时自定义 provider
元素的 resourceFileName
和 messageFileName
属性(均指向原始文件中的虚拟对象),以便它们可以被正确引用。但是,WIX 没有提供类似的方式(至少我没有看到)来平滑地改变其他属性,这正是我想要的。
我还注意到 WiX 提供自定义 parameterFileName
属性。不幸的是,我找不到这些参数如何工作的任何信息。我知道我可以将 %%n
放入清单中的字符串中,然后将插入标识符为 n
的参数。但是我不明白在哪里以及如何声明这些参数另外,我不知道我是否可以在我想要自定义的属性中使用它们,这样它们对我根本没有帮助。
我最终编写了自己的 XML 修改工具(在 C# 中描述 here,但任何其他语言也可以)它获取清单文件和解决方案名称并替换相应的属性值。
为了使这项工作自动进行,我向调用此工具的 Base 项目添加了一个预构建事件,并将清单文件和 $(SolutionName)
.
传递给它。
此解决方案既不美观也不易扩展,但它确实有效。
我正在处理两个共享大部分代码的不同 C++ DLL 项目。
因此,我有一个编译为 Base.lib
的基础项目和两个编译为 Derived1.dll
和 Derived2.dll
以及 link 和 Base.lib
的 "derived" 项目。这些派生的 DLL 应独立运送。用户甚至不知道他们是相关的。
现在我希望我的两个 DLL 都是 windows event providers。我想要记录的所有事件都发生在 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
把它编译成一个资源文件和一个头文件。我的 Base 项目的其他源文件正在包含头文件。
现在效果出奇的好!两个 DLL 的所有事件都已正确记录。
但是,当然,这两个 DLL 现在共享具有相同名称、GUID 和消息的相同提供程序。
所以,我的实际问题是:
如何使 Instrumentation.man
中的 provider
元素以我的 DLL 项目可以填充它们自己的 name
、guid
和 message
属性的方式进行自定义?
我正在使用 WiX 创建我的安装包。 WiX 允许我在 DLL 部署到目标系统时自定义 provider
元素的 resourceFileName
和 messageFileName
属性(均指向原始文件中的虚拟对象),以便它们可以被正确引用。但是,WIX 没有提供类似的方式(至少我没有看到)来平滑地改变其他属性,这正是我想要的。
我还注意到 WiX 提供自定义 parameterFileName
属性。不幸的是,我找不到这些参数如何工作的任何信息。我知道我可以将 %%n
放入清单中的字符串中,然后将插入标识符为 n
的参数。但是我不明白在哪里以及如何声明这些参数另外,我不知道我是否可以在我想要自定义的属性中使用它们,这样它们对我根本没有帮助。
我最终编写了自己的 XML 修改工具(在 C# 中描述 here,但任何其他语言也可以)它获取清单文件和解决方案名称并替换相应的属性值。
为了使这项工作自动进行,我向调用此工具的 Base 项目添加了一个预构建事件,并将清单文件和 $(SolutionName)
.
此解决方案既不美观也不易扩展,但它确实有效。