What are the phases that are executed during an msi upgrade? - wix

I am looking for the exact list of operations that are executed during an upgrade of an msi file, in terms of Wix standard actions (StartServices, RemoveFiles etc.).
I am asking because I want to insert to my wxs file some custom actions, and I need to know how to schedule them.
Thanks in advance,
Eitan

This is a very detailed discussion. In general realize that during any given transaction (install, uninstall, repair, maintenance (feature install/uninstall), upgrade (major and minor) that any given component could be getting installed, reinstalled or removed. Depending on the nature of the component, operations could be scheduled (immeadiate) and executed (deferred). This means that one or more of the standard actions you mentioned could be doing something. In the case of a rollback they could be undoing something also.
I would start here:
Installation Phases and In-Script Execution Options for Custom Actions in Windows Installer
Zataoca: Custom actions are (generally) an admission of failure.
Zataoca: Custom actions should be data driven
Data Driven Managed Custom Actions made easy with DTF
Beam Me Up: Using JSON to serialize CustomActionData
It's a lot to cover but if you want to do it properly you want to write one or more custom tables to describe what needs to be done and have a join to the Component table to drive "when" it happens. The custom actions then implement "how" it happens. A custom action to query the tables and evaluate the component states to pass data to multiple custom actions to perform the work, rollback the work and dispose (commit) of any artifacts that were saved off to support rollback or weren't safe to perform until the very end of the install (assuming rollback wasn't disabled).

Related

Uninstall from Control Panel is different from Remove from .msi

Is there a difference between uninstalling an application with WiX based .msi from Control Panel and from the .msi itself?
If there is what is it?
I am asking because of the following reason:
The difference is the following: my .msi stores some files in %PROGRAMDATA%. If i uninstall from Control Panel the files there get uninstalled (it seems that the .msi keeps track of those (they are defined as components)), but when I open my .msi and try to uninstall (I have a maintenance dialog) those files don't get deleted.
Another difference is: I also have a Custom Action to stop my Application if it is running which is being called After="AppSearch" in the InstallUISequence and Before="CostFinalize" in the InstallExecuteSequence but when removing from the .msi it isn't being called. Only a dialog shows that says that there are files to be deleted but are being usedbut some processes and when I tell it to stop them it doesn't do so.
The following "discussion" got a little out of hand. But I will leave it here as an explanation for people who research differences experienced between silent mode and interactive mode installs.
Yes, the short answer is that you can indeed see different installation or uninstallation behavior depending on how you invoke the (un)install.
This has mostly to do with how an MSI can run with different user interface levels, and this causes the entire user interface sequence (InstallUISequence) in the MSI to either be run or skipped entirely (silent installation). Once skipped, all custom actions defined only in the InstallUISequence will not run at all. If the MSI is well-designed, this is not a problem since user interface custom actions run in immediate mode and should never make changes to the system - they should just inquire for user data and settings, system state or help the user enter proper data for the installation. If the MSI is not well designed and changes are made to the system in the user interface, the installation will be incomplete when running in silent mode. This is a serious MSI design error which becomes all the more serious when you realized that all major corporations deploy software silently. I have seen such errors many times when doing corporate application repackaging. It is not a vote of confidence for the software, no matter how good it is. Weird and unpredictable problems are bound to surface.
Accordingly, the InstallExecuteSequence (which is the only one that runs when the setup is installed silently) should have all required custom actions that make system changes inserted there for an MSI to be correctly designed. As already stated, custom actions existing only in the user interface sequence should deal with getting values and settings from the user, whereas these values should be set and defined by command line or defined in transforms for a silent install.
Certain odd and erroneous combinations of custom action conditions can also cause differences between interactive and silent installs in special circumstances. And finally putting custom actions after InstallFinalize in the InstallExecuteSequence can cause actions to fail when run silently. There are certainly other potential problems as well.
In summary, if you do see a difference in installation behavior based on the user interface level, your MSI contains a serious design-flaw. You should always ensure that your MSI can be run silently with the equivalent result as interactively. And as already stated large corporations never run installations interactively since they push out software via software management systems such as SCCM.
There are 4 MSI UI levels ranging from fully silent to fully interactive:
INSTALLUILEVEL_NONE = 2, (totally silent)
INSTALLUILEVEL_BASIC = 3, (progress bars and simple error handling)
INSTALLUILEVEL_REDUCED = 4, (authored UI, no wizards)
INSTALLUILEVEL_FULL = 5 (full UI)
The important point is that for UILevel 2 and 3 the InstallUISequence is skipped.
There is an MSI property UILevel holding the GUI level value 2, 3, 4 or 5. Check this property if your custom action must take the user interface type into account. This is obviously most important for totally silent installs that should never show any dialogs.
When you right click an MSI and select uninstall you are generally running UILevel 3 (Basic UI with progress bar). This means the InstallUISequence is skipped.
When you uninstall from Add/Remove programs the normal UILevel is also 3 - basic user interface. This means the InstallUISequence is also skipped.
If you double-click the MSI and run uninstall, your GUI level is 5 - full GUI. The same happens if you select "Change" in add/remove programs.
In summary, it is possible for bugs to occur in only one of the modes (silent / non-silent) because the MSI's user interface sequence is skipped along with all its custom actions for certain user interface levels. In other words, a product could work when installed interactively and fail when installing silently (or vice versa), if the MSI is badly designed.
It is also possible to condition custom actions in the main MSI installation sequence erronously based on this UILevel feature so that results differ based on installation mode. I have seen people spawn dialogs from code in custom actions placed in the main installation sequence (where no interactivity is allowed) and then use UILevel checks to suppress the dialog in silent installation mode (or they forget that as well, triggering a hidden modal dialog that stops the install dead when running in silent mode). These weird design constructs cause unexpected installation behavior based on how the install is triggered and run.
Though this is sort of not an answer to what you asked, a final conclusion from all of this is that if your software is intended for large corporations you should not waste your design efforts on an advanced GUI for your setup as it is likely never to be used for large-scale deployment scenarios. Rather you should parameterize your installer with public properties that can be set at the command line or via a transform so that your installer can be controlled easily without running it interactively. See this post: How to make better use of MSI files.
Since I have gone so far beyond your question, I should also note that some advanced installers intended for server installations may (with moderation) benefit from a good GUI to help people quickly get your server software installed and tested. These installers tend to meddle with very advanced features such as IIS, MS SQL, AD, etc... and some interactivity could be desired for knowledgeable system administrators. But as the saying goes "most things can default" and good default settings are generally easier for people to get installed and tested whether knowledgeable or not. Many large companies run large farms of server virtuals these days (one virtual server per use case), so even server installs tend to get automated for large-scale rollout and then a good parameterized installer with public properties to set is appreciated. Smaller companies may also have server virtuals (making testing easy), but they are likely to install your setup interactively accepting whatever defaults are there - at least that is my impression.
Links:
Is it possible to passively install an .EXE but still show the GUI using Powershell?
There is no practical difference between right-clicking an MSI to uninstall it, and using Control panel to uninstall it. Both result in a minimal UI (not totally silent, shows progress bar) uninstall, and will ask for elevation if required.
If you have a maintenance mode dialog in your setup then you may have a slightly different path - you may show a dialog that offers to change features, repair, or uninstall. That might result in a difference somewhere.
If there is some code somewhere that alters something, then who knows? An uninstall from a dialog might choose to suppress the Cancel button, as a random example.

Rollback event if setup fails

I have custom action scheduled after InstallFinalize. When I run a setup, and it fails, I noticed that I get error screen that setup failed and no changes were done to my computer, but if I run setup again, it has options to repair, change or remove. I assume that it's because the rollback event isn't triggered. How can I make it happen?
The InstallFinalize action is when the installation transaction is committed to the machine. Anything that happens after that point (or before InstallInitialize) happen outside the transaction. That means they cannot be rolled back.
Instead, you'll need to schedule your custom action sometime after InstallInitialize and before InstallFinalize in order for it to error and cause rollback. Additionally, a custom action that modifies machine state should be deferred. This topic in the MSI SDK is a good place to start and then read topics around it.
If you'd like to see examples of the way to write custom actions, I'd recommend looking at some examples in the WiX toolset in src\ca\wixca\dll. Lots of different kinds of custom actions doing things in a way I hope is "correct" according to the MSI SDK.

Elevated Immediate Custom Actions

I have a request that I know many will shout about but I don't have any other way around it. In my WIX setup I have a dialog that uses the properties set in the setup to determine a product name(with version type etc) that ties in with our algorithm and a lock code that needs to be produced. Based on these the user enters their unlock key and the custom action pulls the details from all three text boxes to ensure it is correct. I did not write the algorithm for creating these and unfortunately can't change it.
My issue is that I need to be able to create a product key in the registry before this dialog so that my lock code algorithm can read from it. So basically I need my custom actions to be elevated. I read somewhere that someone implemented a custom action to call msiexec but now I cannot find it and don't know how to go about creating this. Has anyone ever had the same issues? I have been reading that people have but I can't seem to find their solution or even if there is one. Thanks in advance
Immediate custom actions CANNOT be elevated. Period, end of story. #FACT
What can you do?
1) Use a setup.exe bootstrapper that is manifested to require admin and a Launch Condition in the MSI that enforces it was launched by the bootstrapper. ( Bootstrapper passes a property to the MSI SETUPEXEDRIVEN=1 is what InstallShield calls it. ) This ensures that the entire UI sequence is elevated. (Not a best practice but I'm putting it out there for you.)
2) Write to HKCU instead of HKLM ( will likely require license code to be refactored but hey it was a broken design anyways. )
3) Refactor the installers interface to the license API. I've done this before. I once worked for a company that expected the installer to call an EXE to validate a license. One big problem is the EXE is out of process and cannot communicate back to the installer. So they started writing "ISVALID" to the registry and I was then expected to write a VBScript around the EXE to flush the value, call the exe and then check the value and set the MSI property. Ummmm can you say #FAIL? The optimal solution was to force the dev team to create an API for the license code that I could call directly from a standard MSI custom action that didn't require elevated permissions or any other hackery.

show dialog during uninstallation using UIRef wixUI_InstallDir [duplicate]

I want to add customized dialog box for uninstallation of my application.
I have also tried the following:
<InstallUISequence>
<Show Dialog="RemoveDlg" OnExit="success">REMOVE="ALL"</Show>
</InstallUISequence>
Is it possible or not in wix? Can anyone help me out with this?
While you can certainly author dialogs that are specific to product removal, uninstallations started from the remove button in Add or Remove Programs (now Programs and Features) are run without the UI sequence, and thus will not show these dialogs. One common alternative is to set the ARPNOREMOVE property which then requires the end user to click Modify instead of Remove. The modify button starts maintenance, which does show your UI.
Unless the data in %appdata%\product\ can cause problems for a re-installation of the application I would recommend leaving it in place on uninstall. Whatever you install in this folder is considered user data, and should not be automatically removed by default - and often not as an option either. Many companies apply custom permissioning on the userprofile folders. Messing around in there could cause your MSI to hickup seriously - particularly on terminal servers by triggering self-repair (which is generally not allowed on TS).
Keep in mind that the same installation sequence is used for install, uninstall and patching. If you use major upgrade patches that essentially uninstall and reinstall the product you could end up deleting the user data and reinstalling it for every installation. If this is acceptable, the data you deal with is not user data, and is hence located in the wrong place on disk.
If you run a delete operation towards the end of the uninstall via a custom action that checks exit code, you could trigger rollback of the uninstall, essentially causing the product to be reinstalled and be impossible to uninstall! Rare, but it happens. If the custom action is run after InstallFinalize and hence outside the MSI install sequence your setup could return an uninstall error code and leave your product broken and the uninstall incomplete or your product partially unregistered.
In short I wouldn't mess around with this. If you have insistent customers I wouldn't mess with a dialog if I could help it. I would add a PUBLIC property to control whether a custom action is run immediately prior to InstallFinalize. Flush any error return codes and write information into the MSI log instead. Then users could uninstall user data by specifying the property on the command line or hard code it in the Property table.
If you have to have a GUI you can use the same property to set from a custom dialog to control whether deletion is done or not. Remember to condition the display of the dialog with care. I.E don't show it during patching operations.

Is it possible to add dialog box for uninstallation in wix?

I want to add customized dialog box for uninstallation of my application.
I have also tried the following:
<InstallUISequence>
<Show Dialog="RemoveDlg" OnExit="success">REMOVE="ALL"</Show>
</InstallUISequence>
Is it possible or not in wix? Can anyone help me out with this?
While you can certainly author dialogs that are specific to product removal, uninstallations started from the remove button in Add or Remove Programs (now Programs and Features) are run without the UI sequence, and thus will not show these dialogs. One common alternative is to set the ARPNOREMOVE property which then requires the end user to click Modify instead of Remove. The modify button starts maintenance, which does show your UI.
Unless the data in %appdata%\product\ can cause problems for a re-installation of the application I would recommend leaving it in place on uninstall. Whatever you install in this folder is considered user data, and should not be automatically removed by default - and often not as an option either. Many companies apply custom permissioning on the userprofile folders. Messing around in there could cause your MSI to hickup seriously - particularly on terminal servers by triggering self-repair (which is generally not allowed on TS).
Keep in mind that the same installation sequence is used for install, uninstall and patching. If you use major upgrade patches that essentially uninstall and reinstall the product you could end up deleting the user data and reinstalling it for every installation. If this is acceptable, the data you deal with is not user data, and is hence located in the wrong place on disk.
If you run a delete operation towards the end of the uninstall via a custom action that checks exit code, you could trigger rollback of the uninstall, essentially causing the product to be reinstalled and be impossible to uninstall! Rare, but it happens. If the custom action is run after InstallFinalize and hence outside the MSI install sequence your setup could return an uninstall error code and leave your product broken and the uninstall incomplete or your product partially unregistered.
In short I wouldn't mess around with this. If you have insistent customers I wouldn't mess with a dialog if I could help it. I would add a PUBLIC property to control whether a custom action is run immediately prior to InstallFinalize. Flush any error return codes and write information into the MSI log instead. Then users could uninstall user data by specifying the property on the command line or hard code it in the Property table.
If you have to have a GUI you can use the same property to set from a custom dialog to control whether deletion is done or not. Remember to condition the display of the dialog with care. I.E don't show it during patching operations.