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.
Related
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.
The Setup
So I have a Custom Action in my InstallExecuteSequence that looks like this:
<Custom Action="UpdateConfigFile" After="InstallFinalize">NOT Installed OR Upgrading</Custom>
Where Upgrading is defined to:
<SetProperty After="SetFirstInstall" Id="Upgrading" Value="true">
WIX_UPGRADE_DETECTED AND NOT (REMOVE="ALL")
</SetProperty>
The Custom Action updates a web.config file with a value that is passed into the installer via a Property. It is a VB.Net function.
The Issue I'm Running Into
This Custom Action has always executed in many of our installers. But for a certain environment that we have in development, the conditions for it resolve to False on a install/upgrade scenario. It says "(condition is false)" in the MSI log.
The environment is used for development purposes such as testing the product after installed/updated.
What I'm Trying to Accomplish
I would like this to be resolved so that this environment can install our product successfully.
What I've Done So Far
I've installed the same installer to different Operating Systems such as Windows 10, 2012 R2, and 2016. The installer works just fine since the Custom Action runs as expected.
The troublesome environment is a Windows Server 2012 R2 machine. Which makes me even more confused.
I did some digging in and was only able to find this link: (https://blogs.msdn.microsoft.com/heaths/2006/07/11/why-a-custom-action-may-not-run/#comments)
From the link's suggestion, I think it is really odd if a dependency was missing because the same installer works on other machines.
So I'm pretty stumped at this point. Any help or direction would be very much appreciated. If I'm not being clear enough, feel free to ask for more clarification. Please and thank you.
Just some comments to get going, this isn't a real answer:
First things first: in order to be passed properly to deferred mode (InstallExecuteSequence) properties should be UPPERCASE (public properties) and they should be listed in the SecureCustomProperties delimited list of "safe properties" to pass to deferred mode.
Other than uppercasing it, I wouldn't set a property called Upgrading like that, I would rather use the "raw" conditions for the custom action in deferred mode (InstallExecuteSequence).
Here is a cheat sheet of common conditions from Flexera (makers of Installshield): Common MSI Conditions Cheat Sheet. And here is a direct link to the PDF.
You can have a look at this old post: How to add a WiX custom action that happens only on uninstall (via MSI)?. I have never had the time to test all those conditions, but at face value it looks correct.
Some notes about the special property UPGRADINGPRODUCTCODE.
UPGRADE:
Questions:
That Windows Server 2012 R2 machine - is there anything special about it? Is it tightened for security? What is its task or purpose on the network?
What is the actual implementation of UpdateConfigFile - is it a script, a compiled DLL written in C++, a managed DLL written in a .NET language, or something else? Maybe an EXE file?
Does any of this sound familiar: Installer fails on Windows Server 2012 R2
Did you verify that the correct version of the .NET framework is installed on this problem server? Does the function run interactively? Try running that VB.NET function interactively on that computer via a test harness EXE if it is a DLL function. Or just run it straight is it is an EXE file outright.
The issue is likely to be that you are scheduled after InstallFinalize (which is not good, see later) because the Upgrading property is not public (not uppercase). If you change the condition to WIX_UPGRADE_DETECTED AND NOT (REMOVE="ALL") it should work, assuming:
WIX_UPGRADE_DETECTED is the actual property associated with the major upgrade, such as from the major uypgrade element.
WIX_UPGRADE_DETECTED is in SecureCustomProperies.
Actions after InstallFinalize are generally not recommended because if they fail (in your case screw up the config file) then there is not much that can be done (such as roll back to a correct config file). It's effectively after the install, so it's also easier to do the config changes in the app when the upgraded version runs for the first time.
After helping the team responsible for the environment, we found out that it was a certain scenario that was causing this issue. Digging deep into the MSI log further, we found that a previous Custom Action running, also after InstallFinalize, was returning a Failure Action Result. Since that happened, the following Custom Actions such as my UpdateConfigFile Custom Action, don't execute. Resulting in the "(condition is false)" entry in the log.
Once we figured that out, I was able to reproduce it on my local environment.
Since these Custom Actions are after InstallFinalize, I thought that those Custom Actions would still run if one failed because we're past the point of the installer being able to do a Rollback. But I was wrong and now I know.
Thanks for everyone helping me out in trying to figure out this issue. I was getting worried that I was going to try to figure this out for days and start pulling my hair out. XD
How do I avoid triggering self-repair from my WiX generated MSI package?
This is a Q/A-style question with an answer that just list a few things not to do in your MSI file to avoid the most common causes of repeating self-repair.
Self-Repair, Simple & Short Explanation: Why does the MSI installer reconfigure if I delete a file?
General WiX / MSI Advice: This self-repair piece was
split from the original answer on general MSI problems:
How do I avoid common design flaws in my WiX / MSI deployment solution?
Short Summary
I keep trying to write about repeating MSI self-repair for developers, but end up with too much detail. Here is my last attempt: concrete design advice for what not to do in your WiX / MSI file. Other deployment specialists, please extend the "pitfall list" below.
The earlier answers I wrote turned out to be developer relevant, but not developer friendly:
How can I determine what causes repeated Windows Installer self-repair? - Focuses on understanding the self-repair problem in general. Setup developer / application packager focus.
What do I do when launching an application triggers repeating, endless Windows Installer self-repair? - Provides a checklist for solving self-repair scenarios. "How to fix focus" - rather than just understanding. For developers, sysadmins, application packagers and end users. How to handle bad MSI packages in general - from any vendor or source, not just your own.
I think there is time for yet another perspective on self-repair. Now I can finally write what I intended all along: the developer's view of self-repair - some of the pitfalls to avoid for developers who do their own setup development work - often using the WiX framework. Just a short, concrete list of things not to do in your MSI package.
MSI / WiX design pitfalls causing self-repair issues
This is a rough first-draft. These bullet points will be fleshed out when time allows.
You mess up the installation of shared runtimes. You don't use merge modules to deploy globally registered, and/or shared runtime files. Rather you install your own copies of the files and register them system-wide. This is particularly bad for COM files, but applies also to other types of files. Conflicting applications will try to put their state back, and "self-repair fighting" results on every alternate application launch.
You run into the empty folder self-repair peculiarity. You create an empty component with a directory key path without adding a CreateFolder entry. This causes an endless loop where MSI removes the folder and then triggers self-repair to put it back. There might be protection in WiX against this at this point.
Incorrect component reference counting. You create a suite of packages yourself that install a file with the same name to the same location on disk from different MSI setups using different component GUIDs. This will most likely trigger self-repair as the packages "fight" to put its version of the file in place. There are several "fixes" for this such as designing a merge module, using a WiX include file, installing the file without reference counting (blank component guid) - (more details will be added soon).
Erroneous per-user file installation. You install files to the user-profile and set a file key path instead of a registry key path in HKCU (required by MSI design guidelines). This frequently cause regular users to experience repeating self-repair that never succeeds due to missing disk permissions. The key files are not "seen" by the regular user because there is no read permission where the key file resides (another user's user-profile). Here is a color illustration. And in addition to a link, in image form as well:
Erroneous disk / registry custom permissioning. This problem is different, but similar to the previous issue. You apply custom file, folder and registry permissions during installation that removes read access to installation locations for regular users. Regular users will see repeating self-repair that never succeeds. This can happen to "per machine" file locations as well, not just user-profile paths (like the previous issue). I hear rumors that some have seen this in particular for write protected ini files as well.
You leave ref-counting enabled for temp files. For some crazy reason you decide to install a file to the tmp folder or another folder that might be cleaned up at any point. Perhaps you intend to run the file from a custom action or something. In either case you install it via a component with a component guid and a key path set, and when the file is "cleaned" from disk, your MSI file will try to put it back. This repeats every time the file is "cleaned". Since the install location is likely a per-user location, other users might not "see" the file from their login, and they experience immediate, repeating self-repair whereas you only see it when the file is "cleaned".
Malware - real and false positives. You install an unusual binary without running it through a basic virus / malware screening. It is as important to check for actual malware as it is to check for false positives (one malware scanning service to use is http://www.virustotal.com - almost 70 different scanners - pay special attention to the major vendors - obviously). So you ignore the malware check, and after deployment your product suffers false positives from several anti-virus vendors and self-repair will run in vain trying to put back the file only to have it "quarantined" again. Your customers blame you (funny how a false positive can be harder to get rid of than real malware?). The result is of course equally bad if you actually install a real virus or malware instead. The result is exactly the same - self-repair keeps running in vain. On the other hand, if the binary was infected after installation, then self-repair should serve its purpose and run once to put the clean file back in place. The major problem is that fixing a false positive is actually harder than dealing with malware (malware is of course worse for the customer if it causes data loss, but it is understood that this is out of your hands as software provider). With malware you simply tell your client to rebuild their PCs and reinstall your software, but with a false-positive you need to do something to whitelist your binary - often with several security software vendors. How do you deal with this process? As malware seems to become worse and worse and security is attempted tightened in any way possible, false positives are likely to become a major deployment problem - even more so than now. A lot of time can be wasted trying to get your binary whitelisted. And the obvious, but let's just say it out loud: don't brave this task on your own as a deployment person - this whitelisting is a huge task that requires management involvement. The problem affects everything for a software vendor: sales, development, marketing and support. As security software become more advanced and "smart" - they may start to quarantine the whole cached MSI on the system that is found in %SystemRoot%\Installer (used for maintenance installs, repair and uninstall). When this happens no self-repair will be possible - and also no uninstall (!) - unless you have access to the exact, original MSI that was used to install with. In these cases I suppose you could try some of the options listed here to get your MSI with malware or false-positives uninstalled: Why does MSI require the original .msi file to proceed with an uninstall? or section 12 here: Uninstalling an MSI file from the command line without using msiexec.
You install desktop files likely to be deleted by the user. This is a "fringe case" requiring that you have also erroneously set the key path for the installing component to a disk key path (rather than the correct HKCU path). Most of the time you put shortcuts on the desktop, and this is fine. However, if you install a data file of some sort that the user then deletes, you could see it put back by self repair when your application is launched via an advertised shortcut, or even if a advertised COM object is instantiated or a particular file type is launched.
You install advertised shortcuts to the "Startup" folder. Don't install advertised shortcuts to the "Startup" folder. It can trigger self-repair to run on every system startup without any user interaction taking place at all. Deleting the shortcut has been reported to also trigger self-repair. This is something I have never actually seen, but it makes sense.
You use a HKCU key path (or HKLM for that matter) that your application changes. Any setting you write from your MSI to the registry should generally not be modified, or worse, deleted by your application's operation. Self-repair will likely result. Only write data that the application just reads. Your application itself should always populate all default settings to HKCU, and your setup should never interfere with them. The same goes for userprofile files. They should be copied for each user from a per-machine template location. The overall moral of the story: deploy only per-machine files and settings (HKLM). Everything else should be initialized by the application: Why is it a good idea to limit deployment of files to the user-profile or HKCU when using MSI?.
Your setup writes to registry keys that are periodically overwritten by group policy. I believe I first saw this problem in relation to some IE proxy settings keys in HKCU being set using an MSI. Using an MSI to just set a few registry keys is always a bad idea for a lot of reasons. Please see this serverfault.com answer for a list of several problems: MSI package for reg deployment (recommended quick read, though it is most relevant for system administrators, but important to know about for developers). I am having trouble reproducing this problem since self-repair is triggered when key paths are missing (generally not just changed or modified). Perhaps group policy actually removed the HKCU values that were added by the MSI? We did see the problem, so this is probably what happened. The overall message: never use an MSI to just set a few registry keys, particularly if they are in HKCU. Use group policy, logon scripts, VB Scripts, PowerShell or other, more reliable measures such as having applications do it on launch (once per user).
You register a particular file / MIME association or command verb in your MSI file. Most self-repair seems to be triggered by COM registry interference between products that triggers self-repair on COM object instantiation, or the invocation of an advertised shortcut. However, you can also trigger self-repair via file / MIME associations and command verbs. In particular file associations could be registered by other applications / MSI files on the system, and this could trigger very persistent self-repair as each application tries to "steal back" the file association. Use these features sparingly in your MSI - and make sure the file associations you register really are unique. Never set a "common" file association in your MSI setup (for example jpg).
The same MSI is installed twice (or more) by mistake. This sounds strange, but it is possible in several ways actually. Self-repair might not be your biggest problem if this happens, you will see other problems too:
You forget to generate a new package GUID for your rebuilt MSI. Windows Installer then treats the two different MSI files as the same file "by definition". I believe I have seen self-repair in these cases, but you will be facing a plethora of other problems as well, all equally weird. Always auto-generate the package GUID. There is no reason for any two MSI files to have the same package GUID (unless you are testing something incredibly obscure in the Windows Installer Engine). While fully aware of the problem of duplicate GUIDs, it still happened to me many years ago using Installshield during some very hectic development. I still wonder how it actually happened - but it did. Perhaps it was an unknown bug in the tool?
A failed major upgrade can leave two versions of your setup installed at the same time. You see two entries in add/remove programs. Self-repair problems are possible in these cases, but so are a plethora of other problems. In my experience this problem is serious, but not as bad as using the same package GUID for two MSI files (previous bullet point).
I am sure there are several other ways the same product can end up being installed multiple times. Perhaps failed multi-instance transforms can cause the problem as well? I dislike that particular concept so I haven't really tried.
Some general "runner-up" self-repair related issues:
Run validation on your MSI and several of the above issues will be flagged and easily eliminated.
Never run MsiZap.exe on your developer box or any machine that you can't easily revert. In fact don't use this "tool" at all. You will often see self-repair problems when deploying on top of the "dirty state" created by the MsiZap.exe's nuking of the MSI database.
If you need to install COM shell extensions, make sure to test thoroughly when using Windows Explorer and switch between different view modes to check if self-repair kicks in. A COM object like this is essentially in continuous use, and self-repair is hence very likely (certain) if any settings are interfered with.
If you put an advertised shortcut in a feature by itself it should almost never trigger a self-repair. Key path checking is done for the feature the shortcut is in and for all its parent features (last time I checked ;-) - which was years ago).
Self-repair related answers (links for safekeeping):
What could be causing MsiInstaller to continuously reconfigure applications (EventID 1035)?
How can I determine what causes repeated Windows Installer self-repair?
Serverfault.com: How can I determine what causes repeated Windows Installer self-repair?
MSI self-repair triggered for the non-admin user when Tabctl32 was installed via merge module
Diagnosing self-healing MSI
why does windows installer start up everytime i start up visual basic 6
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.)
We have the scenario with an application with one .Net- and one VB6-client that should be deployed as a single bundle. The VB6 part on its hand contains its binaries as well as an ComPlus proxy. The proxy's installer is generated using COMAdminCatalog.ExportApplication. The three parts is bundled together with WiX Burn and uses the standard bootstrapper application. The creation of the bundle is part of an automatic build and deploy chain.
The problem is how to handle the proxy's installer in the bootstrapper.
There is no way of controlling the product- and upgrade code or version in COMAdminCatalog.ExportApplication. Thus a previous version can't be upgraded by a new. (At least I have not found a way, is there any?)
The msi generated from COMAdminCatalog.ExportApplication does not handle repair or reinstall. Will result in error and rollback of whole bundle.
Two versions of the proxy cannot be installed at the same time. Second one will result in error and rollback.
I have had some progress wrapping the complusproxy.msi in a bat script and use ExePackage instead of MsiPackage. The script begins with removing any previous version of the complusproxy. The problem with this is to get all different install/upgrade/uninstall-scenarios to work correctly.
I'm considering the option to edit the generated complusproxy.msi to get control of the upgrade code and version and add that to the build process.
It feels like I'm trying complex work arounds and it should be a correct, better way of doing it. What would be a better or good enough approach to solve it?