first of all, I’m using WiX version 3.5.2519.0, but I’ve also tested this on the newest 3.6-release with the same results.
I’m having some trouble finding out how excactly PatchFamily can filter out only certain parts of a torch-generated diff. Following the example in the manual (“Building a patch using purely WiX” http://wix.sourceforge.net/manual-wix3/wix_patching.htm), I’ve been able to successfully generate a basic installer + patch that works as advertised. However, when I try to expand on that example I run into some issues.
Short version:
I add a new component, B, to the same folder as the original component A in Product.wxs, then build version 1.0 and version 1.1 of the installer. The files of both component A and B are changed between version 1.0 and 1.1.
Using torch, I generate the transform between installer 1.0 and 1.1.
Using pyro, I create the msp patch. Note that I did not change Patch.wxs, so the PatchFamily element still only contains a ComponentRef to component A, and not component B.
Now, based on this, I assumed what would happen when I applied the patch was that the file of component A would be updated, but that the file of component B would stay the same. In other words, that pyro would take the total transform from torch, which contains the transform of both component A and B, but then filter away all the transform actions that cannot be found in a PatchFamily element, so that all that is left in the final patch is the transform of component A.
Apparently I was wrong, so all I really want to know is how, if possible, I can actually filter out unwanted transforms from a diff when creating a patch?
Detailed version, if you want the contents of the files and the commands used:
Product.wxs:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="48C49ACE-90CF-4161-9C6E-9162115A54DD"
Name="WiX Patch Example Product"
Language="1033"
Version="1.0.0"
Manufacturer="Dynamo Corporation"
UpgradeCode="48C49ACE-90CF-4161-9C6E-9162115A54DD">
<Package Description="Installs a file that will be patched."
Comments="This Product does not install any executables"
InstallerVersion="200"
Compressed="yes" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<FeatureRef Id="SampleProductFeature"/>
</Product>
<Fragment>
<Feature Id="SampleProductFeature" Title="Sample Product Feature" Level="1">
<ComponentRef Id="SampleComponent" />
<ComponentRef Id="SampleComponent2" />
</Feature>
</Fragment>
<Fragment>
<DirectoryRef Id="SampleProductFolder">
<Component Id="SampleComponent" Guid="{C28843DA-EF08-41CC-BA75-D2B99D8A1983}" DiskId="1">
<File Id="SampleFile" Name="Sample.txt" Source=".\$(var.Version)\Sample.txt" />
</Component>
<Component Id="SampleComponent2" Guid="{C28843DA-EF08-41CC-BA75-D2B99D8A1984}" DiskId="1">
<File Id="SampleFile2" Name="Sample2.txt" Source=".\$(var.Version)\Sample2.txt" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="SampleProductFolder" Name="Patch Sample Directory">
</Directory>
</Directory>
</Directory>
</Fragment>
</Wix>
Patch.wxs:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Patch
AllowRemoval="yes"
Manufacturer="Dynamo Corp"
MoreInfoURL="http://www.dynamocorp.com/"
DisplayName="Sample Patch"
Description="Small Update Patch"
Classification="Update"
>
<Media Id="5000" Cabinet="RTM.cab">
<PatchBaseline Id="RTM"/>
</Media>
<PatchFamilyRef Id="SamplePatchFamily"/>
</Patch>
<Fragment>
<PatchFamily Id='SamplePatchFamily' Version='1.0.0.0' Supersede='yes'>
<ComponentRef Id="SampleComponent"/>
</PatchFamily>
</Fragment>
</Wix>
Two subfolders, 1.0 and 1.1, both containing Sample.txt and Sample2.txt with varying (differing) contents.
Commands:
candle.exe -dVersion=1.0 product.wxs
light.exe product.wixobj -out 1.0\product.msi
candle.exe -dVersion=1.1 product.wxs
light.exe product.wixobj -out 1.1\product.msi
torch.exe -p -xi 1.0\product.wixpdb 1.1\product.wixpdb -out patch\diff.wixmst
candle.exe patch.wxs
light.exe patch.wixobj -out patch\patch.wixmsp
pyro.exe patch\patch.wixmsp -out patch\patch.msp -t RTM patch\diff.wixmst
Edit:
As Bob Arnson was nice enough to point out, the Fragment element “becomes an immutable, atomic unit which can either be completely included or excluded from a product”, so in order to update files individually they have to be defined in different fragments. This certainly was good to know, as I’ve so far treated fragments as just a way to separate element-references and element-definitions. In case anyone should be remotely interested, the following would be a working version of Product.wxs:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="48C49ACE-90CF-4161-9C6E-9162115A54DD"
Name="WiX Patch Example Product"
Language="1033"
Version="1.0.0"
Manufacturer="Dynamo Corporation"
UpgradeCode="48C49ACE-90CF-4161-9C6E-9162115A54DD">
<Package Description="Installs a file that will be patched."
Comments="This Product does not install any executables"
InstallerVersion="200"
Compressed="yes" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<FeatureRef Id="SampleProductFeature"/>
</Product>
<Fragment>
<Feature Id="SampleProductFeature" Title="Sample Product Feature" Level="1">
<ComponentRef Id="SampleComponent" />
<ComponentRef Id="SampleComponent2" />
</Feature>
</Fragment>
<Fragment>
<DirectoryRef Id="SampleProductFolder">
<Component Id="SampleComponent" Guid="{C28843DA-EF08-41CC-BA75-D2B99D8A1983}" DiskId="1">
<File Id="SampleFile" Name="Sample.txt" Source=".\$(var.Version)\Sample.txt" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="SampleProductFolder">
<Component Id="SampleComponent2" Guid="{C28843DA-EF08-41CC-BA75-D2B99D8A1984}" DiskId="1">
<File Id="SampleFile2" Name="Sample2.txt" Source=".\$(var.Version)\Sample2.txt" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="SampleProductFolder" Name="Patch Sample Directory">
</Directory>
</Directory>
</Directory>
</Fragment>
</Wix>
Both components are in the same fragment, so they’re both included in the patch. If you don’t want that, put them in different fragments.