Windows Installer always fails with error 1601 or 1603 when run from a service - wix

We have an application that gets installed at a customer's location. This application consists of a self-hosted WCF server running as a Windows service, as well as a client application that isn't related to this problem.
We publish updates to our customers by having the service download our WiX-generated .msi file in the background, then it is installed when the customer chooses to install it. The installation procedure is as follows:
The server copies a bootstrapper application to a temporary path and runs it, passing it the path to the MSI file to install
The bootstrapper uses the upgrade code in the MSI file to uninstall the previous version, then install the new version. It invokes the installer using various P/Invoke calls related to MSI's, like MsiInstallProduct.
The bootstrapper restarts the service
The issue is that at almost call customer sites, this automated process fails, though as with everything, it works in both testing and production at our location. Sometimes it fails during uninstallation, but normally it's during installation. Error codes 1601 (InstallServiceFailure) and 1603 (InstallFailure) are as common as they are entirely unhelpful in determining what went wrong.
We have a backup procedure whereby the user can manually invoke the installer by running the bootstrapper from within Windows (Run As Administrator is required, of course). This process works without fail, and it uses exactly the same installation logic as the automated process that fails.
All services are running as accounts with, at minimum, administrative privileges on the server box.
Where can I start in either trying to find more information about what is causing the error(s) or, even better, prevent them in the first place?
EDIT Here's one example of a failed install's verbose log file:
=== Verbose logging started: 3/29/2013 8:23:30 Build type: SHIP UNICODE 5.00.7600.00 Calling process: <<PATH TO MSI>> ===
MSI (c) (00:7C) [08:23:30:194]: Resetting cached policy values
MSI (c) (00:7C) [08:23:30:262]: Machine policy value 'Debug' is 0
MSI (c) (00:7C) [08:23:30:418]: ******* RunEngine:
******* Product: <<PATH TO MSI>>
******* Action:
******* CommandLine: **********
MSI (c) (00:7C) [08:23:30:491]: Client-side and UI is none or basic: Running entire install on the server.
MSI (c) (00:7C) [08:23:30:520]: Grabbed execution mutex.
MSI (c) (00:7C) [08:23:30:562]: Failed to connect to server. Error: 0x800703FA
MSI (c) (00:7C) [08:23:30:605]: Failed to connect to server.
MSI (c) (00:7C) [08:23:30:637]: MainEngineThread is returning 1601
=== Verbose logging stopped: 3/29/2013 8:23:30 ===

This is too broad of a question to answer but here's what I've designed for other customers:
1) The elevated service downloads the MSI to a local directory and "advertises" (blesses) the MSI using the command msiexec /jm foo.msi
2) The non-elevated client side component then installs the MSI using the command msiexec /I foo.msi
The MSI must be properly designed and UAC compliant. The transition from Install UI to Install Execute will happen without a UAC prompt. Only properly scheduled ( deferred without impersonation ) custom actions will run elevated.
Once all the kinds were ironed out, the customer was very happy with their autoupdate pattern.

Maybe you need to look into another corner:
When I came over strange installation problems in the past, they were usually caused by behavior analysis tools which exidentally blocked something they shouldn’t have. If some such a tool—may be part of a virus scanner suite or a standalone application such as ThreatFire—is installed on the computer in question, make sure no parts required for your update procedure are listed as “blocked” anywhere. If your update performs actions that lead to auto-treatment by the behavior analysis component, make sure to white-list them reliably.

Related

WIX Minor Upgrade with MSI instead of Burn

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

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

Windows per-machine install requires reference to original installer when second user runs application

I'm working on an MSI installer written in Wix. The installer works in both per-user, and per-machine contexts.
In a per-machine installation, everything goes smoothly; the product is installed and configured for the initial user. Upon switching to a test user, the application appears in the start menu correctly. Running it for the first time, a msiexec process starts with the message that the app is being configured. However, if the original .msi has been deleted, this process fails.
The failing setup action gives the following message in its log:
Error 1706. An installation package for the product myProduct cannot be found. Try the installation again using a valid copy of the installation package 'myInstaller.msi'.
=== Logging stopped: 3/16/2017 11:15:52 ===
I understand from reading a blog post by Rob Mensching (Lead of Wix) that it probably isn't possible to just edit the source list to point towards the windows cached .msi, a point backed up by another article I've found. Is that correct?
Is there a way to stop this entire action of calling the msi on first run by users from happening? Caching the msi or keeping the original is not ideal, I'd like to use the .msi in a custom bootstrapper that involves deleting the msi once installation is complete.
Microsoft recommends you keep the original MSI available, Rule 31:
https://blogs.msdn.microsoft.com/windows_installer_team/2006/05/24/tao-of-the-windows-installer-part-3/
and I won't repeat what it says about repair/resiliency, but you cannot guarantee the source MSI won't be needed sometime.
You're probably getting this "repair" because there is some resource (a file most likely) that is being installed to a user-profile location. When another user logs on and uses the application that file is missing, so potentially the application is broken. For example a file installed to User's Application Data needs to be available for all users of the system, not just the user that installed it.
So keeping the MSI might not be ideal but is strongly recommended, and in your case of product use by multiple users it's even more likely to required. There should be an Application Event log entry under MsiInstaller that says something about the missing resource.

Windows service fails to install for minor to major upgrade on Windows 8 in installshield

I have an installer of Minor Upgrade type. (Say MyAppMinor_v.msi)
I built another installer of same application of type Major Upgrade type (Say MyAppMajor_v+1.msi).
Both of these are built using InstallShield 2014.
MyApp has a Windows system service (MyService.exe) running in background.
Also, MyApp has functionality to update itself from App UI; in which the application updates itself using following command:
msiexec.exe /i MyAppMajor_v+1.msi
This command is run from MyService.exe of MyAppMinor version.
After the update process is completed, the service MyService.exe for MyAppMajor version does not get installed.
It gives following error in Installer logs:
MSI (s) (FC:2C) [10:17:54:387]: Product: MyAppMajor -- Error 1923.Service MyService failed to install. Verify that you have sufficient privileges to install system services.
I do have the admin privileges on the target machine.
This behavior is observed only on Windows 8/8.1.
On Windows 7 I do not get this error and MyService runs perfectly fine on MyAppMinor to MyAppMajor upgrade.
You may have admin on the box but it sounds with UAC you only have a standard user token.

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