1

我正在使用heat.exe此脚本在构建后事件中收集我的 Visual Studio 项目的调试(或发布)目录:

call "C:\Program Files (x86)\WiX Toolset v3.8\bin\heat.exe" dir "$(TargetDir)." -var var.WixDemo.TargetDir -dr INSTALLFOLDER -cg Binaries -ag -scom -sreg -sfrag -srd -o "$(SolutionDir)WixSetup\$(ProjectName).Binaries.wxs"

我会得到一个具有两个功能的安装程序:

  1. 项目A

  2. 项目B

问题是这两个项目引用了相同的 dll ( xyz.dll),因此,两个收获进程都为此文件创建了一个具有相同 ID 的组件。


编辑

这是我收获发布目录后的输出文件。

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
            <Directory Id="dir325E6775ACBC3561D5CA2F51CFCCC7E8" Name="WixDemoFeature1">
                <Component Id="cmp22AE0957A805CEDAC8D05EF04AE18D5E" Guid="*">
                    <File Id="fil9EDCA091AB8E6440E9D83A815255C794" KeyPath="yes" Source="$(var.WixDemoFeature1.TargetDir)\xyz.dll" />
                </Component>
                <Component Id="cmpFCBDB8083076AA83E1B67540ADFECC9D" Guid="*">
                    <File Id="filAA36C3D42B58D430C889BE47087CA911" KeyPath="yes" Source="$(var.WixDemoFeature1.TargetDir)\WixDemoFeature1.exe" />
                </Component>
                <Component Id="cmp8BCDCA87324BD346D955DDB4318E80BD" Guid="*">
                    <File Id="fil69700DBD0795710A0AE5DC17574128D5" KeyPath="yes" Source="$(var.WixDemoFeature1.TargetDir)\WixDemoFeature1.exe.config" />
                </Component>
            </Directory>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="WixDemoFeature1Binaries">
            <ComponentRef Id="cmp22AE0957A805CEDAC8D05EF04AE18D5E" />
            <ComponentRef Id="cmpE0CAA29B7BB706D56252E85F7C1DDD0A" />
            <ComponentRef Id="cmp8BCDCA87324BD346D955DDB4318E80BD" />
        </ComponentGroup>
    </Fragment>
</Wix>

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
            <Directory Id="dir325E6775ACBC3561D5CA2F51CFCCC7E8" Name="WixDemoFeature2">
                <Component Id="cmp22AE0957A805CEDAC8D05EF04AE18D5E" Guid="*">
                    <File Id="fil9EDCA091AB8E6440E9D83A815255C794" KeyPath="yes" Source="$(var.WixDemoFeature2.TargetDir)\xyz.dll" />
                </Component>
                <Component Id="cmpE0CAA29B7BB706D56252E85F7C1DDD0A" Guid="*">
                    <File Id="fil3A3B754D2B216E86025902C3A826545D" KeyPath="yes" Source="$(var.WixDemoFeature2.TargetDir)\WixDemoFeature2.exe" />
                </Component>
                <Component Id="cmpFB159630D6E1604557E20776A46EB6B3" Guid="*">
                    <File Id="fil060CF132A168E46D3C4C1C24CA1AEFF4" KeyPath="yes" Source="$(var.WixDemoFeature2.TargetDir)\WixDemoFeature2.exe.config" />
                </Component>
            </Directory>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="WixDemoFeature2Binaries">
            <ComponentRef Id="cmp22AE0957A805CEDAC8D05EF04AE18D5E" />
            <ComponentRef Id="cmpFCBDB8083076AA83E1B67540ADFECC9D" />
            <ComponentRef Id="cmpFB159630D6E1604557E20776A46EB6B3" />
        </ComponentGroup>
    </Fragment>
</Wix>

这两个 xml 对于组件“xyz.dll”具有相同的 ID,因此我不能在我的 Product.wxs 中同时使用“WixDemoFeature1Binaries”和“WixDemoFeature2Binaries”。

我想得到这些:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
            <Directory Id="dir325E6775ACBC3561D5CA2F51CFCCC7E8" Name="WixDemoFeature1">
                <Component Id="cmp_WixDemoFeature1.xyz.dll" Guid="*">
                    <File Id="fil_WixDemoFeature1.xyz.dll" KeyPath="yes" Source="$(var.WixDemoFeature1.TargetDir)\xyz.dll" />
                </Component>
                <Component Id="cmp_WixDemoFeature1.WixDemoFeature1.exe" Guid="*">
                    <File Id="fil_WixDemoFeature1.WixDemoFeature1.exe" KeyPath="yes" Source="$(var.WixDemoFeature1.TargetDir)\WixDemoFeature1.exe" />
                </Component>
                <Component Id="cmp_WixDemoFeature1.WixDemoFeature1.exe.config" Guid="*">
                    <File Id="fil_WixDemoFeature1.WixDemoFeature1.exe.config" KeyPath="yes" Source="$(var.WixDemoFeature1.TargetDir)\WixDemoFeature1.exe.config" />
                </Component>
            </Directory>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="WixDemoFeature1Binaries">
            <ComponentRef Id="cmp_WixDemoFeature1.xyz.dll" />
            <ComponentRef Id="cmp_WixDemoFeature1.WixDemoFeature1.exe" />
            <ComponentRef Id="cmp_WixDemoFeature1.WixDemoFeature1.exe.config" />
        </ComponentGroup>
    </Fragment>
</Wix>

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
            <Directory Id="dir325E6775ACBC3561D5CA2F51CFCCC7E8" Name="WixDemoFeature2">
                <Component Id="cmp_WixDemoFeature2.xyz.dll" Guid="*">
                    <File Id="fil_WixDemoFeature2.xyz.dll" KeyPath="yes" Source="$(var.WixDemoFeature2.TargetDir)\xyz.dll" />
                </Component>
                <Component Id="cmp_WixDemoFeature2.WixDemoFeature2.exe" Guid="*">
                    <File Id="fil_WixDemoFeature2.WixDemoFeature2.exe" KeyPath="yes" Source="$(var.WixDemoFeature2.TargetDir)\WixDemoFeature2.exe" />
                </Component>
                <Component Id="cmp_WixDemoFeature2.WixDemoFeature2.exe.config" Guid="*">
                    <File Id="fil_WixDemoFeature2.WixDemoFeature2.exe.config" KeyPath="yes" Source="$(var.WixDemoFeature2.TargetDir)\WixDemoFeature2.exe.config" />
                </Component>
            </Directory>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="WixDemoFeature2Binaries">
            <ComponentRef Id="cmp_WixDemoFeature2.xyz.dll" />
            <ComponentRef Id="cmp_WixDemoFeature2.WixDemoFeature2.exe" />
            <ComponentRef Id="cmp_WixDemoFeature2.WixDemoFeature2.exe.config" />
        </ComponentGroup>
    </Fragment>
</Wix>

我怎样才能改变这种行为?

4

1 回答 1

0

目标目录设计用于在开发人员机器上进行调试,而不是用于收集要打包的文件。

尽管如此,您有几个选择,包括:

  • Heat 在发出 .wxs 文件之前接受要应用的 XSL 转换。使用 XSL,您可以过滤掉不需要的 Component 和 ComponentRef 元素。
  • 在 WiXSetup 中使用项目 A 和项目 B的项目参考并收集 它们的输出。然后,您必须单独获取 xyz.dll 或为它手写一个组件。手动创建两个特征并在两者中引用 xyz 组件。(我假设 WiXSetup 是从 WiX 设置项目模板创建的 Visual Studio 项目。)
  • 使用 MSBuild 的Copy 任务来创建您的包布局并收获它。复制任务可以创建硬链接而不是实际复制。(几乎所有类型的 Visual Studio 项目都是 MSBuild 项目。)

更新问题的简单 XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
  xmlns="http://schemas.microsoft.com/wix/2006/wi"
  exclude-result-prefixes="wix">
  <xsl:output method="xml" indent="yes"/>

  <!-- Preserving the order of attributes only for aesthetic reasons -->

  <xsl:template match="//wix:Component">
    <xsl:variable name="source" select="wix:File/@Source" />
    <xsl:variable
      name="baseId"
      select="concat(substring-before(substring-after($source, '$(var.'),'.TargetDir)'), 
              concat('.', substring-after($source,'\')))" />
    <Component>
      <xsl:attribute name="Id">
        <xsl:value-of select="concat('cmp_', $baseId)"/>
      </xsl:attribute>
      <xsl:attribute name="Guid">*</xsl:attribute>
      <File>
        <xsl:attribute name="Id">
          <xsl:value-of select="concat('fil_', $baseId)"/>
        </xsl:attribute>
        <xsl:attribute name="KeyPath">yes</xsl:attribute>
        <xsl:attribute name="Source">
          <xsl:value-of select="wix:File/@Source"/>
        </xsl:attribute>
      </File>
    </Component>
  </xsl:template>

  <xsl:template match="//wix:ComponentRef">
    <!-- ComponentRef nodes are interleaved with text() nodes. Want positions 2, 4, 6, ... -->
    <xsl:variable name="index" select="(position() - 1) div 2" /> 
    <xsl:variable name="source" select="//wix:Component[$index]/wix:File/@Source" />
    <xsl:variable
      name="baseId"
      select="concat(substring-before(substring-after($source, '$(var.'),'.TargetDir)'), 
              concat('.', substring-after($source,'\')))" />
    <ComponentRef>
      <xsl:attribute name="Id">
        <xsl:value-of select="concat('cmp_', $baseId)"/>
      </xsl:attribute>
    </ComponentRef>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
于 2014-02-22T04:43:21.397 回答