Uninstallation problem - wix

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

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.

How to copy a file only while major upgrade?

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

Wix 3.6: Conditionally trigger "RemoveExistingProducts"

I crawled the web but found no solution or I just got not the clue.
I need to conditionally perform the RemoveExistingProducts action in my setup. I want my setup to uninstall all existing products by default, like this:
<MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="No downgrades allowed" />
This works fine. But when the user deselects a checkbox in my UI I want the installer NOT to uninstall previous product version. So I tried something like this:
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="3E700BA7-CAF8-4C49-A53A-70F70DE0C8D6">
<UpgradeVersion
Minimum="1.0.0.0" Maximum="99.0.0.0"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" IncludeMaximum="no" OnlyDetect="myVar" />
</Upgrade>
<Property Id="myVar" Value="no" />
hoping, that I can set the myVar, but this is illegal.
Has anybody an idea how to solve my problem?
The reason is, that we want to allow the users - at their own risk - to have more than one version of our product installed - this is a request by our customer.
I think, in the default sequence, RemoveExistingProducts is run before the UI.
You could try rewiring the RemoveExistingProducts action to be after InstallFinalize and trigger it with a condition:
<RemoveExistingProducts After="InstallFinalize">
NOT CHECKBOX
</RemoveExistingProducts>
Not sure how this would fare in your case.
You could also try running a custom action when you exit the dialog with your checkbox to manually uninstall the product. Maybe you could even force the launch of RemoveExistingProducts in said custom action.
One last solution would be to make a separate uninstaller that prompts the user to uninstall the product or not and follow up with the actual installer.

Start application after installation

I've googled around and found some topics like
http://wix.sourceforge.net/manual-wix3/run_program_after_install.htm
and
Launch application after installation complete, with UAC turned on
but, i don't use any ui. Just simple installation!
So far
<CustomAction Id="LaunchApp" Directory="INSTALLDIR" ExeCommand="[SystemFolder]cmd.exe /C MyExe.exe" />
<InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize" />
<Custom Action="LaunchApp" After="InstallFinalize" />
</InstallExecuteSequence>
but when i start the installer, a window pops up: "Please wait while Windows configures MyProgram". and on top of it comes cmd.exe just with a blinking cursor, when i close cmd i get message :"There is a problem with this Windows Installer package. A program required for this install to complete could not be run." Though program remains opened.
How can i do that properly (without any UI)?
Thanks in advance!
What happens if you use
ExeCommand="[SystemFolder]cmd.exe /C start MyExe.exe"
Set Return to asyncNoWait for your custom action. This way the custom action runs and the installer doesn't wait for it or check its return code.
I had the problem that it also tried to run at uninstallation.. This way it runs only on installation, reparation and updating (changing)
<CustomAction Id="LaunchApp" Directory="INSTALLFOLDER" ExeCommand="[SystemFolder]cmd.exe /C start MyFile.exe" />
<InstallExecuteSequence>
<Custom Action="LaunchApp" After="InstallFinalize">NOT REMOVE</Custom>
</InstallExecuteSequence>
Information about NOT REMOVE could be found here: https://stackoverflow.com/a/17608049/9758687