WiX ingores a running program when running uninstall for non-default path - wix

WiX installer uses regular dialogs for specifying the target path:
<UIRef Id="WixUI_Common" />
<UIRef Id="WixUI_InstallDir" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
When the user just clicks through the installation wizard the default path is used. The user then runs the program (SomeExecutable.exe) and leaves it running. He then goes to list of programs and asks Windows to uninstall the program. The wizard properly displays a message saying that SomeExecutable.exe is running, so a restart would be needed. That's the expected behavior.
However if the user changes the target to something like c:\UserSpecificedFolder then installation works just fine but when an uninstall is attempted while SomeExecutable.exe is running then unistall finishes without any messages and files are not removed. The program continues running. That's not the expected behavior.
It looks like some extra step is needed to inform the installer that install path was changed and so it should treat the new path as install path when uninstall is being run.
Why would it not work?

What does the Windows Installer uninstall log say? I'm not completely convinced this is a problem even though it seems obvious. WiX only creates MSI databases. It doesn't do the uninstall, MSI does. MSI only prompts file in use / reboot interactions when it isn't able to do an operation. If there is no file lock it may be completely normal to not see it.
My follow up question would be is the file uninstalled at the end without rebooting?

Related

Wix Installer: Bundled MsiPackage causing install bundle to attempt to run again?

I have the following very basic WIX 3.11 bundle defined at the minute and I have removed the execpackages that fire before the MSI is installed as the problem I'm about to describe only occurs with the MSIPackage command and the specific Third Party MSI I'm using.
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle Name="ACME APP 32Bit" Manufacturer="ACME CORP" Version="1.0.0.0" UpgradeCode="0B736949-AE50-46B0-A534-42C9672FAF1F" IconSourceFile='..\Common Files\Images\icon.ico'>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLargeLicense">
<bal:WixStandardBootstrapperApplication
LicenseFile="..\Common Files\Documents\EULA.rtf"
ShowVersion="yes"
LogoFile="..\Common Files\Images\logo-64x64.png"
LogoSideFile="..\Common Files\Images\logo-64x64.png"
/>
</BootstrapperApplicationRef>
<Chain>
<MsiPackage Id="TP32BIT" SourceFile="ThirdParty.msi" Visible="no" />
</Chain>
</Bundle>
</Wix>
What is happening is after the bundle deploys the MSI and whilst the Installation completed successfully dialog is present , the modify setup dialog again (repair uninstall cancel ).
It only appears to happen with the third party MSI that I need to install. I don't have control over this MSI and nor can I get support on changing from the manufacturer at this time.
I've replaced the MSI with another random product and it doesn't result in the same issue. Its deployed without effectively attempting to run the bundle installer again.
I've run the Third Party MSI from the command line and checked it's return code on instillation and it returns 0.
I'm baffled as to whats causing the installer to think it needs to run itself again on completion of this MSI. Non of the UUIDs are in conflict and I don't think there's anything wrong in my xml.
If anyone can shed some light onto this I'd appreciate it. Currently the only thing I can think of doing is attempting to deploy this specific MSI to the platform via a execpackage approach that runs the msiexec from command line but that completely negates the reason I'm using a bundle in the first place.
Thanks in advance.
I am a little bit confused reading this.
Does the problem manifest itself if you run ThirdParty.msi interactively with full setup GUI outside the Burn Bundle?
In other words a regular installation, that is not invoked via command line but run by double clicking the MSI and then clicking through the setup GUI.
I suppose it is possible that some fancy event in the setup complete dialog kicks off a custom action that does something crazy. Is this an MSI that we can take a look at? Can you provide a download location? (no promises though).
When the setup is run in silent mode, the GUI sequence does not run - which could explain why things work in silent mode - if this is indeed the case.
Turns out it's a known bug in WIX that is triggered by the 3rd Party MSI. github.com/wixtoolset/issues/issues/5266 This MSI can't be changed and has to deploy it's content using this mechanism. I've been able to create a work around to resolve the issue as the installer starts 2 new instances of Wix after the MSI completes so I'm tracking the process IDs and killing anything "unknown" –

Install program fails to shutdown running target...workarounds?

I have a WIX install program.
When I test my install program on a machine where the old version of the software is running, I get the prompt below.
The problem is that the installer can't manage to close the application. When the new program runs, it complains about the old one running.
Is there a way to forcefully kill the app?
If not, is there some entry in WIX that will require the user to shutdown the application before it will continue installation?
I found the answer here:
WiX <util:CloseApplication> element not working
I made one tweak to the solution in the post above. I kill the application earlier in the install sequence so the window above doesn't appear.
<!-- Code to force termination of running program...MSIExec couldn't do it -->
<Property Id="QtExecCmdLine" Value='"[WindowsFolder]\System32\taskkill.exe" /F /IM "$(var.ProductName).exe"'/>
<CustomAction Id="APP.TaskClose" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="immediate" Return="ignore"/>
<InstallExecuteSequence>
<Custom Action="APP.TaskClose" After="LaunchConditions"/>
</InstallExecuteSequence>
If you are wondering what "$(var.ProductName).exe" is, I pass the exe name on the commandline because I'm creating several branded versions of the same program. Just substitute your exe name.
And yes, it is safe in this particular intance to do this. There is no data held in memory that could be lost.
You should use the WiX util extension CloseApplication:
http://wixtoolset.org/documentation/manual/v3/xsd/util/closeapplication.html
That should work.
Long term you should get the app integrated with Restart Manager so it will shut down automatically.

Prompt a Reboot message after installation WIX Bootstrapper

I have a WIX Project and a Bootstrapper of WIX.
I am using Reboot property of WIX to prompt for reboot machine after setup complete its installation.
But when i run my msi using Bootstrapper then it did not prompt a message for reboot machine.
below is my code that i am using in Product.wxs file in WIX:-
<Property Id="REBOOT" Value="Force"/>
Now i am using chain of msi in Bootstrapper project below:-
<Chain>
<MsiPackage SourceFile=".\Bonjour.msi" Compressed="yes" />
<MsiPackage SourceFile=".\Security_IDTools.msi" Compressed="yes" />
<MsiPackage SourceFile ="$(var.BiodentifySetUp.TargetPath)" Compressed ="yes" DisplayInternalUI="yes" />
</Chain>
But when my last msi run it did not prompt reboot message?
The REBOOT property does not force a reboot, and in the context you're using it is a Windows Installer property not a WiX property. The REBOOT property tells Windows what behavior should occur when a reboot occurs. You need a ScheduleReboot action in your MSI file if you want a reboot at the end of an MSI install and want to ask for it, or a ForceReboot if you want to just do it, as Nimish says.
There is also the question of why you want to force a reboot in the first place. Windows will reboot if something happens that requires one - there's no need for you to assume that a reboot is required just because an install has finished.
A Reboot may be necessary due to the stupid behavior of events and security in Windows 8 (and even in windows 7). That is the "easiest" way to make sure all of your services have been started correctly. I would expect that as already mentioned would be the best choice so that there is no abort of the bootstrapper in the middle.
Priyanka if you have any plans to continue your installation after reboot then do not use the MSI's reboot prompt with a bootstrapper.
That's because it would effectively abort the bootstrapper and won't give it a chance to resume on reboot if necessary.use <ExitCode Behavior="forceReboot" /> after MsiPackage you want it to restart. After a force reboot, Burn will automatically resume after the reboot and rest of your MSI/Exe would be installed.
But if you dont have any such plans you can go with ScheduleReboot Action in your MSI.
<InstallExecuteSequence>
<ScheduleReboot After="InstallFinalize"/>
</InstallExecuteSequence>
This will tell the MSI package to reboot after successful install.
And make sure to check log for any error.

Standalone WIX uninstaller

I'd like to create a standalone silent uninstaller using WIX that I can send to specific people for support purposes that can be double-clicked to execute the uninstall of our product when the uninstaller did not work properly on their machine and no longer exists (some users remove things manually using other tools). I have a .wxs file that uses the same product id and package id of the previously installed program, and if I run from msiexec /x it uninstalls the previously installed product perfectly. Double-clicking on it (which is all these users can be expected to do) however runs installation, not the uninstall. I tried adding
<Property Id="REMOVE" Value="ALL"/>
<Property Id="ACTION" Value="UNINSTALL"/>
and making sure all InstallExecuteSequence actions are not using an "Installed" check but the product is still installed after running successfully, the log file shows it is still executing ACTION INSTALL:
MSI (c) (A8:F8) [15:42:08:324]: PROPERTY CHANGE: Adding ACTION property. Its value is 'INSTALL'.
MSI (c) (A8:F8) [15:42:08:324]: Doing action: INSTALL
MSI (c) (A8:F8) [15:42:08:324]: Note: 1: 2205 2: 3: ActionText
Action 15:42:08: INSTALL.
Action start 15:42:08: INSTALL.
Is there a way to force an .msi file to perform an uninstall without using the command line or add/remove programs entries? I've seen entries about using ARPSYSTEMCOMPONENT but not enough information to do it.
I don't think so. You could, of course, use an exe to do it. I would also strongly suggest that you use the original msi file instead of creating a different msi with the same product code.
For the exe, you could use any number of chainer/bundler/downloaders. There is NSIS and also WiX's own Bootstrapper, ... even WinZip.
You should also note that many package management systems that run uninstall commands will run the install command first if anything is amiss. The theory is that an uninstaller can't properly run unless the critical data placed by installation exists. (E.G., WPKG). For Windows Installer, this usually doesn't apply since it's data is hidden from the user. But if they found it and corrupted it, reinstalling and/or repairing using a fresh copy of the original msi might do the job.

WiX MSI behaves differently before and after removing CRT MSM

I've got an MSI built with WiX. It performs the following custom action:
<CustomAction Id='StartTray'
Directory='INSTALLDIR'
ExeCommand='[INSTALLDIR]\myapptray.exe'
Return='asyncNoWait'
Impersonate='no'
Execute='deferred' />
It is scheduled like so:
<Custom Action='StartTray' After='StartServices'>NOT Installed OR (TRAYWASRUNNING AND NOT REMOVE~="ALL")</Custom>
myapptray.exe happens to use impersonation to relaunch itself from its starting context of Local System (running from MSI context) as the user currently active on the desktop. This is not in my control and Impersonate='yes' does not work because the MSI may be invoked for an upgrade from the context of the system service, meaning Impersonate='yes' would still end up running the app as Local System.
I recently moved from including the VC9 CRT as a MSM in this MSI, to including it in a bootstrapper exe.
Doing this prevents the myapptray.exe custom action from running successfully. The impersonation fails in WTSQueryUserToken which returns ERROR_PRIVILEGE_NOT_HELD. This seems to imply that removing the MSM actually changed the user context in which the MSI runs, but that seems ridiculous. The only lines I removed from the wxs file are the <Merge> and <MergeRef> tags for the MSM, nothing else has changed.
What am I doing wrong?
I'd look more at what versions of the CRT your EXE was built against and if there are any policy rules saying what it can run against. Moving from an MSM to an EXE run before your MSI should generally be a good thing.
BTW, I did something really hacking like this once upon a time. We had to push an MSI out under the SYSTEM context using MSI. If a user was logged on we had to relaunch the application using the users desktop login session. I had a DCOM server installed configured to impersonate the interactive user to accomplish this. Really wierd, but there was a valid reason.
This was all before Restart Manager though.
I figured it out.
The CRT MSM was setting ALLUSERS=1 and the installer's behavior changed because it was not present in our base installer. The MSM's setting of ALLUSERS was inherited into the base installer as a result.
Setting ALLUSERS=1 in our wxs file fixed the problem!