How to copy a file only while major upgrade? - wix

We need to copy a file only when majorupgrade. If fresh install happens it should not copy.
I tried to find File attribute and component attribute which would do it but found none.
How to allow a file to copy when major upgrade?

You need to write Custom action to copy the files.
<CustomAction Id="QtExecCopyPropertyFileCmd" Property="QtExec64CmdLine" Value=""[SystemFolder]cmd.exe" /c copy "[INSTALL_DIR]\Test.txt" "[BKP_DIR]\Test.txt""/>
<CustomAction Id="QtExecCopyPropertyFile" BinaryKey="WixCA" DllEntry="CAQuietExec64" Execute="immediate" Return="check"/>
Check previous setup is installed or not using Upgrade property.
<Upgrade Id="{YOUR-GUID-HERE}">
<UpgradeVersion Property="PREVIOUSFOUND" Minimum="1.0.0" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" />
</Upgrade>
<Property Id="PREVIOUSFOUND" Secure="yes" />
Call the Custom action in Install Execute sequence. It will copy the files in Upgrades only.
<Custom Action="QtExecCopyPropertyFileCmd" After="AppSearch">(NOT Installed) AND (PREVIOUSFOUND<>"")</Custom>
<Custom Action="QtExecCopyPropertyFile" After="QtExecCopyPropertyFileCmd">(NOT Installed) AND (PREVIOUSFOUND<>"")</Custom>

You can have component Install Condition which check for existing product and then install. You can Check The following link Wix Conditionally Install Component if Registry Key Exists for more detail. There insead of filesearch you can do registry search also

Related

Wix Installer detecting SELFFOUND when should be PREVIOUSFOUND

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 created msi file, strange major upgrade behaviour

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.

I have installed major upgrade successfully but it also allowing another previous version install in wix

I have installed major upgrade (say #206) successfully and included code as in (#206):
<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" IncludeMinimum="no" OnlyDetect="yes" Language="1033" Property="NEWPRODUCTFOUND" />
<UpgradeVersion Minimum="1.0.0.178" IncludeMinimum="yes" Maximum="$(var.ProductVersion)" IncludeMaximum="no" Language="1033" Property="UPGRADEFOUND" />
</Upgrade>
Scenario is:
I have installed build #177 then upgraded to build #206. It is still allowed to install #177 which I want to prevent this downgrade.
From build #178 onward I have changed product GUID for major upgrade and which is working fine.
Please suggest how to prevent this. I don't want to downgrade build below 177. If I have done major upgrade on build no <= 177.
Your problem is the how the comparison of versions is done in MSI by default - 1.0.0.123 is treated the same as e.g. 1.0.0.33. You either have to increase your revision version to make the installer detect this as an older version or use a workaround.
You might for instance create a custom action to check against this very Revision version and place it e.g. before InstallValidate:
<CustomAction Id='MyVersionCheck' Return='check' (...) />
<InstallExecuteSequence>
<Custom Action='MyVersionCheck' Before='InstallValidate' />
</InstallExecuteSequence>
Some more information can be found in this article, for informations about how to create custom actions i'd recommend this blog entry as a starting point.

Uninstallation problem

When program is installed it is fired(by the installer) right after installation finishes. But when i uninstall the program from Control Panel, then it tries to open the exe too, which gives the following error:
Windows cannot find 'MyExe.com'. Make sure you typed the name correctly, and then try again. To search for a file, click the Start button, and then click Search.
with the cmd.exe in the background.
after i press OK, another window pops up, saying:
There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support...
Although the program gets uninstalled, these errors are not desirable.
Also when i install newer version and older version of the program already exists, i get similar messages as the installer tries to uninstall older version first.
Here is the code:
....
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="D2B0D435-0F86-4D5E-A988-B24215882***">
<UpgradeVersion
Minimum="1.0.0.0" Maximum="99.0.0.0"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
<CustomAction Id="LaunchApp" Directory="INSTALLDIR" ExeCommand="[SystemFolder]cmd.exe /C start MyExe.exe" />
<InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize" />
<Custom Action="LaunchApp" After="InstallFinalize" />
</InstallExecuteSequence>
</Product>
</Wix>
What i would like, is that installer would try to run the program only when installation occurs and do nothing when uninstallation is processed.
Thanks in advance!
Your problem is that you don't have a condition on the action so it fires every time. At a minimum you need a condition of "Not Installed". However for a more elegant solution, read:
How To: Run the Installed Application After Setup

Wix action FindRelatedProducts not working

This could be a stupid question.
What we did
We just want to use FindRelatedProducts action to check existing installation's version, by following Wix tutorial:
<Upgrade Id='YOURGUID-7349-453F-94F6-BCB5110BA4FD'>
<UpgradeVersion OnlyDetect='yes' Property='SELFFOUND'
Minimum='1.0.1' IncludeMinimum='yes'
Maximum='1.0.1' IncludeMaximum='yes' />
<UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND'
Minimum='1.0.1' IncludeMinimum='no' />
</Upgrade>
...
<CustomAction Id='AlreadyUpdated' Error='Foobar 1.0 has already been updated to 1.0.1 or newer.' />
<CustomAction Id='NoDowngrade' Error='A later version of [ProductName] is already installed.' />
<InstallExecuteSequence>
<Custom Action='AlreadyUpdated' After='FindRelatedProducts'>SELFFOUND</Custom>
<Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERFOUND</Custom>
</InstallExecuteSequence>
What we get
if no version was installed, FindRelatedProducts can detect that no installation exists, but
if 1.0.1 exists, when install 1.0.0, existing installation with higher version number should be detected, and err msg pop up, but it doesn't.
We used Orca to check the installation entry info on .msi files (1.0.0 and 1.0.1), properties of both are correct.
We used msiexec /a foo_1.0.x.msi /l* foo_1.0.x.log to get the log, but found the NEWERFOUND property is NOT set!
What we did wrong?
Make sure the UpgradeCode is the same for both 1.0.0 package and 1.0.1 package and in Upgrade/#Id attribute.
YES, I have try the example from WiX tutorial, replace YOURGUID*** with real GUID, the example doesn't work, I still can install old version over the new version, the downgrade check mechanism seems do not work.