WiX - Allowing a *manual* uninstall of one msi to uninstall another msi that shares the same UpgradeCode (and not just during the MajorUpgrade)
Asked Answered
S

1

1

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.

Sumerlin answered 22/7, 2015 at 21:47 Comment(0)
P
0

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.

Pinchhit answered 23/7, 2015 at 6:6 Comment(6)
Hi Kiran, I have looked into Burn and considered using it, but decided to just use the legacy C# custom bootstrapper we already have in place because of its environmental setup procedures. It doesn't seem too difficult to write the custom action for the uninstall of the secondary msi though, as long as I get its ProductCode out of the registry. I will do that instead. Thanks so much for your help!Sumerlin
Just make sure that you make use of standard windows installer API's to retrieve the product code, instead of querying the registry. msdn.microsoft.com/en-us/library/aa370130(v=vs.85).aspxPinchhit
Hi Kiran, I did want to use the MsiGetProductCode method in the API but there were some complications as both the first MSI and the second MSI have multiple instance transforms defined - it was bit difficult to get a component id unique to just one particular instance transform. Even when I had put in a condition such that a component is only installed for only 1 instance transform, the MsiProductCode method seemed to detect it in all the instance transforms installed and sometimes returned the product code of another instance transform installed by the 2nd msi.Sumerlin
The first msi and the second msi are essentially paired by a shared UpgradeCode though, and that is unique between all the msi installer pairs - is it possible to use that somehow to evoke the MsiGetProductCode? Like use it as a component id somewhere? [For now, I am querying the registry for a remaining product under the same UpgradeCode instead of using the API method.]Sumerlin
You will know the ProductCode of the msi package where you are executing your custom action. In your custom action, first retrieve the ProductCode of the currently executing msi package, make use of the API MsiEnumRelatedProducts() and then do the uninstall. Does this sound feasible to you?MsiEnumRelatedProducts() makes use of the UpgradeCode and returns you a list of all the products which share the same UpgradeCode. You can always make sure to uninstall the msi package which does not have the same product code as the currently executing package. Hope this helpsPinchhit
Ohh, yes, I think that definitely sounds feasible - right, I had missed the MsiEnumRelatedProducts() function in the API. I will give that a shot, thank you so much!Sumerlin

© 2022 - 2024 — McMap. All rights reserved.