【发布时间】:2013-10-15 20:26:39
【问题描述】:
我正在将 Windows 服务 VDPROJ 迁移到 WiX。
我能够使用 HEAT 将我的 Windows 服务项目的输出收集到一个片段中。目前,为了让我的自定义操作正常工作,我手动将一些从 Heat 生成的文件生成的 GUID 更改为在主 Product.wxs 中引用的已知字符串。
我需要在每次构建时以编程方式执行此操作,而不是依赖手动干预,因为我需要将 WiX 项目集成到我们的持续构建服务器中。
根据我的研究,我可以在 HEAT 的输出上使用 XSLT 转换来实现我所需要的,但我很难让我的 XSLT 转换工作。
这是生成的片段的一部分,没有使用 XSLT 转换
片段\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 预编译命令修改为:
"$(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 来实现两件事:
- 将所有出现的“ComponentIdINeedToReplace”替换为已知字符串(有两个)
- 将单个出现的“FileIdINeedToReplace”替换为已知字符串
资源\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 以达到我的需要?
【问题讨论】:
-
IMO,安装程序应该是自动化的,而不是安装程序创作。 30 秒内就能写完的东西浪费了太多时间。