I'm using WiX toolset to create my msi file from a C++ codebase with cmake and cpack. This setup works great for the past 6 months, but now i'm getting sporadic bad behaviour.
My Setup uninstall older products with the same upgrade-code to guarantee that there is only one version of my product installed (always major upgrade). I rolled out the newest version to my users (via SCCM) two days ago and in 10% of all installations I have the following problem.
The uninstall of the old installation seems to be sometimes wrong. The uninstall process remove the files, but left the root directory and the bin directory but all files are removed. When I query for the installation of the old product via WMI it say that it is installed, which is strange. The other 90% of the instllations everything works great. I also can not reproduce that locally.
I have a log file, but i'm not sure if it is from an misbehaving installation or not.
The logfile is very long, so I post only snippets which makes me sceptical.
MSI (s) (0C:9C) [15:21:35:083]: Component: CM_CP_runtime.bin.main2.exe;
Installed: Absent; Request: Null; Action: Null
...
MSI (s) (0C:78) [15:21:43:591]: Executing op: FileCopy(SourceName=-dbqfin2.dll|FreeImage.dll,SourceCabKey=CM_FP_runtime.bin.FreeImage.dll,DestName=FreeImage.dll,Attributes=512,FileSize=6201856,PerTick=65536,,VerifyMedia=1,,,,,CheckCRC=0,Version=3.17.0.0,Language=1033,InstallMode=58982400,,,,,,,)
MSI (s) (0C:78) [15:21:43:591]: File: C:\Program Files\LDS Studio\bin\FreeImage.dll; To be installed; Won't patch; No existing file
The Action: Null means that there is no operation (but it should be local), but I'm not sure why. When I start the installation a second time everything works fine (because there is no old version). I had that behaviour a year ago (but only for two single files) when we are porting from Visual Studio to cmake and forgot to add a version to our dll (previous dll had a version, new one had no version, so msi think that's not a new version and skip it in REINSTALLMODE default mode 'omus'). Since then we have changed nothing and everything works fine until 2 days ago.
Here is my wix_main.wxs file
<Product Id="$(var.CPACK_WIX_PRODUCT_GUID)"
Name="$(var.CPACK_PACKAGE_NAME)"
Language="1033"
Version="$(var.CPACK_PACKAGE_VERSION)"
Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)">
<Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine"/>
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="$(var.CPACK_WIX_UPGRADE_GUID)">
<UpgradeVersion
Minimum="1.0.0.0" Maximum="99.0.0.0"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" IncludeMaximum="no"
/>
</Upgrade>
<WixVariable Id="WixUILicenseRtf" Value="$(var.CPACK_WIX_LICENSE_RTF)"/>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALL_ROOT"/>
<?ifdef CPACK_WIX_PRODUCT_ICON?>
<Property Id="ARPPRODUCTICON">ProductIcon.ico</Property>
<Icon Id="ProductIcon.ico" SourceFile="$(var.CPACK_WIX_PRODUCT_ICON)"/>
<?endif?>
<?ifdef CPACK_WIX_UI_BANNER?>
<WixVariable Id="WixUIBannerBmp" Value="$(var.CPACK_WIX_UI_BANNER)"/>
<?endif?>
<?ifdef CPACK_WIX_UI_DIALOG?>
<WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/>
<?endif?>
<FeatureRef Id="ProductFeature"/>
<UIRef Id="$(var.CPACK_WIX_UI_REF)" />
<?include "properties.wxi"?>
<?include "product_fragment.wxi"?>
<CustomAction Id="RegisterExtensions"
FileKey="CM_FP_runtime.bin.main.exe"
ExeCommand="-regext"
Execute="deferred"
Return="check"
HideTarget="no"
Impersonate="no"
/>
<CustomAction Id="UnregisterExtensions"
FileKey="CM_FP_runtime.bin.main.exe"
ExeCommand="-unregext"
Execute="deferred"
Return="ignore"
HideTarget="no"
Impersonate="no"
/>
<InstallExecuteSequence>
<RemoveExistingProducts Before='InstallInitialize'>
NOT REMOVE
</RemoveExistingProducts>
<Custom Action="RegisterExtensions" After="InstallFiles">
NOT REMOVE
</Custom>
<Custom Action="UnregisterExtensions" After="InstallInitialize">
Installed AND (REMOVE = "ALL")
</Custom>
</InstallExecuteSequence>
</Product>
I've found some blogpost where people deal with the OnlyDetect mode in but I'm not sure if it can help me or not because I'm not able to reproduce it on my machines.
Switching to REINSTALLMODE amus (https://msdn.microsoft.com/en-us/library/windows/desktop/aa371182(v=vs.85).aspx) maybe is my last resort, but that would be my last resort.
I've found this blogpost https://jpassing.com/2007/06/16/where-to-place-removeexistingproducts-in-a-major-msi-upgrade/ => could it be that i have to change from
<RemoveExistingProducts Before='InstallInitialize'>
NOT REMOVE
</RemoveExistingProducts>
to
<RemoveExistingProducts After='InstallInitialize'>
NOT REMOVE
</RemoveExistingProducts>
???
Maybe somebody can help me with the problem
Greetings
Tonka
The most likely explanation for what you see is that RemoveExistingProducts (an uninstall of the older product) is failing. That will result in a rollback that restores that older product. The old product is then installed, and then the new product continues with its install. At some point in time the install of your new upgrade fails and rolls back, and this will potentially damage the older installed product. That's the general issue with doing an upgrade RemoveExistingProducts outside of the upgrade's transaction. If your REP was after InstallInitize it would fail and the upgrade would not proceed.
(As an aside, asimilar issue can happen if you sequence REP after InstallFinalize and outside the upgrade's transaction, because you install the upgrade product, the transaction finishes, the uninstall of the older product is attempted and fails, it rolls back and restores the older product so now you have both old and new products installed. )
You need to create a verbose MSI log of the upgrade to see why the REP is failing and leaving the older product installed, and why the new upgrade is failing (because otherwise it would show in Program&Features). Also it is safer to keep RemoveExistingProducts inside the upgrade's transaction.
Related
I have a strange issue whereby WiX Installer appears to be detecting a SELFFOUND instead of a PREVIOUSFOUND.
I am moving an old InstallAware project over to WiX so I have copied the UpgradeCode from the project to this Product.wxs
<Upgrade Id='MyGuid'>
<UpgradeVersion OnlyDetect='yes' Property='SELFFOUND' Minimum='!(bind.FileVersion.MainEXE)' IncludeMinimum='yes' Maximum='!(bind.FileVersion.MainEXE)' IncludeMaximum='yes' />
<UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND' Minimum='!(bind.FileVersion.MainEXE)' IncludeMinimum='no' />
<UpgradeVersion Minimum="1.0.0"
IncludeMinimum="yes"
OnlyDetect="no"
Maximum="!(bind.FileVersion.MainEXE)"
IncludeMaximum="no"
Property="PREVIOUSFOUND" />
</Upgrade>
<CustomAction Id='AlreadyUpdated' Error='[ProductName] is already installed.' />
<CustomAction Id='NoDowngrade' Error='A later version of [ProductName] is already installed.' />
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
<Custom Action='AlreadyUpdated' After='FindRelatedProducts'>SELFFOUND</Custom>
<Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERFOUND</Custom>
</InstallExecuteSequence>
and the Upgrade GUID matches that in my Product tag of the UpgradeCode attribute. The product codes between the two versions is different but I don't think making these the same is a good idea.
The version installed by the old InstallAware project is 4.11.7311.0 and is visible in control panel with this version. The version I am trying to install via the Upgrade and remove the old version is 4.11.7314.0.
For some reason whenever I try to run the new WiX .msi it is throwing the [ProductName] is already installed message.
Am I missing something? Because everything seems correct to me. Thanks in advance. Wix Toolset v3.11.
Okay, so I found the problem, well there were multiple actually.
Firstly I ran the installer via command prompt to generate a log file.
msiexec /i "C:\Path\To\Installer.msi" /L*V "C:\ProgramData\Install.log"
I then searched this file for
FindRelatedProducts
and it found an application which was setting the SELFFOUND property, now I searched through the registry for the GUID and realised it was an old one from my testing, so I uninstalled this using
msiexec /x {FoundGuid}
Still having the issue at this point though, so repeated the process and found a message that said
FindRelatedProducts: current install is per-machine. Related install for product '{MyGUID}' is per-user. Skipping...
so all I had to do was change my InstallScope from perMachine to perUser and it detects correctly.
WIX MSI perMachine installer writing installed property to HKCU instead of HKLM.
One of the symptoms is that the original logic I used to detect an attempt to install an older version of the product fails because I was depending on the Installed property to get defined on a system where an install had previously been executed. Just to be clear this logic has worked in the past but now I am doing regression testing and it failed.
I edited the msi with orca and modified the launch condition that tests for this. I changed the launch condition to "Installed" and the message to "Not installed" I then ran the installer on several systems where our application is installed. If Installed were true then the installer would run but in every case the installer displayed the message box meaning that it couldn't find the registry entry.
I looked in all these systems and the "installed" registry entry was located in HKCU/Software/company/product/installed=1 instead of in HKLM.
Also this is a 64 bit installer and when I run the installer it gets into the UI and I look at the task manager to make sure it is running the 64 bit version of msiexec which it is.
Here's the relevant WIX fragment which stopped working. See the 1st launch condition. I am adding the beginning of the Product ... section.
<Product Id="*"
Name="$(var.ProductDisplayName)"
Language="1033"
Version="$(var.OurVersion)"
Manufacturer="$(var.ProductAuthor)"
UpgradeCode="$(var.ProductUpgradeCode)">
<Product Id="*"
Name="$(var.ProductDisplayName)"
Language="1033"
Version="$(var.VayTekVersion)"
Manufacturer="$(var.ProductAuthor)"
UpgradeCode="$(var.ProductUpgradeCode)"
>
<Package
Description="$(var.ProductDisplayName)"
Comments="$(var.ProductDisplayComment)"
Manufacturer="$(var.ProductAuthor)"
InstallerVersion="301" Compressed="yes"
Platform="$(var.Platform)"
InstallScope="perMachine"
InstallPrivileges="elevated"/>
<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.OurVersion)"
IncludeMinimum="no"
OnlyDetect="yes"
Property="NEWERPRODUCTFOUND" />
<UpgradeVersion
Minimum="07.01.01001" IncludeMinimum="yes"
Maximum="$(var.OurVersion)" IncludeMaximum="no"
Property="PREVIOUSVERSIONSINSTALLED"/>
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize"/>
</InstallExecuteSequence>
<Condition
Message="A later version of the product is already installed. Setup will now exit.">
(NOT NEWERPRODUCTFOUND) OR (NOT Installed)
</Condition>
After I stared at the code a while I removed the "NOT Installed" logic and left
NOT NEWERPRODUCTFOUND
This isn't ideal but it works in most situations.
Anyone have an idea why the registry entry is getting placed in the wrong hive?
An MSI package is per-machine when the ALLUSERS property is set to "1". In the WiX toolset, you can set this using the Package element InstallScope attribute is set to "perMachine".
Also, upgrades will not detect packages in the other install scope. In other words, per-machine cannot upgrade per-user and vice versa.
PS: "NOT Installed" in a LaunchCondition is a very strange thing to see. That would just try to block repair/uninstall.
I have a product that used to ship with a .vdproj installer. In the most recent version, I shipped a beta with a completely redone installer using WiX (as part of the move to Visual Studio 2012, which no longer supports .vdproj). Unfortunately, at the time I didn't know that the upgrade code was supposed to be consistent across copies, and already shipped one beta installer with a different upgrade code.
I would like my installer to automatically remove previous versions built with the .vdproj installer, as well as the version that was shipped as a beta copy. This is where I've gotten so far:
<Product Id="{A4CBA9F9-D86B-400C-BD23-996B4367931A}" Name="Foo Viewer" Language="1033" Version="6.0.1.0" Manufacturer="Foo Corporation" UpgradeCode="43e024b8-b3ea-40a3-a854-2af83f207f0f">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MediaTemplate EmbedCab="yes" />
<Feature Id="FOOVIEWERFeature" Title="Foo Viewer" Level="1" Description="The Foo Viewer GUI and CLI binaries." AllowAdvertise="no" Absent="disallow" Display="expand">
<!-- Stuff -->
</Feature>
<PropertyRef Id="NETFRAMEWORK40CLIENT" />
<Condition Message="Foo Viewer requires the .NET Framework 4.0 Client Profile or higher to run.">Installed OR NETFRAMEWORK40CLIENT</Condition>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="FooViewerInstallerUI" />
<UIRef Id="WixUI_ErrorProgressText" />
<Icon Id="FooViewerIcon" SourceFile="../FooViewer.ico" />
<Property Id="ARPPRODUCTICON" Value="FooViewerIcon" />
<!-- I got this upgrade code by opening one of the old .vdproj MSIs in Orca -->
<Upgrade Id="{80539F30-8176-4DCC-A102-ED32A34A91CB}">
<UpgradeVersion OnlyDetect="no"
Minimum="0.0.0.0"
IncludeMinimum="yes"
MigrateFeatures="no"
IgnoreRemoveFailure="no"
Property="UPGRADE_VDPROJ_FOOVIEWER"
/>
</Upgrade>
<Upgrade Id="{43e024b8-b3ea-40a3-a854-2af83f207f0f}">
<!-- Foo Viewer 6.0.0.0 (Beta) shipped with a version 5.3.0.0 in the installer. -->
<UpgradeVersion OnlyDetect="no"
Minimum="5.3.0.0"
Maximum="5.3.0.0"
IncludeMinimum="yes"
IncludeMaximum="yes"
MigrateFeatures="yes"
IgnoreRemoveFailure="no"
Property="UPGRADE_WIX_FOOVIEWER"
/>
<!-- Detect newer versions -->
<UpgradeVersion OnlyDetect="yes"
Minimum="6.0.1.0"
IncludeMinimum="no"
Property="NEW_VERSION_FOUND"/>
</Upgrade>
<Condition Message="A newer version of Foo Corporation Foo Viewer is already installed.">
Installed OR NOT NEW_VERSION_FOUND
</Condition>
<InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize" />
</InstallExecuteSequence>
</Product>
However, despite putting in a <upgrade> element for the old installer's upgrade code, the old version isn't getting removed. As a result the new copy tries to install on top of the old copy, and then neither version works any longer.
The detection of the beta copy, and of newer versions, works correctly (the <Upgrade with GUID {43e024b8-b3ea-40a3-a854-2af83f207f0f} ). The beta version gets uninstalled, and if I generate a "newer" installer, then the current installer correctly doesn't install. That is, the WiX installers have no problem detecting each other.
Is there something I did wrong here that won't let it detect the old .vdproj installed copies?
EDIT: I tool a log of the installation process when this happens, I get the following:
Action start 17:25:47: FindRelatedProducts.
MSI (c) (10:B8) [17:25:47:269]: FindRelatedProducts: current install is per-machine. Related install for product '{2024FF03-D6F2-4065-A22B-80252B2A66B6}' is per-user. Skipping...
Action ended 17:25:47: FindRelatedProducts. Return value 1.
which appears to be accurate. The old installer gave an option for "Per User" or "Per Machine", whereas the new installer always forces per machine. If I select "Everyone who uses this computer" in the old installer, then the new installer is able to detect it. I would like to detect either option if possible in the WiX.
I'm afraid you can't deal with 2 different existing installations at the same time in single installer. Moreover you shouldn't try to run uninstallation of another product (since your UpgradeCode and ProductCode are different, it is anoter product) because msi can't work with simultaneous installations.
What I would recommend is creating separate exe application (bootstrapper), which will run child uninstallation processes of previously installed products and then immediately run your product's installation (probably in full UI mode).
To uninstall the product with no user interaction, use the following command:
msiexec /x {ProductCode} /qn
I hope you know the ProductIds of the previously installed products. If not, you can find it, searching the registry:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}\DisplayName
and HKEY_CURRENT_USER if application was installed for single user.
{ProductCode} mentioined in registry path is GUID which is your productCode. You should retrieve all nodes in "Uninstall" branch and find those which are your products checking the "DisplayName" attribute. I hope you know at least the name of the products installed =). And be careful not to delete all software on client's machine =)
Please note if you installed x86 application on x64 machine, you should search location
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}\DisplayName"
One more important notice: if your bootstrapper will be also x86 application, you should retrieve node without "Wow6432Node" node because it will be automatically inserted in the requested path. Wonderful world of registry keys on different platforms =).
Please ensure your bootstrapper will be run with admin permission or will ask permission elevation (it should contain security manifest).
One assumption about problem in your post: maybe you didn't change the ProductCode when changed the UpgradeCode? I'm not sure how it will behave, but it is definitely not a MajorUpgrade which automatically removes the previously installed product. For more details see Wix documentation on upgrades. So you might got Minor upgrade or patch which directly installs new components on top of the previously installed files. That definitely could break the application.
I have a major upgrade that I am trying to do, but it just doesn't work. It simply installs the new program along side the old one. They are in different directories (as I changed the directory structure with the new version) so there are no conflicts, but the old one NEEDS to be erased in order for my product to function properly.
<Property Id="UPGRADE_NEEDED" Secure="yes" />
<Property Id="SAME_OR_NEWER_VERSION" Secure="yes" />
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize" />
</InstallExecuteSequence>
<Upgrade Id="{PUT-YOUR-GUID-HERE}">
<UpgradeVersion Minimum="5.1.3" OnlyDetect="yes" IncludeMinimum="yes" Property="SAME_OR_NEWER_VERSION" />
<UpgradeVersion Minimum="5.1" Maximum="5.1.3" Language="1033" Property="UPGRADE_NEEDED" MigrateFeatures="yes" IncludeMinimum="yes" />
That is my upgrade elements (with GUID removed of course). If anyone can find where the problem lies I would greatly appreciate it.
There are some general rules for an upgrade to be working:
Old and new products must have identical UpgradeCode values and
different ProductCode values.
Old and new products must have identical values for
InstallAllUsers [i.e. a per-machine
installation cannot upgrade a per-user
installation and vice-versa.]
New product's setup Version (the setup project, nothing to do with file
versions) must be higher.
All setup versions (again, not file versions) must be 1.0 or greater.
Further details how to correctly implement an upgrade using WiX can be found in this thread:
How to implement WiX installer upgrade?
I am struggling to enable the major upgrade functionality in WiX.
I want every new version of the installer to be a major upgrade (full uninstall, then new install) as we don't want different upgrade and clean install versions.
I started off trying to do it using the tag stuff, but I kept getting "Another version is installed." error message when I run the installer.
So I implemented the new tag that was added in V3.5 to make upgrades easier. I was still getting the error message.
I then read somewhere that you need to change the Id GUID for each new version. So I set Id="*" to get WiX to generate them.
Now when I install the newer version it doesn't uninstall the older version, and you end up with two installations to the same folder. I worked this out because running either MSI (new or old) would bring up the repair/remove screen.
Also the program was not overwritten with the new version.
Here is the start of my WiX script:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="Foo"
Language="1033"
Codepage="1252"
Version="!(bind.FileVersion.Foo.exe)"
Manufacturer="Foo Bar Ltd."
UpgradeCode="dac2fab2-7d76-4e47-b25f-0748380dab81">
<Package
Description="Foo"
Comments="This installer database contains the logic and data required to install Foo."
InstallerVersion="300"
Languages="1033"
SummaryCodepage="1252"
Platform="x86"
Compressed="yes" />
<!-- Remove older versions -->
<!-- Important note: MSI ignores the last version digit 1.0.0.? when comparing versions, so always change at least the 3rd digit for new external releases-->
<MajorUpgrade DowngradeErrorMessage="The version currently installed is newer than the version you are attempting to install."/>
Here's a snippet of what I use for all my packages, refined over many internal and public releases
<Product Id="*"
UpgradeCode="$(var.Property_UpgradeCode)"
Name="!(loc.ApplicationName)"
Language="!(loc.Property_ProductLanguage)"
Version="$(var.version)"
Manufacturer="!(loc.ManufacturerName)" >
<Package Description="!(loc.Package_Description) $(var.version)"
Comments="!(loc.Package_Comments)"
Manufacturer="!(loc.ManufacturerName)"
InstallerVersion="301"
Compressed="yes"
InstallPrivileges="elevated"
InstallScope="perMachine"
Platform="$(var.ProcessorArchitecture)" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Upgrade Id="$(var.Property_UpgradeCode)">
<UpgradeVersion OnlyDetect="yes"
Minimum="$(var.version)"
Property="NEWERVERSIONDETECTED"
IncludeMinimum="no" />
<UpgradeVersion OnlyDetect="no"
Maximum="$(var.version)"
Property="OLDERVERSIONBEINGUPGRADED"
IncludeMaximum="no" />
<!-- Detect for changes in 4th field only -->
<UpgradeVersion Property="ANOTHERBUILDINSTALLED"
Maximum="$(var.version)" Minimum="$(var.version)"
IncludeMinimum="yes" IncludeMaximum="yes" OnlyDetect="yes" />
</Upgrade>
<CustomAction Id="CA_BlockOlderVersionInstall" Error="!(loc.LaunchCondition_LaterVersion)" />
<CustomAction Id="CA_BlockAnotherBuildInstall" Error="!(loc.LaunchCondition_AnotherBuild)" />
<InstallExecuteSequence>
<Custom Action="CA_BlockOlderVersionInstall" After="FindRelatedProducts">
<![CDATA[NEWERVERSIONDETECTED]]>
</Custom>
<!-- Prevent installation on 4th version field change only -->
<Custom Action="CA_BlockAnotherBuildInstall" After="FindRelatedProducts">
<![CDATA[ANOTHERBUILDINSTALLED]]>
</Custom>
<LaunchConditions After="AppSearch" />
<!-- Schedule RemoveExistingProducts early -->
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="CA_BlockOlderVersionInstall" After="FindRelatedProducts">
<![CDATA[NEWERVERSIONDETECTED]]>
</Custom>
<!-- Prevent installation on 4th version field change only -->
<Custom Action="CA_BlockAnotherBuildInstall" After="FindRelatedProducts">
<![CDATA[ANOTHERBUILDINSTALLED]]>
</Custom>
<LaunchConditions After="AppSearch" />
</InstallUISequence>
<!-- .... -->
</Product>
If it's of any use to those who discover this thread, I've also encountered a similar problem which I've just figured out.
In my case (and still having been in early stages of developing my installer), the critical difference was that, between versions, I had switched from a per-user install to a per-machine install. More specifically, I'd added the following line to my Product.wxs:
<Property Id='ALLUSERS' Value='1'/>
I'm still getting my head around many of the idiosyncrasies of Windows Installers, but I'd assume that by switching the type of installation in this way would be comparable with shifting to a mutually exclusive stream of versioning in many ways (even enabling two identical versions to be installed in parallel!).
It's a shame that the Windows Control Panel doesn't clearly distinguish between installations which are per-user and all-users.
I know this post is old and answered, but, in case anyone runs across this, I had issues with my upgrade installer. The upgrade sections were all fine. The installer would run, but, the previous version was never removed, therefore, the new version was not installed. The issue was this
<Feature Id="ProductBinaries" Title="ProductBinariesInstaller" Level="0">
The Level="0" above, should have been Level="1" as it is below:
<Feature Id="ProductBinaries" Title="ProductBinariesInstaller" Level="1">
Scott