如何使用自定义引导程序执行Wix升级 [英] How to perform Wix Upgrade with custom bootstrapper

查看:89
本文介绍了如何使用自定义引导程序执行Wix升级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我们的WiX定制BA安装程序的第二版中启用升级.在我的Product.wxs中,产品ID设置为*,版本设置为2.0.0,升级代码与第一个版本相同.为了检测升级,我在Boostrapper中使用了DetectRelatedBundle事件处理程序.

I want to enable Upgrade in the 2nd version of our WiX custom BA installer. In my Product.wxs, Product ID is set to *, version is set to 2.0.0, and upgrade code remains the same as the 1st version's. To detect Upgrade, I used DetectRelatedBundle event handler in the Boostrapper.

MSI中的MajorUpgrade标记如下:

The MajorUpgrade tag in the MSI looks like this:

<MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="A newer version of [ProductName] is already installed." AllowSameVersionUpgrades="no" Schedule="afterInstallInitialize" />

在安装程序用户界面中,我有一个安装"按钮.在升级"方案中单击此按钮时,我将调用PlanAction并传递LaunchAction.Install.但是一旦安装开始,它将显示BA的另一个实例,我相信这是我当前BA调用的用于卸载旧版本的旧软件包.为了隐藏新的BA实例并仅显示安装进度,我在Bootstrapper中进行了以下更改:

In my installer UI, I have an Install button. When this button is clicked during Upgrade scenario, I call PlanAction and pass LaunchAction.Install. But once installation starts, it shows another instance of BA, which I believe is the old package called by my current BA to uninstall the old version. In order to hide the new BA instance and just show installation progress, I made these changes in my Bootstrapper:

Bootstrapper.cs:

Bootstrapper.cs:

protected override void Run()
{
    BootstrapperDispatcher = Dispatcher.CurrentDispatcher;

    try
    {
        _model = new BootstrapperApplicationModel(this);

        var uninstall = new UpgradeUninstall(_model);
        if (uninstall.IsUpgradeUninstallation())
        {
            uninstall.PerformSequence();
        }
        else
        {
            //show install or uninstall main UI

            this.WireUpEventHandlers();
            _model.BootstrapperApplication.Engine.Detect();
            Dispatcher.Run();
        }
    }
}

UpgradeUninstall.cs:

UpgradeUninstall.cs:

public class UpgradeUninstall
{
    private BootstrapperApplicationModel _bootStrapperModel;

    public UpgradeUninstall(BootstrapperApplicationModel model)
    {
        _bootStrapperModel = model;
    }       

    public void Perform()
    {
        this.WireUpEventHandlers();
        _bootStrapperModel.BootstrapperApplication.Engine.Detect();
    }

    public bool IsUpgradeUninstallation()
    {
        var action = _bootStrapperModel.BootstrapperApplication.Command.Action;
        var display = _bootStrapperModel.BootstrapperApplication.Command.Display;

        return action == LaunchAction.Uninstall && (display == Display.None || display == Display.Embedded);
    }

    private void WireUpEventHandlers()
    {
        _bootStrapperModel.BootstrapperApplication.DetectComplete += OnDetectComplete;
        _bootStrapperModel.BootstrapperApplication.PlanComplete += OnPlanComplete;
        _bootStrapperModel.BootstrapperApplication.ApplyComplete += OnApplyComplete;
    }

    private void OnDetectComplete(object sender, DetectCompleteEventArgs e)
    {
        this._bootStrapperModel.PlanAction(LaunchAction.Uninstall);
    }

    private void OnPlanComplete(object sender, PlanCompleteEventArgs e)
    {
        this._bootStrapperModel.ApplyAction();
    }

    private void OnApplyComplete(object sender, ApplyCompleteEventArgs e)
    {
        BootstrapperDispatcher.InvokeShutdown();
    }
}

问题1)我如何让我的主要BA实例(一个正在执行安装的实例)知道旧软件包的卸载已完成?现在发生的事情是它能够成功卸载旧软件包,但是没有执行新版本的安装.

Question 1) How will I let my main BA instance (the one doing installation) know that uninstallation of old package has completed? What's happening now is that it was able to successfully uninstall the old package, but no installation of the new version is being performed.

问题2)我对WiX升级的理解正确吗?:)

Question 2) Is my understanding of WiX upgrade correct? :)

推荐答案

正在发生的事情是您的旧BA正在使用卸载开关以静默方式被调用.我看不到您的代码确实可以处理一些命令行卸载,尽管我看不到您在哪里调用Engine.Plan(LaunchAction.Uninstall).

What is happening is your old BA is getting called in silent mode with the uninstall switch. I can see your code does have some of the plumbing to handle a command line uninstall although I can't see where you're calling Engine.Plan(LaunchAction.Uninstall).

Q1)我不认为您需要做任何特别的事情来让您的原始BA知道您已经完成.您只需要以正常方式退出安装即可.

Q1) I don't believe you have to do anything in particular to let your original BA know you're finished. You just need to exit the install in the normal way.

Q2)是的,我认为您快到了.我建议您从git下载WIX源代码,以了解它如何实现其自定义BA.具体看一下DetectComplete代码:

Q2) Yes I think you're almost there. I suggest you download the WIX source code off git to see how it implements its custom BA. Specifically look at the DetectComplete code:

private void DetectComplete(object sender, DetectCompleteEventArgs e)
{
    // Parse the command line string before any planning.
    this.ParseCommandLine();
    this.root.InstallState = InstallationState.Waiting;

    if (LaunchAction.Uninstall == WixBA.Model.Command.Action)
    {
        WixBA.Model.Engine.Log(LogLevel.Verbose, "Invoking automatic plan for uninstall");
        WixBA.Plan(LaunchAction.Uninstall);
    }

您可以看到它正在检查卸载命令行选项,并立即开始卸载.

You can see it is checking for the uninstall command line option and immediately kicking off an uninstall.

这篇关于如何使用自定义引导程序执行Wix升级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆