You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WiX工具集自动收割文件中配置CompanionFile属性?

解决WiX自动收割场景下System.IO.Compression.Native.dll的版本降级问题

问题背景

在.NET 6到.NET 7的MSI升级流程中,System.IO.Compression.Native.dll会出现丢失问题,核心原因是版本冲突导致安装程序未正确处理该文件的升级逻辑。官方解决方案是通过WiX的CompanionFile特性,将System.IO.Compression.dll设为Native DLL的伴生文件,让安装程序将两者视为同一组件进行版本管理。但如果使用WiX的自动收割(Heat)功能,无法直接编辑自动生成的XML元素添加该属性。

针对自动收割场景的解决方案

1. 通过XSLT转换修改收割输出(推荐)

WiX的Heat工具支持通过XSLT规则修改自动生成的WXS文件,你可以编写转换逻辑为指定文件添加CompanionFile属性。

步骤1:编写XSLT转换文件

创建AddCompanionFile.xslt,内容如下:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
  <xsl:output method="xml" indent="yes" />
  
  <!-- 保留所有原有元素和属性 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  
  <!-- 为System.IO.Compression.Native.dll添加CompanionFile属性 -->
  <xsl:template match="wix:File[contains(@Source, 'System.IO.Compression.Native.dll')]">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:attribute name="CompanionFile">System_IO_Compression_dll</xsl:attribute>
    </xsl:copy>
  </xsl:template>
  
  <!-- 将System.IO.Compression.dll设为组件的KeyPath -->
  <xsl:template match="wix:File[contains(@Source, 'System.IO.Compression.dll')]">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:attribute name="KeyPath">yes</xsl:attribute>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

步骤2:在.wixproj中配置收割时应用转换

在项目文件的HarvestDirectory任务中添加Transform属性,指定XSLT文件路径:

<HarvestDirectory Include="$(PublishDir)">
  <ComponentGroupName>AppComponents</ComponentGroupName>
  <DirectoryRefId>INSTALLFOLDER</DirectoryRefId>
  <Transform>AddCompanionFile.xslt</Transform>
  <SuppressCom>true</SuppressCom>
  <SuppressRegistry>true</SuppressRegistry>
  <SuppressRootDirectory>true</SuppressRootDirectory>
</HarvestDirectory>

如果直接使用Heat命令行,添加-transform AddCompanionFile.xslt参数即可。

2. 自定义MSBuild目标修改收割后的WXS文件

如果XSLT无法满足需求,可以在MSBuild流程中添加自定义目标,在收割完成后直接修改生成的WXS文件:

<Target Name="PostHarvest" AfterTargets="HarvestDirectory">
  <XmlPoke 
    XmlInputPath="$(IntermediateOutputPath)\AppComponents.wxs"
    Query="//wix:File[contains(@Source, 'System.IO.Compression.Native.dll')]/@CompanionFile"
    Value="System_IO_Compression_dll"
    Namespaces="&lt;Namespace Prefix='wix' Uri='http://schemas.microsoft.com/wix/2006/wi' /&gt;" />
  <XmlPoke 
    XmlInputPath="$(IntermediateOutputPath)\AppComponents.wxs"
    Query="//wix:File[contains(@Source, 'System.IO.Compression.dll')]/@KeyPath"
    Value="yes"
    Namespaces="&lt;Namespace Prefix='wix' Uri='http://schemas.microsoft.com/wix/2006/wi' /&gt;" />
</Target>

该目标会在收割完成后,自动为指定文件添加所需属性。

最终效果

通过上述方法,收割生成的组件会自动调整为如下结构:

<Component Id="Comp_Compression" Guid="*">
  <File Id="System_IO_Compression_dll" Source="path/to/System.IO.Compression.dll" KeyPath="yes" />
  <File Id="System_IO_Compression_Native_dll" Source="path/to/System.IO.Compression.Native.dll" CompanionFile="System_IO_Compression_dll" />
</Component>

内容的提问来源于stack exchange,提问作者Kristoffer Tungland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:09:50