Windows サービス VDPROJ を WiX に移行する作業を行っています。
HEAT を使用して、Windows サービス プロジェクトからの出力をフラグメントに収集することができました。現在、カスタム アクションが適切に機能するように、Heat によって生成されたファイルから生成された GUID の一部を、メインの Product.wxs で参照される既知の文字列に手動で変更しています。
WiX プロジェクトを継続的なビルド サーバーに統合する必要があるため、手動の介入に頼るのではなく、ビルドごとにプログラムでこれを行う必要があります。
私が調査できることから、HEAT の出力で XSLT 変換を使用して必要なことを達成できますが、XSLT 変換を機能させるのに苦労しています。
XSLT 変換を使用せずに生成されたフラグメントのセクションを次に示します。
Fragments\Windows.Service.Content.wxs
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
[...]
<Fragment>
<ComponentGroup Id="Windows.Service.Binaries">
<ComponentRef Id="ComponentIdINeedToReplace" />
[...]
</ComponentGroup>
</Fragment>
[...]
<Fragment>
<ComponentGroup Id="CG.WinSvcContent">
<Component Id="ComponentIdINeedToReplace" Directory="TARGETDIR" Guid="{SOMEGUID}">
<File Id="FileIdINeedToReplace" Source="$(var.Windows.Service.TargetDir)\Windows.Service.exe" />
</Component>
[...]
</ComponentGroup>
</Fragment>
[...]
</Wix>
HEAT prebuild コマンドを次のように変更しました。
"$(WIX)bin\heat.exe" project "$(ProjectDir)\..\Windows.Service\Windows.Service.csproj" -gg -pog Binaries -pog Symbols -pog Content -cg CG.WinSvcContent -directoryid "TARGETDIR" -t "$(ProjectDir)Resources\XsltTransform.xslt" -out "$(ProjectDir)Fragments\Windows.Service.Content.wxs"
次の XSLT を作成して、2 つのことを達成しました。
- 「ComponentIdINeedToReplace」のすべての出現箇所を既知の文字列に置き換えます (2 つ存在します)
- "FileIdINeedToReplace" の単一出現を既知の文字列に置き換えます
Resources\XsltTransform.xslt
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable
name="vIdToReplace"
select="//ComponentGroup[@Id='CG.WinSvcContent']/Component/File[contains(@Source,'Windows.Service.exe') and not(contains(@Source,'config'))]/../@Id" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="node[@Id=vIdToReplace]">
<xsl:copy-of select="@*[name()!='Id']"/>
<xsl:attribute name="Id">C_Windows_Service_exe</xsl:attribute>
</xsl:template>
<xsl:template
match="//ComponentGroup[@Id='CG.WinSvcContent']/Component/File[contains(@Source,'Windows.Service.exe') and not(contains(@Source,'config'))]">
<xsl:copy-of select="@*[name()!='Id']"/>
<xsl:attribute name="Id">Windows_Service_exe</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
必要なものを実現するために XSLT を変更するにはどうすればよいですか?