I have an already released MSI that has a custom action scheduled to run when UPGRADINGPRODUCTCODE is true. The action I released looks like this:
<Custom Action="DoThing" After="InstallFinalize" >
NOT REMOVE OR UPGRADINGPRODUCTCODE
</Custom>
The problem is I DON'T want it to run when my users upgrade. The action SHOULD have looked like this
<Custom Action="DoThing" After="InstallFinalize" >
NOT Installed
</Custom>
but unfortunately I didn't think this process through before I sent it out the door. So my question is what can I do? Is there any way to suppress this action in my next version's actions?
This is what patches are for. You are using WiX, so you could create a bundle that first installs the patch with the corrected condition then does the upgrade with the new MSI.
Related
When performing an installation while there is already another version installed, we need to call a custom action that makes use of an exe of the old application (prior to it being removed). The custom action is responsible for removing an old scheduled task. How would one go about doing such a thing?
You can implement this in the upgrading installer.
The basic idea is you have a deferred custom action which will run only when WIX_UPGRADE_DETECTED property exists. This is set when you use the <MajorUpgrade> wix element in your product for upgrades. Then you can schedule your custom action before RemoveExistingProducts and it will be able to remove the scheduled task.
There are some caveats to this approach.
The first caveat is that this approach limits where you can schedule RemoveExistingProducts. You must schedule "afterInstallInitialize" or later.
If you do use "afterInstallInitialize" then scheduling your custom action Before="RemoveExistingProducts" will be fine. If you schedule RemoveExistingProducts later on in the install process you will probably need to shcedule your custom action Before="InstallFiles" in case the old exe or a file it might load is replaced by the new install.
A basic implementation of this might look something like this
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A newer version of [ProductName] is already installed."/>
<CustomAction Id="CA_RemoveScheduledTask" BinaryKey="CustomActionsDLL" DllEntry="RemoveScheduledTask" Execute="deferred" Return="check" />
<InstallExecuteSequence>
<Custom Action="CA_RemoveScheduledTask" Before="RemoveExistingProducts">WIX_UPGRADE_DETECTED</Custom>
</InstallExecuteSequence>
You may also need to pass in the install location to the custom action which can be access using the session's CustomActionData property. An example of how to do this can be seen here. This is just so you have the correct path for the exe location. Usually I get the install path via a registry key search.
There are at least two approaches that could be used longer term, because it's not normal to want to run a custom in another installed product.
If this executable is needed in both installs then it's a shared resource, and the executable and the custom action could be common to both installs (perhaps in a merge module to keep sharing properly).
It seems that the condition on calling the custom action in the older install might be incorrect if it's supposed to be called sometime during an upgrade or uninstall. For example, if it should be called when it's being uninstalled as part of an upgrade then condition the call on UPGRADINGPRODUCTCODE.
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.
EDIT: My custom actions seem to be running well now, but I don't believe I changed any code. Do custom actions run in the order they appear in the wxs file or is their execution order arbitrary?
If I build my product.msi version 1.0.0 and install it, then rebuild it to be product.msi version 1.0.1 and upgrade it, the custom actions get called perfectly.
If I build my product.msi version 1.0.0 and put it into a burn installer version 1.2.0 and install it, then rebuild product.msi version 1.0.1 and put it into burn installer version 1.2.1 and upgrade it, my custom actions do not get called correctly.
Something about the burn bootstrapper is making custom actions not perform identically.
Here are my 4 custom actions. The final two are not being called when running the bootstrapper to update them.
<Custom Action='RemoveServiceWithProvidedBatch' After='InstallInitialize'>Installed</Custom>
<Custom Action='WaitForFileLocks' After='InstallInitialize'>Installed</Custom>
<Custom Action='InstallService' Before='InstallFinalize'>NOT REMOVE ~= "ALL"</Custom>
<Custom Action='MergeConfigFiles' Before='InstallFinalize'>NOT REMOVE ~= "ALL"</Custom>
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 am using wix in my installer,
I need to uninstall add-on Setup while uninstall the Main setup,
I am using the below code in Main setup wix,
<CustomAction Id="UNINSTALL_ADDON" Return="asyncNoWait" Execute="immediate" ExeCommand="msiexec.exe /x [add-onProductID] /qn” Property="add-onProductID" />
Below code in InstallExecute Table
<Custom Action="UNINSTALL_ADDON" Sequence="1282">(REMOVE="ALL")</Custom>
I am using the below property
<Property Id=" add-onProductID" Value="NULL" />
I have read the add-on Property Id from registry and pass it set to add-onProductID using CustomAction while uninstall the main setup.
This won’t help. Could you please help me to solve the issue?
You cannot install or uninstall another MSI during InstallExecuteSequence because Windows Installer doesn't support simultaneous install processes.
A solution is to make sure that your custom action is scheduled after InstallFinalize action (it's sequence is greater than InstallFinalize).