WIX Bootstrapper Takes Too Long To Begin - wix

I have a working WIX Bootstrapper that does install the software I need it to install. However On Windows 8 At least, there is a 16 minute period where it appears to do nothing. Looking at TaskManager, I see no processes taking resources from the Bootstrapper (that I can tell). For some reason about 15 minutes into it it will just finish the install:
[0E6C:0E90][2014-01-24T13:49:45]i299: Plan complete, result: 0x0
[0E6C:0E90][2014-01-24T13:49:45]i300: Apply begin
[0E04:0DD8][2014-01-24T14:05:35]i360: Creating a system restore point.
[0E04:0DD8][2014-01-24T14:05:50]i361: Created a system restore point.
Any ideas as to why this is taking so long, after the log says "Apply begin"?
Note: Behavior does not happen on XP or Vista, Or 7. I think it has something to do with "pausing" Windows updates during installs. Does anybody know anything about that?
Thanks.

This sounds like a timeout of some sort. I assume there are multiple MSI files, and some of them may be tagged with a launch condition (look in the LaunchCondition table) which disallows installation on Windows 8? Maybe worth a check at least. Try launching each MSI manually in sequence and see if you receive any error messages. There may also be missing runtimes such as .NET, C++, Crystal Reports or similar. Often the MSI will display an appropriate error message to tell you what is wrong.
In case you find nothing when launching each MSI, you should make verbose log files for all of them so there is something to work with for debugging. If you are unfamiliar with msiexec.exe (Windows Installer Command Line Interface), you can use the tool described in this thread: installation using msi.exec open help options every time . It should be easy to enable verbose logging using that tool.
Also check this thread: How to skip a bootstrapper or ignore fail in Windows 8?
And the documentation might be useful: http://wixtoolset.org/documentation/manual/v3/howtos/redistributables_and_install_checks/

I never could find a parameter or condition in my installer that would cause this. However the effect went away when I used insignia to sign my wix projects (MSIs and a bootstraper). Prior to that I had been using the signtool by itself to do the signing.

Related

Uninstall is not working for MSI application - Error 1722

I have created MSI using WIX 3.11. I have made some customization to the Installer to install the application in a custom folder. I am also writing Install path to registry value under HKLM\Software.
I am reading registry value in batch file for one of my use-case.
Installation is successful and the application is running fine.
But while uninstalling, I am facing below issue -
Uninstall window pops up with the message - The following applications should be closed before continuing the Install: [MyApplication]
In uninstall log while removing the service, I see below error - Error 1722. 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 personnel or package vendor.
If I remove the service manually, no errors can be seen and the service is getting deleted. Not sure why Uninstall is failing.
Please shed some light on this.
Stop Service Before Uninstall: In the compiled MSI, what entries do you have in the ServiceControl table? You need to stop the service before its executable is deleted. See WiX service installation sample linked to below.
Failing Custom Action: It is also possible that you have a custom action which tries to run a batch file that has already been uninstalled when you try to run it. This can be a custom action that should not run on uninstall (conditioning is wrong), or you have sequenced it incorrectly so the batch file is gone from disk - courtesy of the uninstall - before the custom action can run successfully. You need to move the custom action earlier in the installation / un-installation sequence or condition it better so it never runs on uninstall. Both issues are very common. Be aware that it is common to fail to condition custom actions so they run unexpectedly. Very often they run during major upgrade uninstalls undesirably.
Batch Files CAs: For what it is worth - and no offense: using batch files in custom action is an MSI anti-pattern in my opinion. There is basically zero error handling and hence no management and recovery from error conditions. And generally no MSI rollback support. C++ custom actions are best in my view (minimal dependencies, good debugability, full featured language, large down-to-the-metal API). Just so it is mentioned. It all depends how large your distribution is. For in-house appliations one can get away with more than for truly global package distribution. This has to do with the complexity of deployment (see section a bit down the page). There are so many error sources.
WiX Service Installation: Maybe see this hands on WiX-markup sample from Rainer Stropek: WiXSamples - github.com/rstropek. Please check
the ServiceControl element.
Common MSI Problems: I hate to "pitch" this content. It is essentially the things you can't easily find in books - and for good reason. Some rules of thumb and opinions in a chaotic form, but here it is if you want to check it out: How do I avoid common design flaws in my WiX / MSI deployment solution? Just honest opinions and practical advice - no claim to be "right", but it should help setup reliability. Hopefully.

Other installation In Progress Hanging my Wix Install

I am creating a WIX installer bootstrapper (with DisplayInternalUI="yes" on the msipackage), but it hangs when there are other installations occurring at the same time.
If i run the MSI file on its own using msiexec I get a windows installer error
"Another installation is in progress" message (i.e 1500 MSI error message) - and I presume this is hanging my install.
Therefore what I am doing is seeing if I can lock the _MSIExecute mutex just after the user presses the Install button (i.e. before the ProgressDlg). If I can lock the Mutex then there are no other installs in progress - therefore it is safe to proceed with the install (i.e. the execution phase) . If not the installer shows a cancel button (and no other buttons) - so the install will not proceed.
I was wondering if there was a way of preventing the "Another installation is in progress" error message (and other messages) from hanging the installer.
Simpler explanation from serverfault.com
No MSI Concurrency: Why are there other installations happening "at the same time" - or in other words concurrently? I am not too potty-trained when it comes to WiX Burn bootstrappers, but I am wondering if the MSI in question contains any custom actions which kicks off other MSI installs? This is not allowed for MSI packages. You can not have two concurrent InstallExecuteSequences running at the same time. Hence you can not kick off an MSI from within an InstallExecuteSequence. Some people try to kick off installs from the InstallUISequence, which is also very unadvisable for many reasons - for one thing it won't run at all when the setup is run in silent mode. I also suspect potential issues with elevation, and unexpected setup failure if you set check exit code for the custom action, and that kind of stuff. It always permutes. The basic rule of thumb to remember is: Custom actions must never launch other MSI installations. The WiX Burn bootstrapper basically specifically exists to allow you to run MSI files in sequence - and not concurrently - but it is also more: it is a combined bootstrapper, chainer, downloader, etc...
Mutex: Strong words, but if you know what is good for you, you will stay away from MSI mutexes. Save yourself! :-). MSI is a technology which fights back, and you will be fighting windmills for real if you take the fight. That is all I can say to warn you. It really is impossible to deal with unless you follow the basic rules, which in this case is one installer running at a time. The WiX guys could deal with it though - leave it to them - and use their tool propery (WiX Burn). Though the technical details are unclear to me, they will certainly have features implemented to do exactly what you describe (check if the system is ready for installation).
Suspended Installation: It is also possible that there is a suspended installation on your system that needs to be undone before you can install MSI files at all. Can you try to install another MSI file and see if it runs correctly? I am not 100% sure this is the right link, but you can also try: Fix problems that block programs from being installed or removed.
UPDATE: With regards to _MSIExecute Mutex. See towards bottom for technical info on checking the current Windows Installer status using QueryServiceStatusEx. Heath Stewart suggests another way (sample C++ code).
Also, some pre-existing, related answers:
check for windows installer mutex availability
How to detect a running MSI Installation
Windows Installer always says “Another program is being installed”
First some comments on the issue at hand (virtuals updating and pending reboots):
Windows Updates In Progress: If you are dealing with the situation where Windows Updates are being performed in the background and MSI installations won't run, then it is possible that WiX Burn might hang whilst checking whether a system reboot is pending. I have seen issues like this before (see "technical issues" below).
Real Fix: If this is the case the only real fix is to let the Windows Updates finish and then reboot and persist a new virtual machine state and then install your package. This is the only sane fix - in my opinion. Not what you want to hear :-).
Dirty "Fix": I suppose you could also stop the Windows Update service to prevent Windows Updates from installing, but my guess is that your virtual will be infected with malware eventually if you do this, and then you have the horrible situation that you may accidentally persist malware in your virtual that is then resurrected regularly and not detected by security software (which often does not scan virtuals). This might be one of the worst malware vectors in existence due to the difficulty of erradicating it and discovering it (in the same league as malware on read-only media and malware checked into source control systems - there might not be an easy way to get rid of it). Well-meant advice (the kind that is never wanted - we all live in reality): please do not disable Windows Update on your virtual without a proper consideration of consequences. Corporate-wide I would never allow such a thing - only as exceptions for specific users who have testing needs beyond normal - and the virtuals would be forcibly malware checked regularly. Which reminds me to check what security software can scan offline virtuals properly. More research to do. Funny that, writing stackoverflow answers always teaches me what I don't do properly myself! Not good :-).
Technical Issues: As to the technicalities. I have seen issues before where WiX Burn hangs because it specifically tries to avoid installing on a system that is being updated:
WiX behaving badly on XP machine with windows update issues
How do I reference the Reboot Pending Property in Burn (WiX) (recommended)
Maybe check if that little VBScript in the linked answers (or equivalent COM call in whatever language you want) will tell you if the system is not ready for installation?
The Simple Hack?: Not verified, but maybe you can check the registry key / value (not sure whether this is a value or a key): HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer : InProgress - it should be present to indicate an active Windows Installer session - as far as I know. I think this is better than trying to handle mutexes and other OS fundamentals.
Strangely I am not aware of any MSI API calls that will tell you whether there is an active installation session (mutex set). The only thing I can see is a Win32 function (i.e not COM automation): MsiBeginTransaction (a very recent addition to the MSI API, 4.5 up only).
There is also this: MSDN: _MSIExecute Mutex - suggesting to use QueryServiceStatusEx and check whether the value of dwControlsAccepted is SERVICE_ACCEPT_SHUTDOWN. I have never tried it. Frankly I would try to check the above registry key instead.
If Windows Update is your main concern, then you'd use the Windows Update Agent API to detect if there is an update in progress. I think you'd need to run it from your own bootstrapper before attempting to install the MSI. The general C++ idea is as follows:
#include "stdafx.h"
#include <wuapi.h>
#include <iostream>
#include <ATLComTime.h>
#include <wuerror.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr;
hr = CoInitialize(NULL);
IUpdateSession* iUpdate;
IUpdateSearcher* searcher;
IUpdateInstaller* iInstaller;
ISearchResult* results;
BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1 or
IsPresent=1");
hr = CoCreateInstance(CLSID_UpdateInstaller, NULL,
CLSCTX_INPROC_SERVER, IID_IUpdateInstaller, (LPVOID*)&iInstaller);
VARIANT_BOOL Busy;
hr = iInstaller->get_IsBusy(&Busy);
etc
Basically the IsBusy property tells you if an update is in process.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa386502(v=vs.85).aspx
The discussion thread here:
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Windows-Updates-either-pending-or-running-causes-our-installs-to-fail-td7598536.html
also has a better code example. I'm not aware of a managed code interface or built-in WiX support.

WiX Toolset - Handling the case of running the installer again after it's been installed

I have a custom bootstrapper (C# WPF) and it works well enough. If the installer gets run from the command line after it was installed, it brings up a window allowing the user to select if they want to modify, repair or uninstall. So far so good. Modify mode starts the UI which ends up calling Bootstrapper.Plan(LaunchAction.Modify). The problem is that if I call it from the launcher UI it immediately complains that a prior install requires a reboot.
I have not found any good examples on what this should do. Even the WiX mailing list came up blank.
Any ideas?
It would be helpful with the screenshot for that reboot message - just to get a feel for where it might be coming from and to get a literal string to search for. Did you have a look in the WiX source code yourself btw? (WiX 3.111 branch)
I started writing a lot of stuff about reboots. Not good. Maybe just some questions instead:
Does this happen every time you invoke modify and is it reproducible on more than one computer? Or maybe it is just Windows Update acting up on a problem computer?
I assume you have rebooted the computer where you see the problem and you see the problem again when you re-launch the bundle?
Do you schedule any reboots inside your MSI files during the initial installation?
Either using the ScheduleReboot action or a custom action which schedules a reboot with a call to MsiSetMode (for example)?
There is a long explanation here why such reboot-constructs cause problems, but that may be besides the point. Essentially badly configured reboot-constructs can trigger spontaneous, unexpected reboots without warning when packages are run in silent mode (plus other problems).
Could you try to run the test VBScript found in this answer: WiX behaving badly on XP machine with windows update issues in order to check if the script reports a reboot being necessary?
Other than that I guess you could try to run Burn yourself in debug mode (not sure how much plumbing that would be to get running) or perhaps first try a ProcMon.exe session to see if you can see something obvious. The latter should be quick to do?
There are some registry locations you can hunt down to see if you can figure out what triggered the reboot warning. Get-PendingReboot-Query. And a similar PowerShell script.
So in the end it was user error. :-( O well. I did learn a lot about how to figure out how Windows checks for the need to reboot etc.
The issue was simple in the end. During the modify run it was uninstalling, then reinstalling a number of services. The problem is that when it runs (seeing as you have to set it to repair to get it to work) it copies all the files again and the services were still running at the start of the install. The fix was to uninstall anything that might lock a file before the actual file copy starts and that solved the issue for me.
Thanks for your help guys, all the info helped me look in different directions until I found the issue. Awesome community as always!

Can WiX do anything besides RollBack and Log files if installer fails? Like reboot?

I have an installer whose initial installation will be done by a human, but updates have to be done automagically.
Handling installer failure is a problem. I have to plan for the installer to fail: I use the <RollbackBoundary/> element in the Bootstrapper to get to a good state, and then I use both the WiX log and a log of my own devising to document the failure.
However, that's not good enough.
There's a program (let's call it X.exe). If-and-when the installer fails, I need to roll back to the state that the installer was in before the installer started and:
Restart X.exe or
Restart the target machine so that X.exe can start (I install X.exe into the startup folder of the target computer; this is also what I do for a successful install -- restart the target machine).
Deal with the problem in some as-yet unforeseen way.
Is there anything besides Logging that WiX can do for a installer failure? Is there a condition that is set that I could catch, or... anything?
I learned WiX through the fantastic book WiX 3.6: A Developer's Guide to Windows Installer XML (by Nick Ramirez), but I can't find anything to solve my problem there, nor can I find it on the interwebs.
I'm hoping there's something obvious I missed. Does anyone know how to deal with installer failure besides logging them and calling it a day?
Based on the lack of answers and lack of finding the answer to my question in existing resources, I realize that I'm simply asking Windows Installer to do too much.
I was hoping that there would be a way to do something like:
if (installation fails)
{
do something (besides rollback and logging)
}
I wonder if other installation programs provide functionality like this? Or if there's some other way to get a target machine to do something if the installer fails?
There is, in theory, but the whole area of rollback is fraught with caveats. Consider the "installation failed" dialog box and how it differs from a success case: you could run a custom action on that dialog box. But that's only if there's UI. So maybe do things from the rollback action. But what if Rollbacks are disabled? Your only mildly robust solution will be outside of the Windows Installer package.
So in your X.exe, make sure to capture the return code so you can identify a success, a cancelation, a failure, and various reboot required states. If it's a failure, then consider applying your external fix (your reboot, or whatever). If you didn't write X.exe, consider doing so, or writing something that will call X.exe.
But really PhilDW's comment gets to the core of it: rebooting on failure is not an expected behavior for an application installer. (Reboots by application installers in general are advised against.)

how to catch installation progress and return-value from an installer in vb.net

I'm developing a windows application (using vb.net) that can install various versions of runtimes like vc++, Direct X, .net frameworks etc on a PC. My program must be able to to run the runtime installers (msi & exe) one at a time in the background and do the following:
1.Check weather the runtime is already (previously) installed or not.
2.Show the installation progress in a progress bar in the main form of my program.
3.And at last get the return code (exit code) from the installer to indicate weather the installation was successful or not.
What are the codes required to perform the above tasks?
Also I want to know what are all the possible return codes(values) an installer can return.
All of those redistributables might have different command line options, so it's not likely to be one answer for everything.
It's not clear how you can get the installation progress. It's almost certainly impossible or very difficult. You're asking how you can run a program that will "steal" the output of some other program, and in many cases that will be Windows Installer. If I had a program that fired off a Windows Form program, then you're asking "how can I get the content of that program and steal the output messages". That's not an install question, it's a Windows messaging/windows message loop question.
The detection methods used by those setups are coded internally (or configured as internal data), so you're also asking how the code in all those programs detects that the dependency isn't installed (on multiple OS versions and 32-bit and 64-bit), and some of that might be available on the web but it's unlikely that it is readily available for every redistributable.
You might also have an issue with EULAs. Some redistributables need a EULA to be accepted and might not install unless it's accepted, or some may have a command line option that includes something like (just an example) ACCEPTEULA=1.
Basically you should:
Find the command line options available for all those redistributables to see if they have an option that displays only progress, then let them show that.
Similarly, see if they have documentation that tells you if the exit code means success or not.
Don't bother trying to find all the detection methods for everything - just run the redist, and if the target is already installed it won't do anything.
Finally, you are re-inventing the wheel. WiX, the Bootstrap Manifest Generator, InstallShield, Advanced Installer (and so on) all provide bootstrapper programs that already do this as prerequisites for installing software. Nobody writes code to do this any more because there are existing solutions.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa376931(v=vs.85).aspx
1638 for already installed. 0 for successful installation. Yet mind 3010 which stands for success but pending reboot.
About showing progress in parent window .. this may be not a trivial task. Hopefully someone else can give you a hand with that.