About Windows Installer, the .NET Framework, and Visual Studio.
File versions in Windows Installer and properties like REINSTALL and REINSTALLMODE determine what files are copied to their destination. But before files versions are even a factor, any patches being installed or already installed are sequenced first.
A Windows Installer patch file, a .msp file, contains a set of transforms for one or more target products. When applying a patch, Windows Installer enumerates all the transforms in the patch package until it finds the first authoring transform that applies based on its validation bits and target values. If that transform changes the ProductVersion property, it is sequenced into "buckets" with the original Windows Installer installation package (RTM), a .msi file, and other minor upgrade patches that change the ProductVersion in order from lowest ProductVersion to highest. Keep in mind that if a newer minor upgrade patch targets the RTM and an older patch already updated the ProductVersion, the newer minor upgrade patch must target the RTM and newer ProductVersion values, or define MinorUpdateTargetRTM as 1 in the MsiPatchMetadata table of the .msp file itself.
After minor upgrade patches are sequences, small update patches are sequenced within each of the latest buckets to which they apply. After patches are sequenced based on any patch families in common and the sequence number defined in the MsiPatchSequence table, patches are superseded if all patch families for any given patch are superseded by another, higher-sequenced patch with the supersedence bit set for all patch families. At this point, the installation sequence defined in the InstallUISequence or InstallExecuteSequence tables hasn't even started yet.
This final patch application order determines in what order transforms are applied. This creates an aggregate view that then gets reinstalled. Based on the determined or specified features to be reinstalled, changes required by the components being added or modified are costed to determine how much space is required to install them and cache existing baseline files.
When the InstallFiles standard action eventually runs, it schedules components' files to be copied. During InstallFinalize when the file copy operations and other deferred operations are finally executed, Windows Installer uses the file versioning rules to determine if the files are actually copied.
MSI (s) (AC:C4) [18:20:20:093]: Executing op: FileCopy(SourceName=foo.exe,SourceCabKey=F_foo.exe,DestName=foo.exe,Attributes=5120,FileSize=3614056,PerTick=32768,,VerifyMedia=1,,,,,CheckCRC=0,Version=188.8.131.52,Language=1033,InstallMode=25427968,,,,,,,)MSI (s) (AC:C4) [18:20:20:097]: File: C:\Program Files\Example\foo.exe; Overwrite; Won't patch; Existing file is a lower version
Here "Overwrite" refers to the operation on the whole file, while "patch" actually refers to whether or not the baseline file will be patched by a binary delta patch - a binary difference between the target and update file.
If patches are sequenced incorrectly, the file version you expect might not be installed. That is because either the patch was superseded, or was effectively superseded because in the aggregate view the file version and sequence are for the older version because the older transform was applied last. This could happen, for example, if a couple of patches shared no patch families in common. In this case, patch sequences are not guaranteed. At least one patch family must be common between two or more patches for them to sequenced relative to each other, and all patch families must be common between two or more patches for a higher-sequenced patch to supersede a lower-sequence patch or patches.