5
votes

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"
1
There are two ways of patch creation: "Using Patch Creation Properties" or "Using Purely WiX". After having problems with "Using Purely WiX" - the way you use, I now use "Using Patch Creation Properties" without problems. Link: wix.sourceforge.net/manual-wix3/patching.htmMorten Frederiksen
How have you solved this?Balázs Szántó
@boli: unfortunately not. we dismissed it and now unsinstall reinstall the whole thing which works also even though not that elegant. :(+moik
@moik I solved this, but I'm considering it as a hack rather than a nice solution (had to store the installers, had to use administrative install, ...)Balázs Szántó

1 Answers

1
votes

I had a similar problem, and got it fixed by adding the appropriate validation to the patch wxs. Try this...

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

If you don't want the patch to work when the installed revision number is greater than the patch's revision number, you might want to change the ProductVersion to "Update" and set the ProductVersion to "GreaterOrEqual".

I hope it works for you!