【问题标题】:WiX Installer: using xslt with heat.exe to update attributesWiX 安装程序:使用 xslt 和 heat.exe 更新属性
【发布时间】:2011-11-07 09:40:39
【问题描述】:

我正在尝试为 Windows 服务创建 WiX 安装程序,并且我已阅读到我需要将所有文件的 KeyPath 设置为“no”,但我的 WiX 脚本中的 .exe 除外。 我目前正在使用 Heat.exe 生成我的目录和文件结构,这是我的命令:

"$(WIX)bin\heat.exe" dir $(SolutionDir)EmailGenerationService\bin\PROD 
                    -cg EmailGenFiles -gg -scom -sreg -sfrag -srd -suid 
                    -dr INSTALLLOCATION -var var.FileSource 
                    -t $(Projectdir)KeyPathTransform.xslt 
                    -out $(ProjectDir)DirectoryAndFileComponents.wxs

我打算在我的 DirectoryAndFileComponents.wxs 文件中用Keypath=”no” 更新所有文件元素。 热量输出的示例是:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <DirectoryRef Id="INSTALLLOCATION">
      <Component Id="Dollar.Common.dll" Guid="{2BCD0767-2383-47CF-B1BF-325FA4A3264F}">
        <File Id="Dollar.Common.dll" KeyPath="yes" Source="$(var.FileSource)\Dollar.Common.dll" />
      </Component>
      <Component Id="Dollar.Common.Exceptions.dll" Guid="{B7238091-76D1-42F5-A3B4-A539DFF3BD92}">
        <File Id="Dollar.Common.Exceptions.dll" KeyPath="yes" Source="$(var.FileSource)\Dollar.Common.Exceptions.dll" />
      </Component>
      <Component Id="Dollar.Common.Exceptions.pdb" Guid="{43711979-747D-49C9-BAE4-ECD44FAF5E67}">
        <File Id="Dollar.Common.Exceptions.pdb" KeyPath="yes" Source="$(var.FileSource)\Dollar.Common.Exceptions.pdb" />
      </Component>
      <Component Id="Dollar.Common.Logging.dll" Guid="{59F9ABF3-5F68-410C-BC96-0556282F1E04}">
        <File Id="Dollar.Common.Logging.dll" KeyPath="yes" Source="$(var.FileSource)\Dollar.Common.Logging.dll" />
      </Component>

这是我传递给 heat 以执行转换的 XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
            exclude-result-prefixes="msxsl" 
            xmlns:wix="http://schemas.microsoft.com/wix/2006/wix"
            xmlns:my="my:my">

  <xsl:output method="xml" indent="no"/>

  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match='/wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Component/wix:File[@Id and not (@Id="EmailGenerationService.exe")]'>
    <xsl:attribute name="KeyPath">
          <xsl:value-of select="no"/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

我已经根据本网站和其他地方的其他帖子尝试了很多变体,但至今仍无法让 heat.exe 创建的文件具有 KeyPath=”no”。

我是否遗漏了一些明显的东西?

【问题讨论】:

    标签: xml xslt xpath installation wix


    【解决方案1】:

    你有两个不同的定义命名空间:

    1. 在 XML 中:http://schemas.microsoft.com/wix/2006/wi
    2. 在 XSLT 中:http://schemas.microsoft.com/wix/2006/wix

    据我所知,WiX 的正确命名空间是 http://schemas.microsoft.com/wix/2006/wi。所以你应该改变你的 XSLT。

    XSLT:

    <xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl"
                xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
                xmlns:my="my:my">
    
        <xsl:output method="xml" indent="yes" />
    
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match='wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Component/wix:File[@Id and not (@Id = "EmailGenerationService.exe")]'>
            <xsl:copy>
                <xsl:apply-templates select="@*"/>
                <xsl:attribute name="KeyPath">
                    <xsl:text>no</xsl:text>
                </xsl:attribute>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    输入 XML:

    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
        <Fragment>
            <DirectoryRef Id="INSTALLLOCATION">
                <Component Id="Dollar.Common.dll" Guid="{2BCD0767-2383-47CF-B1BF-325FA4A3264F}">
                    <File Id="Dollar.Common.dll" KeyPath="yes" Source="$(var.FileSource)\Dollar.Common.dll" />
                </Component>
                <Component Id="Dollar.Common.Exceptions.dll" Guid="{B7238091-76D1-42F5-A3B4-A539DFF3BD92}">
                    <File Id="Dollar.Common.Exceptions.dll" KeyPath="yes" Source="$(var.FileSource)\Dollar.Common.Exceptions.dll" />
                </Component>
                <Component Id="Dollar.Common.Exceptions.pdb" Guid="{43711979-747D-49C9-BAE4-ECD44FAF5E67}">
                    <File Id="Dollar.Common.Exceptions.pdb" KeyPath="yes" Source="$(var.FileSource)\Dollar.Common.Exceptions.pdb" />
                </Component>
                <Component Id="Dollar.Common.Logging.dll" Guid="{59F9ABF3-5F68-410C-BC96-0556282F1E04}">
                    <File Id="Dollar.Common.Logging.dll" KeyPath="yes" Source="$(var.FileSource)\Dollar.Common.Logging.dll" />
                </Component>
            </DirectoryRef>
        </Fragment>
    </Wix>
    

    输出 XML:

    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
      <Fragment>
        <DirectoryRef Id="INSTALLLOCATION">
          <Component Id="Dollar.Common.dll" Guid="{2BCD0767-2383-47CF-B1BF-325FA4A3264F}">
            <File Id="Dollar.Common.dll" Source="$(var.FileSource)\Dollar.Common.dll" KeyPath="no" />
          </Component>
          <Component Id="Dollar.Common.Exceptions.dll" Guid="{B7238091-76D1-42F5-A3B4-A539DFF3BD92}">
            <File Id="Dollar.Common.Exceptions.dll" Source="$(var.FileSource)\Dollar.Common.Exceptions.dll" KeyPath="no" />
          </Component>
          <Component Id="Dollar.Common.Exceptions.pdb" Guid="{43711979-747D-49C9-BAE4-ECD44FAF5E67}">
            <File Id="Dollar.Common.Exceptions.pdb" Source="$(var.FileSource)\Dollar.Common.Exceptions.pdb" KeyPath="no" />
          </Component>
          <Component Id="Dollar.Common.Logging.dll" Guid="{59F9ABF3-5F68-410C-BC96-0556282F1E04}">
            <File Id="Dollar.Common.Logging.dll" Source="$(var.FileSource)\Dollar.Common.Logging.dll" KeyPath="no" />
          </Component>
        </DirectoryRef>
      </Fragment>
    </Wix>
    

    【讨论】:

    • 感谢您的回复,但这也不起作用。 Heat 运行正常,没有错误,但生成的文件在所有节点上仍然有 KeyPath="yes"。
    【解决方案2】:

    我不会回答你原来的问题。 :)

    我读到我需要将所有文件的 keyPath 设置为“no”, .exe 除外

    我认为你被误导了。实际上,ServiceInstall table 有一个列 Component_,根据 MSDN:

    使用 InstallService 表安装此服务,KeyPath 这个组件必须是服务的可执行文件。

    这并不意味着其他组件中的非exe文件应该有@KeyPath='no'。它只是说服务的 EXE 文件应该驻留在一个单独的组件中,并且必须是它的关键路径。

    关键路径是微星技术中一个非常重要的概念。你可以阅读更多关于它的信息here, see the description of the KeyPath column

    现在,如果我们回到您最初的问题 - 不,您不必按照您提到的方式调整热量输出。默认情况下,它将生成您需要的 WiX 创作。

    【讨论】:

    • 感谢 Yan 提供的信息,我从这里得出了我的假设:blog.tentaclesoftware.com/archive/2009/01/01/21.aspx
    • 在示例中,您引用的单个组件包含许多文件。确实只有一个文件可以标记为 KeyPath='yes',但您不必将其他文件显式标记为 KeyPath='no'。在为您生成的示例 heat.exe 中,您的假设是完全错误的。
    • @Mark Jones,对不起,如果我之前的评论似乎以一种强硬的形式表达。当我看到人们花时间和精力试图解决一个不存在的问题时,我简直无法抗拒:)
    【解决方案3】:

    我可以建议一种不同的方法吗?

    <xsl:template match="@KeyPath[parent::wix:File[parent::wix:Component[parent::wix:DirectoryRef[parent::wix:Fragment[parent::wix:Wix]]]] and . != 'EmailGenerationService.exe']">
            <xsl:attribute name="KeyPath">
                <xsl:value-of select="'no'"/>
            </xsl:attribute>
    </xsl:template>
    

    只需将您的模板匹配更改为上述,您应该会得到正确的结果。

    【讨论】:

    • 这种转换效果很好,但请注意,因为您不能使用 Keypath=No 生成的 Guid (Guid="*")(Heat 使用 KeyPath 来生成 Guid)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多