WIX:动态生成补丁

WIX: Dynamically generate patch

我们有许多基于 WIX(当前为 3.9)的安装,例如,我们使用 harvest 来收集不同的组件,它的流程非常好。一切都是自动化的,我们在需要最新安装时进行夜间构建。

像许多其他公司一样,我们需要对一个或多个安装中的许多文件之一进行修补,但要确保我们在不同的安装中找到正确的文件和正确的组件真的很痛苦.

对于这种情况,是否有任何最佳实践,因为我无法相信我们是单独使用这种设置的? AND 我们不想仅仅为了修复一些错误而进行升级。

这里有一个场景需要解决:

2.0 版终于发布了,我们有一个完整的系统安装以及几个不同的客户端安装和一个可选包。

当然,我们在软件中发现了一些小故障,首先,比如说 3 周,我们在系统的不同部分修复了大约 15 个或多或少的关键错误。

现在我们觉得我们需要修补那里的安装,并且相信我们需要为每个安装 (MSI) 做一个补丁项目,然后我们构建它并收集差异并创建补丁以便能够快速发送给那些已经安装了不同部分的人。

下面是我做过的 patch.wxs 的一个片段,但找不到自动化的方法:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <?include "InitDefinitions.wxi"?>
  <Patch  AllowRemoval="no" Manufacturer="$(var.Company)" 
          DisplayName="$(var.InstallerProductName), patch $(var.Build)" 
          Description="Small Update Patch" Classification="Update">
    <Media Id="5000" Cabinet="patch.cab" EmbedCab="yes">
      <PatchBaseline Id="RTM"/>
    </Media>

    <PatchFamilyRef Id="SP-$(var.Build)-Patch"/>
  </Patch>

  <Fragment>
    <PatchFamily Id="SP-$(var.Build)-Patch" 
                 Version="$(var.Major).$(var.Minor).$(var.Build).$(var.Revision)" 
                 Supersede="yes">
      <PropertyRef Id="ProductVersion" />
      <!--  
            As I understand it's here I define the changes, 
            but I like this section to be automatic populated during build, 
            or something
      -->
    </PatchFamily>
  </Fragment>
</Wix>

有办法解决吗?

提前致谢!

我在标题为 Automated Patch Building with WiX and Visual Studio 的 post 博客中对此进行了介绍。

基本步骤如下:

  1. 创建初始补丁文件。您已经使用 patch.wxs 完成了此操作。
  2. 对您发布的 msis 执行管理员安装并更新。您可以从服务器位置复制发布的 .msi。我假设您正在使用某种类型的自动构建来构建更新 .msi。
  3. 使用Torch.exe生成msis之间的差异。
  4. 构建补丁。 使用 Candle.exe 编译它,link 使用 Light.exe 编译它,并使用 [=40 创建最终补丁=].

可以找到有关如何手动 运行 这些步骤的简单示例 here at FireGiant

将焦点从 <Patch> 切换到 <PatchCreation>,基于此页面我得到:http://wixtoolset.org/documentation/manual/v3/patching/patch_building.html

不确定为什么有两种方法可以在 WIX 框架中制作补丁,但无论如何我现在都会使用 PatchCreation!

基本上,我已经将 Patch.wxs 中的内容改为:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <?include "InitDefinitions.wxi"?>
  <PatchCreation
      Id="{BAF94FD0-924C-4ED6-8BBF-2F6ACF8B3B3D}"
      CleanWorkingFolder="yes"
      OutputPath="patch.pcp"
      WholeFilesOnly="yes"
        >

    <PatchInformation
        Description="Small Update Patch"
        Comments="Small Update Patch"
        ShortNames="no"
        Languages="1033"
        Compressed="yes"
        Manufacturer="$(var.Company)"/>

    <PatchMetadata
        AllowRemoval="no"
        Description="Small Update Patch"
        ManufacturerName="$(var.Company)"
        MoreInfoURL="http://www.company.com"
        TargetProductName="Sample"
        Classification="Update"
        DisplayName="Sample Patch"/>

    <Family DiskId="5000"
        MediaSrcProp="Sample"
        Name="Sample"
        SequenceStart="5000">
      <UpgradeImage SourceFile="C:\Temp\PatchWork\NewMSI\Install\Product.msi" 
                    Id="SampleUpgrade">
        <TargetImage SourceFile="C:\Temp\PatchWork\ReleasedMSI\Install\Product.msi" 
                      Order="2" Id="SampleTarget" IgnoreMissingFiles="no" />
      </UpgradeImage>
    </Family>

    <PatchSequence PatchFamily="SamplePatchFamily"
        Sequence="2.0.0.1"
        Supersede="yes" />

  </PatchCreation>
</Wix>

并且还将我的 VS 项目中的 PostBuild 事件更改为:

FOR /D /R "C:\Temp\PatchWork\ReleasedMSI\Install" %%X IN (*.*) DO RD /S /Q "%%X"
FOR /D /R "C:\Temp\PatchWork\NewMSI\Install" %%X IN (*.*) DO RD /S /Q "%%X"
msiexec.exe /a "C:\Temp\PatchWork\ReleasedMSI\Product.msi" /qb TARGETDIR="C:\Temp\PatchWork\ReleasedMSI\Install"
msiexec.exe /a "$(SolutionDir)Installations\Product.Setup\bin\Release\Product.msi" /qb TARGETDIR="C:\Temp\PatchWork\NewMSI\Install"
candle.exe "$(SolutionDir)Installations\Product.Patch\Patch.wxs"
light.exe  "$(TargetDir)Patch.wixobj" -out "$(TargetDir)Patch.pcp"
msimsp.exe -s "$(TargetDir)Patch.pcp" -p "$(TargetDir)Patch.msp" -l "$(TargetDir)Patch.log"

我得到了一个内容不错的补丁文件,乍一看似乎是正确的。当然需要更多关于名称、描述等的工作和决定。但现在似乎已经有了基线! :)

... 下一步是将其挂接到我们用于某些 msi 安装程序的 bundle/bootstrapper 中。感觉并非不可能,但它可能会给我和其他人带来一些新的头痛问题……;)