WIX Minor Upgrade with MSI instead of Burn - wix

I have an MSI and an EXE generated with Burn that warps the MSI. Although I can get the exe to properly run a minor upgrade every day I have a new build, when automatically run on DoD hardened systems (In this one case McAfee Endpoint Security with Access Protection, Exploit Protection and ON-Access Scan all enabled) the burn generated EXE fails with a Failed to launch clear room process error. So I went down the path of manually executing the MSI. Now I can get this to update the binaries are restart my service, however the version in the Add/Remove programs is not updated. Is there anyway to get the version number to update in add/remove programs without Burn and without uninstalling first?
I am using the following command line to run the MSI:
msiexec /I "[myinstaller.msi]" REINSTALL=ALL REINSTALLMODE=vomus -norestart

Related

Why would a WiX installation create two entries in HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\

I'm trying to uninstall an older version of our product which was installed using a WiX-built installer and after uninstalling it silently:
msiexec /x{GUID}
the program still appears in Control Panel. I've opened a separate item to
explore that mystery, but another curious issue has popped up. I noticed that after running the install for this program, two entries (GUIDs) are added to HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall. One with the product GUID and one that I have no idea where it comes from. I've searched through the .msi and it's not in there. Both are created each time I install, both are removed if I uninstall from the Control Panel and both are left in the registry if I uninstall from the command line. So have a look
Anyone have any ideas what's going on here?
Embedded Setup.exe: In essence it looks like you are installing an MSI that also installs an embedded non-MSI setup.exe via a custom action as part of its own installation sequence. Or, there is a setup.exe launcher that kicks off the MSI and the legacy setup in sequence. Result: two entries in Add / Remove Programs.
Uninstall: It is obvious, but to get rid of the second entry you must run its uninstall sequence - in addition to the uninstall of the MSI. Non-MSI setups are less reliable when it comes to uninstall than MSI packages. The implicitly available uninstall for all MSI packages with reliable silent running is one of the core benefits of MSI: MSI Core Benefits (among other topics).
Uninstall Commands: Try running the silent uninstall string, I guess that is what you have done?
Run commands elevated! With admin rights!
REM Uninstall MSI
msiexec.exe /x {PRODUCT-GUID} /L*v C:\MySetup.log /QN
REM Uninstall legacy setup.exe
"%SystemDrive%\ProgramData\Package Cache\{c5f0cb3e-1de3-4971-843a-abb981ed670c}\MDRSetup.exe" /uninstall /quiet
Silent Running: To run legacy setups silently you sometimes have to record a "response file" to record all settings in the GUI and pass to the uninstall process. I have some previous answers on this. You also need to run with admin rights:
Create MSI from extracted setup files
Regarding silent installation using Setup.exe generated using Installshield 2013 (.issuite) project file
How to run an installation in /silent mode with adjusted settings
Application Repackaging: What is the name of the software you are installing? MDRSetup.exe, is that Max Data Recovery 1.9? Probably not. Getting rid of legacy software can be challenging. You can always try to re-package it as an MSI if you have the tools to do so, or maybe you have a team in your company to do so (all large companies tend to). Not all legacy setups can be repackaged. There could be constructs that are impossible to capture, such as certain drivers, generated and unique keys per machine etc...
Links:
Create MSI from extracted setup files
How can I use powershell to run through an installer?
Wix - How to run/install application without UI
Capturing all changes during an application install on Windows

WIX BootStapper should prompt Reboot message

I am using WIX bootstrapper for installing the newer version of the Installed MSI. The issue is during the installation if one of my files in the MSI is being used by any of the processes, I want them to be queued for installation and prompt a message box telling the user to reboot the system so that the queued packages will be updated after rebooting.

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.

I screwed up, how can I uninstall my program?

My Wix installer worked installing my program, but it's broken for uninstallation. A file is removed too early, and it's needed further down the line. The uninstaller fails and reverts its changes.
This means I can't remove the package from my machine, and hence can't install any further builds of my installer (a considerable inconvenience). How can I force removal of the package?
Update, Stein Åsmul: Injecting this newer list of cleanup approaches.
Find your package in C:\Windows\Installer, where Windows keeps copies of installed MSI packages. The names are generated randomly, so you'll have to look at the creation dates of the files.
Open the MSI file with Orca. (Unfortunately there is no simple download for the orca installer. You can get it by installing the "MSI Tools" of the Windows 10 SDK, and then searching for orca.msi in C:\Program Files (x86)\Windows Kits.)
Delete the offending custom action from the CustomAction table
Now you should be able to uninstall the package.
UPDATE: You can find the actual cache MSI file using Powershell. That was for one package, you can also get for all packages (scroll down to first screenshot).
This command usually works for me:
msiexec /fv installer.msi
It somewhat recaches the installer, so you can try again with a corrected one.
One time this command didn't work and I had to use Microsoft FixIt. It solved the problem (quite a shock for me).
Depending on the exact reason of the behavior you described, you might have at least a couple of options.
If the reason of the failure is a custom action which runs on uninstall, and this custom action is conditioned with some properties you can influence upon, you can try to pass the desired value via the command line:
msiexec /x {YOUR-PRODUCTCODE-HERE} RUNMYACTION=false
In this sample RUNMYACTION is a Windows Installer property which participates in a custom action condition, and if you pass false as its value, the action won't run.
Otherwise, you can fix the logic (or just disable the custom action explicitly) and build the new MSI package. Then upload it to that target machine, and run like this:
msiexec /i YourPackage.msi REINSTALL=ALL REINSTALLMODE=vomus
Here YourPackage.msi is a new fixed package, REINSTALL=ALL instructs the msiexec to re-install the product using this new package, and REINSTALLMODE=vomus (the v part of it) will re-cache the MSI package and you'll be able to remove it the normal way afterwards.
A side note: you should test your installation on a virtual machine in order not to risk your real one.
FYI: In Windows 8.1 the installers have been moved here: C:\ProgramData\Package Cache\
If you are really desperate and all solutions above don't work try
msizap.exe
This will erase all that your installer put on a machine
LITTLE WARNING
Don't run msizap without knowing what options you want to run it with (for a list of options run msizap /? first).
I used this little tool also from Microsoft
https://support.microsoft.com/en-us/help/17588/fix-problems-that-block-programs-from-being-installed-or-removed
Basically this tool can be used to "repair issues including corrupted registry keys that block you from installing or removing programs"
What it fixes:
Corrupted registry keys on 64-bit operating systems
Corrupted registry keys that control the update data
Problems that prevent new programs from being installed
Problems that prevent existing programs from being completely uninstalled or updated
Problems that block you from uninstalling a program through Add or Remove Programs (or Programs and Features) in Control Panel
It can be used for:
Windows 7
Windows 8
Windows 8.1
Windows 10
I usually just look for <Your Installer's Name>.msi or <Your Installer's Company Name> in the registry and delete some of the uninstall keys from some of the Products under the Windows installer trees and everything usually works fine and dandy afterwards, although this WOULD leave some stuff lying around like cached installers and possibly tons of other registry keys for each file installed, etc. but its ALWAYS worked for me when developing installers because honestly, who cares if one MSI is left over and cached somewhere? You're using the machine for development anyways, right?

WiX: Forcefully launch uninstall previous using CustomAction

I'm writing a new major upgrade of our product.
In my installer I start by finding configuration settings of the previous version, then I'd like to uninstall the previous version.
I have found several guides telling me how one should make a MSI suitable for such upgrades.
However, the previous was not an MSI.
It was not according to best practices.
It does, however, in registry HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{GUID} specify an UninstallString.
Using a RegistrySearch I can easy find the command below, which I store in UNINSTALL_CMD.
RunDll32 C:\PROGRA~1\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\01\Intel32\Ctor.dll,LaunchSetup
"C:\Program Files\InstallShield Installation Information\{GUID}\setup.exe"
-l0x9 -removeonly 4:
I cannot get the hang of the CustomAction needed to perform the actual uninstall.
<CustomAction Id="ca.UninstPrev" Property="UNINSTALL_CMD" ExeCommand="" />
The MSI logs says:
Info 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: ca.UninstallPrevious, location: RunDll32 C:\PROGRA~1\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\01\Intel32\Ctor.dll,LaunchSetup "C:\Program Files\InstallShield Installation Information{GUID}\setup.exe" -l0x9 -removeonly, command:
Anyone seeing what I am doing wrong here?
Regards
Leif
I did application repackaging for a couple years at Continental Airlines where I did SMS pushes to an 18,000 seat forest. I frequently had a legacy application in the wild that was not installed using MSI that I needed to get redeployed using MSI and once that was done I supported major upgrades going forward.
These previously deployed apps typically had very broken and misbehaved uninstallers. Instead of calling these, I would use SMS to query the forest to get all the deployed versions. I would then deploy those old packages to a integration lab and work out what it was each installer did to the machine and write my own aggregated "forced cleanup" custom action that was capable of wiping the various versions of the application off the machine.
I executed this custom action prior CostInitialize so that when the new MSI did it's costing it wouldn't be influenced by the crap that was no longer on the machine. This worked for me because I pushed packages as System and I didn't have to worry about elevation issues. If you want to be fully UAC compliant you would want to run this custom code from a prereq package and either have your users run it manually or wire it into a bootstrapper to run prior to your MSI.
After a good nights sleep I found my error.
If you really read http://wix.sourceforge.net/manual-wix3/wix_xsd_customaction.htm the answer was there.
I was trying to make a type 50 custom action, launch an executable already installed on system.
Property specifies the full path to an executable to launch
ExeCommand specifies the command line arguments for this executable above.
And my fault was that I did place the full exe+command line in the Property field.
/L