Uninstall multiple products using Custom Action

2019-03-30 08:56发布

问题:

I am developing WIX based instller for our product which is having a base product and many plug-ins. Base and plug-in will be shipped as separate MSIs. Plug-ins can be installed only when base is available. Base and plug-ins are sharing common folder tree under a ROOT folder like "C:\Program files\MyProduct".

I am using custom actions to uninstall all dependant plug-ins. But the plug-ins are not uninstalling properly. It is very random. Some times three plug-ins got uninstalled and some times only two plug-ins. But I could uninstall plug-ins separately from Add/Remove programs.

I am using following Custom actions...

<Fragment>
    <CustomAction Id='UninstallP1Action' Directory='SystemFolder' ExeCommand="[SystemFolder]MSIExec.exe /X {PRODUCT_CODE_HERE} /qn /l* $(env.windir)\Temp\p1.log" Execute='immediate' Return='asyncNoWait' />
    <CustomAction Id='UninstallP2Action' Directory='SystemFolder' ExeCommand="[SystemFolder]MSIExec.exe /X {PRODUCT_CODE_HERE} /qn /l* $(env.windir)\Temp\p2.log" Execute='immediate' Return='asyncNoWait' />
    <CustomAction Id='UninstallP3Action' Directory='SystemFolder' ExeCommand="[SystemFolder]MSIExec.exe /X {PRODUCT_CODE_HERE} /qn /l* $(env.windir)\Temp\p3.log" Execute='immediate' Return='asyncNoWait' />
    <CustomAction Id='UninstallP4Action' Directory='SystemFolder' ExeCommand="[SystemFolder]MSIExec.exe /X {PRODUCT_CODE_HERE} /qn /l* $(env.windir)\Temp\p4.log" Execute='immediate' Return='asyncNoWait' />
    <CustomAction Id='UninstallP4Action' Directory='SystemFolder' ExeCommand="[SystemFolder]MSIExec.exe /X {PRODUCT_CODE_HERE} /qn /l* $(env.windir)\Temp\p4.log" Execute='immediate' Return='asyncNoWait' />

</Fragment>

I am calling this CA in my product script like...

       <!--Uninstall Plug-ins -->
        <Custom Action='UninstallP1Action' After='InstallFinalize'>(REMOVE="ALL")</Custom>
        <Custom Action='UninstallP2Action' After='UninstallP1Action'>(REMOVE="ALL")</Custom>
        <Custom Action='UninstallP3Action' After='UninstallP2Action'>(REMOVE="ALL")</Custom>
        <Custom Action='UninstallP4Action' After='UninstallP3Action'>(REMOVE="ALL")</Custom>
        <Custom Action='UninstallP5Action' After='UninstallP4Action'>(REMOVE="ALL")</Custom>

My questions here are,

  1. How to do a clean uninstall of all plug-ins when I uninstall base?

  2. There is no logs created when the plug-in is missing from uninstall. But log created successfully when the plug-in uninstalled correctly. How to check this?

  3. I know about creating features (for different plug-ins) within single MSI. But our plan is to ship the plug-ins as separate MSIs. Any other possible way available in WiX?

Any help would be really appreciated!

回答1:

How to do a clean uninstall of all plug-ins when I uninstall base?

Your uninstall custom actions do not wait for return. So they are basically launching uninstall commands one after another without waiting for each process to finish.

Windows Installer doesn't support two InstallExecuteSequences running at the same time. So two uninstall process cannot run simultaneously. Since your launching multiple uninstall processes simultaneously, some of them fail.

A solution is using a BAT file to execute the uninstall commands. It waits for each command to finish before launching the next one. The downside is that you can't remove that BAT easily from the target machine when your uninstall is finished.

There is no logs created when the plug-in is missing from uninstall. But log created successfully when the plug-in uninstalled correctly. How to check this?

Windows Installer automatically detects conflicting install or uninstall processes. So your plugin uninstall fails before it starts writing a log.

I know about creating features (for different plug-ins) within single MSI. But our plan is to ship the plug-ins as separate MSIs. Any other possible way available in WiX?

Not really.