如何使用msbuild更改检测清单中的属性值?

时间:2016-10-18 16:26:57

标签: xml msbuild eventlog-source xmlpoke

Microsoft EventRegister Tool在项目编译期间创建一个检测清单文件以及一个资源文件。我想在编译后将这些文件移动到另一个路径,并使用msbuild更改检测清单文件中的两个属性。属性的值相同,每个属性表示伴随资源文件的路径。似乎我无法获得使用msbuild修改属性的语法,我觉得它与两件事有关。

首先,检测清单文件不包含经典的xml文件声明。其次,检测清单包括命名空间。

到目前为止,由于博客文章"Updating XML files with MSBuild" by Sayed Ibrahim Hashimi,我得出的是:

<PropertyGroup>
    <SourceManifestAssembly>$(OutputPath)Name.etwManifest.dll</SourceManifestAssembly>
    <DestinationManifestAssembly>$(Programdata)\MyCompany\MyProduct\1.0.0.0\Name.etwManifest.dll</DestinationManifestAssembly>
    <SourceManifest>$(OutputPath)Name.etwManifest.man</SourceManifest>
    <DestinationManifest>$(Programdata)\MyCompany\MyProduct\1.0.0.0\Name.etwManifest.man</DestinationManifest>
</PropertyGroup>
<ItemGroup>
    <UpdateManifest Include="UpdatemessageFileName">
        <NewValue>$(DestinationManifestAssembly)</NewValue>
        <Namespaces>&lt;Namespace Prefix='x'  Uri='http://schemas.microsoft.com/win/2004/08/events' /&gt;</Namespaces>
        <XPath>//x:events/provider/@messageFileName</XPath>
    </UpdateManifest>
    <UpdateManifest Include="UpdateresourceFileName">
        <NewValue>$(DestinationManifestAssembly)</NewValue>
        <Namespaces>&lt;Namespace Prefix='x'  Uri='http://schemas.microsoft.com/win/2004/08/events' /&gt;</Namespaces>
        <XPath>//x:events/provider/@resourceFileName</XPath>
    </UpdateManifest>
</ItemGroup>
<Target Name="AfterBuild">
    <Copy SourceFiles="$(SourceManifestAssembly)" DestinationFiles="$(DestinationManifestAssembly)" />
    <Copy SourceFiles="$(SourceManifest)" DestinationFiles="$(DestinationManifest)" />
    <XmlPoke XmlInputPath="$(DestinationManifest)" Query="%(UpdateManifest.XPath)" Value="%(UpdateManifest.NewValue)" Namespaces="%(UpdateManifest.Namespaces)" />
</Target>

这会处理复制,但不会更改属性值。

检测清单文件如下所示:

<instrumentationManifest xmlns="http://schemas.microsoft.com/win/2004/08/events">
<instrumentation xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events">
    <events xmlns="http://schemas.microsoft.com/win/2004/08/events">
        <provider name="MyCompany-MyProduct-MyLog" guid="{658FE45E-C2D4-4E73-82BB-6441A0348D9B}" resourceFileName="C:\Documents\Visual Studio\Projects\Name\bin\Debug\Name.etwManifest.dll" messageFileName="C:\Documents\Visual Studio\Projects\Name\bin\Debug\Name.etwManifest.dll" symbol="MyCompanyMyProductMyLog">
        </provider>
    </events>
</instrumentation>

需要更改的属性为//provider/@resourceFileName//provider/@messageFileName

1 个答案:

答案 0 :(得分:0)

在Windows Installer XML Util扩展中,元素EventManifest用于安装事件清单。此elemnent在安装期间安排配置文件更改,这完全符合上述要求。在启用安装日志的情况下运行安装后,我只需查看日志并检查SchedXmlFile条目。在那里我找到了以下XPath表达式:

/*/*/*/*[@messageFileName]

我尝试了这个代码片段,当您使用以下表示法时,似乎可以省略XPath名称空间:

<PropertyGroup>
    <SourceManifestAssembly>$(OutputPath)Name.etwManifest.dll</SourceManifestAssembly>
    <DestinationManifestAssembly>$(Programdata)\MyCompany\MyProduct\1.0.0.0\Name.etwManifest.dll</DestinationManifestAssembly>
    <SourceManifest>$(OutputPath)Name.etwManifest.man</SourceManifest>
    <DestinationManifest>$(Programdata)\MyCompany\MyProduct\1.0.0.0\Name.etwManifest.man</DestinationManifest>
</PropertyGroup>
<ItemGroup>
    <UpdateManifest Include="UpdatemessageFileName">
        <NewValue>$(DestinationManifestAssembly)</NewValue>
        <XPath>/*/*/*/*/@messageFileName</XPath>
    </UpdateManifest>
    <UpdateManifest Include="UpdateresourceFileName">
        <NewValue>$(DestinationManifestAssembly)</NewValue>
        <XPath>/*/*/*/*/@resourceFileName</XPath>
    </UpdateManifest>
</ItemGroup>
<Target Name="AfterBuild">
    <Copy SourceFiles="$(SourceManifestAssembly)" DestinationFiles="$(DestinationManifestAssembly)" />
    <Copy SourceFiles="$(SourceManifest)" DestinationFiles="$(DestinationManifest)" />
    <XmlPoke XmlInputPath="$(DestinationManifest)" Query="%(UpdateManifest.XPath)" Value="%(UpdateManifest.NewValue)" />
</Target>