Shintaro Takechi
Shintaro Takechi

Reputation: 1365

Wix toolset : How can I remove a bundle if the installer in bundle is installed via separate bundle

I have 2 bundles I am dealing with.

  1. Main Bundle with Main installer + Sub installer (+ prereq) (with property, user can chose not to install Sub installer)
  2. Sub Bundle with Sub installer (+ prereq)

Contents of the sub installer are same in both bundles.

Since upgrade code are same, the contents are properly replaced. So functionality does not have issue.

I have issue where if I install sub bundle (#2), THEN install the main bundle(#1), there are 2 entries of sub installer in Add/Remove Program.

I know this is occurring because one is displaying the #2 bundle and the other entry is displaying the sub installer from #1.

But I would not want this behavior.

Is there any way to remove the bundle #2 if #1 bundle is installed afterward?

Upvotes: 0

Views: 741

Answers (2)

Sam Saarian
Sam Saarian

Reputation: 1146

I maintained a bundle uninstall for downgrade and upgrade scenarios. First, I set my Bundle object Operation property at DetectRelatedBundle event, then set the PlanRelatedBundleEventArgs (e.State) to RequestState.ForceAbsent. The code below is simplified to show only statements that is matter to the subject.

    private void OnDetectRelatedBundle(object sender, DetectRelatedBundleEventArgs e)
    {
        // [DetectRelatedBundleEventArgs e]
        // Operation
        // RelationType
        // PerMachine
        // ProductCode
        // Version
        // Result

        Bundle.Version = e.Version;
        Bundle.ProductCode = e.ProductCode;
        Bundle.Operation = e.Operation;
        Bundle.PerMachine = e.PerMachine;
        Bundle.BundleTag = e.BundleTag;
        Bundle.RelationType = e.RelationType;

        LogEvent(nameof(OnDetectRelatedBundle), e);
    }

    private void OnPlanRelatedBundle(object sender, PlanRelatedBundleEventArgs e)
    {
        // [PlanRelatedBundleEventArgs e]
        // BundleId
        // RequestState

        if (Bundle.Operation == RelatedOperation.MajorUpgrade ||
            Bundle.Operation == RelatedOperation.Downgrade)
            e.State = RequestState.ForceAbsent;

        LogEvent(nameof(OnPlanRelatedBundle), e);
    }

public abstract class BaseBundle
{
    public string Id;
    /// <summary>
    /// Installed bundle version.
    /// </summary>
    public Version Version;
    public bool PerMachine;
    /// <summary>
    /// Uninstall registry key, also cache folder name.
    /// </summary>
    public string ProductCode;
    /// <summary>
    /// Action to be applied to an existing bundle.
    /// </summary>
    public RelatedOperation Operation;
    /// <summary>
    /// Existing bundle relation type.
    /// </summary>
    public RelationType RelationType;
    /// <summary>
    /// Arbitrary string set to the bundle.
    /// </summary>
    public string BundleTag;
    public string DisplayName;
    public string UpgradeCode;
}

public class Bundle : BaseBundle
{
    public Package[] Packages;
}

The only problem I have is that, the uninstallation starts AFTER upgrade or downgrade is completed. Meaning, after upgrade or downgrade installation.

Upvotes: 0

Sean Hall
Sean Hall

Reputation: 7878

There is no built-in way for #1 bundle to uninstall #2 bundle. This is mainly because of the scenario where the Sub installer in #1 bundle would downgrade the Sub installer in #2 bundle. Installing #1 bundle in that scenario would mean that it doesn't install its version of Sub installer, so uninstalling #2 bundle would uninstall Sub installer.

If someone implemented the BundlePackage feature in 3693, this would work if the Sub Bundle was used as a BundlePackage of Main Bundle.

A custom BootstrapperApplication, along with a detect RelatedBundle element in #1 bundle for the #2 bundle, could schedule #2 bundle to be uninstalled.

Upvotes: 2

Related Questions