5

I am trying to provide a simple installer package (MSI) which I want to support with updates (patches) that supersede all previous patches. So I have a MSI V1.0.0 and 2 patches V1.0.1 and V1.0.2. The user should be able to just install the latest patch regardless which previous patches were already applied to the system. My project contains 2 features (Client and Server). The basis of the patch so is always the RTM package (HelloWorld 1.0.msi / HelloWorld 1.0.wixpdb).

The generation (build) of all patches work, so the update procedures 1.0.0 -> 1.0.1 and 1.0.0 -> 1.0.2 do, BUT when i try to update from 1.0.1 to 1.0.2 the patch fails with the following error message: "The upgrade patch cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade patch may update a different version of the program. Verify that the program to be upgraded exists on your computer and that you have the correct upgrade patch.". Even worse, when I run the 1.0.1 patch on a system where 1.0.2 is already installed, the patch overwrites the existing installation with an older version!? I am totally confused...

I also found several blog entries on the web about patching, but nothing that works with my supersede szenario.

wix patching code - "patch1.wxs":

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Patch
      AllowRemoval="yes"
      Manufacturer="My Company"
      MoreInfoURL="http://www.mycompany.com/"
      DisplayName="HelloWorld V1.0 Patch 1"
      Description="Patch intaller updating HelloWorld V1.0.x to V1.0.1"
      Classification="Update">

    <Media Id="32000" Cabinet="HelloWorldRTM.cab">
      <PatchBaseline Id="HelloWorldRTM">
        <Validate ProductId="yes" UpgradeCode="yes" ProductVersionOperator="LesserOrEqual" />
      </PatchBaseline>
    </Media>

    <PatchFamilyRef Id="HelloWorldPatchFamily"/>
  </Patch>

  <Fragment>    
    <PatchFamily Id='HelloWorldPatchFamily' Version='1.0.1.0' Supersede='yes'>
      <PropertyRef Id="ProductVersion"/>
      <ComponentRef Id="HelloWorldServer.dll"/>
    </PatchFamily>
  </Fragment>
</Wix>

patch 1 build script - "generate_patch1.bat":

"%WIX%\bin\torch.exe" -p -xi ".\_Distrb\HelloWorld 1.0.wixpdb" ".\_Distrb\HelloWorld 1.0.1.wixpdb" -out ".\_Build\patch1.wixmst"
"%WIX%\bin\candle.exe" -out ".\_Build\patch1.wixobj" ".\patch1.wxs"
"%WIX%\bin\light.exe" ".\_Build\patch1.wixobj" -out ".\_Build\patch1.wixmsp"
"%WIX%\bin\pyro.exe" ".\_Build\patch1.wixmsp" -out ".\_Distrb\HelloWorld 1.0 Patch1.msp" -t HelloWorldRTM ".\_Build\patch1.wixmst"

wix patching code - "patch2.wxs":

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Patch
      AllowRemoval="yes"
      Manufacturer="My Company"
      MoreInfoURL="http://www.mycompany.com/"
      DisplayName="HelloWorld V1.0 Patch 2"
      Description="Patch intaller updating HelloWorld V1.0.x to V1.0.2"
      Classification="Update">

    <Media Id="32000" Cabinet="HelloWorldRTM.cab">
      <PatchBaseline Id="HelloWorldRTM">
        <Validate ProductId="yes" UpgradeCode="yes" ProductVersionOperator="LesserOrEqual" />
      </PatchBaseline>
    </Media>

    <PatchFamilyRef Id="HelloWorldPatchFamily"/>
  </Patch>

  <Fragment>
    <PatchFamily Id='HelloWorldPatchFamily' Version='1.0.2.0' Supersede='yes'>    
      <PropertyRef Id="ProductVersion"/>
      <ComponentRef Id="HelloWorldServer.dll"/>
      <ComponentRef Id="HelloWorld.exe"/>
    </PatchFamily>
  </Fragment>
</Wix>

patch 2 build script - "generate_patch2.bat":

"%WIX%\bin\torch.exe" -p -xi ".\_Distrb\HelloWorld 1.0.wixpdb" ".\_Distrb\HelloWorld 1.0.2.wixpdb" -out ".\_Build\patch2.wixmst"
"%WIX%\bin\candle.exe" -out ".\_Build\patch2.wixobj" ".\patch2.wxs"
"%WIX%\bin\light.exe" ".\_Build\patch2.wixobj" -out ".\_Build\patch2.wixmsp"
"%WIX%\bin\pyro.exe" ".\_Build\patch2.wixmsp" -out ".\_Distrb\HelloWorld 1.0 Patch 2.msp" -t HelloWorldRTM ".\_Build\patch2.wixmst"
4

1 回答 1

1

我有一个类似的问题,并通过在补丁 wxs.xml 中添加适当的验证来解决它。尝试这个...

<Media Id="32000" Cabinet="HelloWorldRTM.cab">
  <PatchBaseline Id="HelloWorldRTM">
    <Validate ProductId="yes" UpgradeCode="yes" ProductVersion="Major" ProductVersionOperator="GreaterOrEqual" />
  </PatchBaseline>
</Media>

如果您不希望补丁在安装的修订号大于补丁的修订号时工作,您可能需要将 ProductVersion 更改为“Update”并将 ProductVersion 设置为“GreaterOrEqual”。

我希望这个对你有用!

于 2012-03-20T18:18:43.340 回答