I have a custom action that meant for maintenance of installation:
<Custom Action="caPostMaintenanceConfiguration" Before="InstallFinalize">Installed AND NOT WIX_UPGRADE_DETECTED</Custom>
But this action is being executed during upgrade from original MSI during its uninstall. Is it a bug in Wix infrastructure? Is there a way to have control over that?
Assuming that the custom action is in the originally installed MSI as well as in your upgrade, then it will run during the uninstall of the older product. The condition will evaluate to true because the older product is still installed at the time you are uninstalling it, and WIX_UPGRADE_DETECTED won't be set during the uninstall.
Related
I have a vbscript to run to create backup of the already installed application.
I have added it in a custom action.
NOT Installed OR UPGRADINGPRODUCTCODE
Problem is during upgrade custom action is running twice..so i will have one more backup folder of previously installed one.
UPGRADINGPRODUCTCODE is not what you want to use. You should use NOT UPGRADINGPRODUCTCODE.
This property is set by the installer when it is running the currently installed version of the msi within the installing MSI's server context. This is what is run when you run "RemoveExistingProducts" during the upgrade. The problem you have now is that your install that you are installing has "NOT Installed" = true and "UPGRADINGPRODUCTCODE" = false. When the installer runs the previous install to remove it this install has "NOT Installed" = false but "UPGRADINGPRODUCTCODE" = true so it will run the custom action.
What I would consider setting the condition to would be
WIX_UPGRADE_DETECTED AND NOT UPGRADINGPRODUCTCODE AND NOT REMOVE~="ALL"
Here's some info on the WIX_UPGRADE_DETECTED property
So this condition will only run when the install detects a previous version and we are upgrading but will not run when we are just removing the old version and will not run when uninstalling. I would also schedule RemoveExistingProducts afterInstallInitialize so that your backup is created at the earliest point during the server context of the MSI installation before any files are removed or updated.
I have a bootstrapper (C# windows forms applications) that trigger two different msi files consecutively out of its resource. The instance transforms between the msi are 'paired' such that one instance transform from the first msi shares an UpgradeCode with one instance tranform from the second msi; these are the pairs that are installed together via the bootstrapper.
The 'core' msi (the first msi that runs) includes the MajorUpgrade element such that when a higher-versioned 'core' msi is run, all related products with a lower version are first uninstalled - this includes the secondary program installed via the second msi since it uses the same UpgradeCode and is recognized as a related product. This is the behaviour I want so that's good, but if I uninstall the 'core' msi program manually via the control panel, it only installs that one. I'd like to get it to uninstall the secondary program as well, even if I manually uninstall the 'core' one.
Do I need to write a custom function that manually calls the uninstall of the secondary msi's program with the ProductCode? E.g., as per here:
Wix - uninstall different product
Or, can I explicitly schedule RemoveExistingProducts to be run for uninstalls? Something like:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize">REMOVE</RemoveExistingProducts>
</InstallExecuteSequence>
Is that not possible because after InstallFinalize of the 'core' msi, it knows nothing about the secondary msi? Basically, I'm wondering if I can also use the RemoveExistingProducts standard action for the manual uninstall the case, like it's doing for the MajorUpgrade case.
Thanks so much in advance.
Unfortunately, the answer is no.
RemoveExistingProducts does not trigger during a maintenance operation.
You will certain lines in the log file which indicate that:
Skipping RemoveExistingProducts action: current configuration is maintenance mode or an uninstall
What you are trying to do is usually achieved by making use of a bootstrapper application.
Have you explored the bootstrapping feature of Wix called Burn?
Burn should be able to easily handle your requirement.
If using Burn is not an option for you, then i dont see any other option other than writing your own custom code to achieve this.
Hope this helps.
In one installer version of our product, I've added a custom dialog (shown by a CA using session.Message()) that asks the user if he wants to keep some of his data, at uninstall.
The CA has the condition set to REMOVE="ALL" AND NOT WIX_UPGRADE_DETECTED.
The dialog is correctly shown when doing a normal uninstall, but it also appears when removing the existing product, at a major upgrade. At that point, the installer hangs and it can only be closed from the Task Manager, resulting in an incorrect upgrade.
The installer version, containing the issue, has already been shipped.
Is there something that we can include in the next installer version (that does a major upgrade), that solves the dialog issue when removing the existing product?
The property UPGRADINGPRODUCTCODE is set in the older product as it is being uninstalled. WIX_UPGRADE_DETECTED is set in the incoming new upgrade setup when it detects.
A condition of REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE seems to be what you want, showing the dialog during unstall but not when the uninstall is because of a major upgrade.
You need to fix the cached MSI of the original version. There shouldn't be any UI during a silent installation transaction. You'll need to make a copy of the original built MSI, modify it to not execute that custom action and then recache it using msiexec /I foo.msi REINSTALL=ALL REINSTALLMODE=vomus before you can do your major uprade. Or, tell your users to do an uninstall first. This is the reason you are supposed to test your servicing strategy before you go to production. MSI is like an airplane... there is not stop or go back button. You are always moving forward and you have to plan accordingly.
I have a wix installer where we have several Custom Actions running, like the registration etc. However we only want these to run on the Install, not on the upgrade or the uninstall.
I've tried setting it to NOT Installed AND REINSTALL but that isn't working either.
Does anyone know what the correct property is when wanting to run certain apps via custom action only on Install and not on Upgrade or uninstall?
<InstallExecuteSequence>
<Custom Action="PosConfig.CustomAction" Before="StartServices"><![CDATA[NOT Installed AND NOT UPGRADINGPRODUCTCODE AND UILevel>3]]></Custom>
<Custom Action="Register.CustomAction" After="PosConfig.CustomAction">NOT Installed AND NOT UPGRADINGPRODUCTCODE </Custom>
<Custom Action="OPOSSelectorFirst.CustomAction" After="Register.CustomAction"><![CDATA[NOT Installed AND NOT UPGRADINGPRODUCTCODE AND &ProductFeature=3 AND Not OPOSDLLINSTALLED]]></Custom>
<Custom Action="OPOSSelectorUpdate.CustomAction" After="OPOSSelectorFirst.CustomAction"><![CDATA[NOT Installed AND NOT UPGRADINGPRODUCTCODE AND &ProductFeature=3 AND Not OPOSDLLINSTALLED]]></Custom>
</InstallExecuteSequence>
EDIT: Added my Custom Action Sequence.
NOT Installed AND REINSTALL can never be true at the same time. That would mean the application is not installed but is currently being re-installed. How would that work?
Schedule your custom action by using this condition instead:
NOT Installed AND NOT UPGRADINGPRODUCTCODE
This prevents it from being triggered on major upgrades.
UPGRADINGPRODUCTCODE is set during the RemoveExistingProducts action. Depending on your MajorUpgrade Schedule it may be too late. I've come to solution NOT Installed AND NOT WIX_UPGRADE_DETECTED.
I have a Wix project that I have set to allow major upgrades. I'm using WixUI_Advanced for a choice between per-user and per-machine installs. When I install and upgrade per-user everything works as expected, the installer recognizes an upgrade and there is only one entry in Programs and Features. However when I choose a per-machine install, it starts duplicating entries in Programs and Features (even when both install and upgrade are per-machine and to the same folder).
Looking at the install log file it seems that FindRelatedProducts is executing before the user gets a chance to select a per-machine install, so the installer thinks that the context has changed and won't do an upgrade. I attempted to suppress FindRelatedProducts in InstallUISequence but when I do that the installer still skips FindRelatedProducts in the InstallExecuteSequence.
What are my options at this point?
You could manually execute the FindRelatedProducts action again, after the installation context was selected. Use the MsiDoAction method. I used this approach once and it seemed to work.
A better approach would be to run your own custom action before FindRelatedProducts that would search for a previous version of the product already installed. That custom action should set ALLUSERS to either 1 or to Nothing depending on the scope of that previous version, so that FindRelatedProducts finds it and schedules its upgrade. A good idea would then be to disallow selecting the per-user scope for the user if the previous version was installed per-machine - otherwise the installer may have insufficient privileges to upgrade the previous per-machine installation.
This seems to be the approach taken by InstallShield. If you create an empty test MSI package with the free InstallShield Limited Edition and then de-compile it with Dark, you will see that that custom action is called IsSetAllUsers and located in SetAllUsers.dll.