Can we apply transform(.mst) while uninstallation? - wix

We found some uninstallation issue on already released msi which is creating issue during upgrade of higher version.I need to modify few custom action conditions so that it doesn't run while msi uninstallation. In order to this, transform file is generated with updated condition. However, I am not sure how to pass this during uninstallation? user can trigger uninstall from Add or Remove Programs.
Minor upgrades are not option for us as it requires release of new msi.

The locally cached MSI within the Windows folder is a transformed version of your original MSI database, if you installed it together with the MST.
Your custom actions added by MST, if they have no condition set, are always run (on install, repair and removal).
If you want to run your action only on uninstallation, set this as the condition: REMOVE="ALL" or inverted NOT REMOVE="ALL" if it should NOT run on uninstallation.
Try to place your custom action in the Table InstallExecuteSequence between InstllValidate and InstallInitialize or after InstallFinalize
You don't need the MST during uninstallation.

Related

Making changes to installed MSI

I will try to explain the issue by example. I have mypackage-v1.0.msi and mypackage-v1.1.msi. Both packages when installed silently expecting PASSWORD parameter:
msiexec /i mypackage-v1.0.msi /qb PASSWORD=SomeThing1
mypackage-v1.0.msi is already installed and mypackage-v1.1.msi should upgrade mypackage-v1.0.msi. There is a custom action in both packages that depends on this parameter but because of the issue with conditioning this custom action in mypackage-v1.0.msi, during upgrade it is executed but the PASSWORD parameter is not transferred to it.
I wonder if there is a way to patch mypackage-v1.0.msi before upgrading to mypackage-v1.1.msi. But the patch is not changing any contents of installation but the package itself. Is it possible?
Edit:
More focused input - is it possible with the patch to replace a condition for InstallExecuteSequence custom actions?
Yes. Patches include transforms, which modify packages. In fact, patches always modify tables in the package, even when they don't change content of the payload files.
The comments above became too messy. Here is a quick re-write as a regular answer:
Minor Upgrade: A minor upgrade can change most things in an installed MSI package before its uninstall or upgrade sequence is called. It can hence fix problems relating to major upgrades or failed uninstalls among other things (you fix the uninstall sequence before it is invoked).
Sample: Here is the simplest sample of a minor upgrade I could find at the moment (another sample from FireGiant's documentation).
For the simple sample: open the CreatePatch.cmd and update path to WiX binaries (likely ending in v3.11 at this point in time: set wixDir="C:\Program Files (x86)\WiX Toolset v3.11\bin\").
Keep in mind that a minor upgrade has many limitations. Keep things simple and change only what you need to fix your problem.
Minor Upgrade Details: The table at the bottom here shows what needs to change for a minor upgrade. Essentially package code and product version + plus whatever change you want to implement. The above link is to InstallShield's documentation (a different MSI tool), but this is a generic MSI technology concept - it is not vendor specific.
You can deliver the minor upgrade as a new MSI or as a patch file (*.msp). For an MSI you need to use a special command line to install. Something like this:
msiexec.exe /i MySetup.msi REINSTALLMODE=vomus REINSTALL=ALL
The v tells msiexec to re-cache the MSI so that it updates the existing cached one "in-place".
REINSTALLMODE documentation.
Applying Small Updates by Reinstalling the Product.
Links:
https://support.firegiant.com/hc/en-us/articles/230912367-Upgrade-options
https://www.firegiant.com/wix/tutorial/upgrades-and-modularization/

WIX upgrade scenario

I have an existing WIX installer file that I'm trying to figure out. In this file I see two custom actions defined:
<Custom Action="CreateBackup" Before="InstallInitialize">
<![CDATA[Installed]]>
</Custom>
<Custom Action="RestoreBackup" After= "InstallFinalize">
<![CDATA[NOT Installed]]>
</Custom>
The CreateBackup function copies some files (not directly related to this installer) from a remote location. Restore puts those files back at the same location.
Now in an upgrade scenario I see the following logging order. I have put the apparent value of "Installed" in brackets:
CreateBackup is skipped (Installed == false)
InstallInit
CreateBackup succeeds (Installed == true)
InstallInit
InstallFinalize
RestoreBackup is skipped (Installed == true)
InstallFinalize
RestoreBackup succeeds (Installed == false)
I have a couple of questions about this:
I understand that there is an uninstall and an install going in this script. And based on the value of "Installed" I conclude that the install is done first. Is this correct?
I see that the InstallInit is called twice before the first InstallFinalize. What does this mean? Is the installation still busy when uninstall begins?
The first value of Installed is false, so I guess it is relative to the new version? But how does it become false again after the deinstallation finishes? Is it relative to the old version then?
I am using an MajorUpgrade element.
Hope someone can clear this up.
I'm assuming that you are using a WiX MajorUpgrade element to do your upgrade, so the conditions you need should be something like this:
When you are doing an upgrade the WIX_UPGRADE_DETECTED property is set when an upgrade is being done:
http://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html
So use that condition when you want to create the backup, assuming that you want to do the backup of existing files (from the older product) when doing the upgrade.
It's not clear from your post exactly when you want to do the restore but if it's after the upgrade then use the same WIX_UPGRADE_DETECTED property.
Those conditions based on the Installed property don't seem to make a lot of sense because the property is set if the current MSI's ProductCode is installed. In a upgrade at that stage it will always be unset.
This post has more info about properties and install actions:
How to add a WiX custom action that happens only on uninstall (via MSI)?

wix pass option to msi for repair

When I repair using the msi, a registry entry is properly re-created. When using the exe generated by Burn, the entry is not-recreated, unless the exe associated with the reg entry also requires compare.
I wonder if, when burn invokes msi, if it is overriding the default /fm behavior of msiexec.
That switch means "repair all required computer-specific registry entries "
Is there any way I can confirm, deny, or modify that behavior?
When planning a "Repair" operation in Burn the REINSTALLMODE is "cmuse". For a "Modify" operation the REINSTALLMODE is "cmuso". So "m" is present in both cases.
The Burn log file should say, "Planning action: Action" and that will tell you which it is doing. If you are executing a Repair operation and there is not newer version of the executable on the machine than what your MSI expects, Burn's REINSTALLMODE should work. If you are doing a "Repair", look in the generated MSI log file for the same Burn execution and see what the Component states are for the Components that are not repaired. That should help you track back to see why the Component was not fixed.
From the provided log file:
Command Line: ARPSYSTEMCOMPONENT=1 MSIFASTINSTALL=7 REINSTALLMODE=cmuse
REBOOT=ReallySuppress IGNOREDEPENDENCIES=ALL CURRENTDIRECTORY=C:\temp
CLIENTUILEVEL=3 MSICLIENTUSESEXTERNALUI=1
The lack of REINSTALL=ALL shows that EnableFeatureSelection='yes'. Either remove that attribute (or change it to the default 'no') or your BA needs to handle the OnPlanMsiFeature() callback

How to execute Custom Action before RemoveExistingProducts with After="InstallValidate" in WiX

I have something like this:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
Since one of the uninstallation fails i need to execute a Custom Action to solve the problem BEFORE RemoveExistingProducts. Something in the lines of:
<CustomAction Id="FixStuff" .. />
<InstallExecuteSequence>
<Custom Action="FixStuff" Before="RemoveExistingProducts" />
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
This of course doesn't work since Custom Action cannot be before InstallInitialize. I'd really like to remove existing products between InstallValidate and InstallInitialize, but i'd like to execute FixStuff before removing existing products.
Is it even possible to do that?
Unfortunately you cannot run an elevated custom action before RemoveExistingProducts with your current configuration.
Some possible approaches would be:
Move RemoveExistingProducts right before InstallFinalize. This solves the custom action problem, but other problems may occur since this approach has many restrictions (the components need to maintain their names and GUIDs between versions, your custom actions should be aware that the upgrade is performed at installation end etc.).
Create an EXE bootstrapper which fixes the old installer before launching the new MSI. This bootrapper can require Administrator privileges through a manifest:
http://msdn.microsoft.com/en-us/library/bb756929.aspx
Repair the broken MSI by using this method:
fix the problem in the old MSI
create a BAT or EXE bootstrapper which recaches it through this command:
msiexec /fv <path_to_msi>
distribute this MSI as an update before your new package
When your new package runs RemoveExistingProducts, the old cached MSI should be fixed and it should uninstall correctly.

How can I execute a Custom Action as System user with Wix 3.0, before checking to see if files are in use?

So I have a Wix 3.0 project that installs an IIS7 Native Code Module. When uninstalling I would like to be able to shut down the IIS7 application pools before deleting the file so that a reboot is not necessary.
I am using the appcmd utility to shut down the app pools in a CustomAction element, but when I attempt to do an uninstall I get this error before the customaction is ever invoked:
The setup must update files or
services that cannot be updated while
the system is running. If you choose
to continue, a reboot will be required
to complete the setup.
I have the "After='InstallInitialize'" property set on the CustomAction, because the documentation says that any deferred/not-impersonated custom action must come between InstallInitialize and InstallFinalize.
So is there some way to have a custom action execute before this check for files in use is made? Or disable this check for a given file, or make the check happen later in the sequence?
Yes, you can specify the order for actions to occur by modifying the Sequence column in the InstallExecuteSequence table within the MSI file.
Get the ORCA tool to examine the MSI file to see what I mean, and use a Javascript script to modify the MSI as appropriate.