繁体   English   中英

如何使用自定义引导程序执行Wix升级

[英]How to perform Wix Upgrade with custom bootstrapper

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

MSI中的MajorUpgrade标签如下所示:

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

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

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:

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实例(一个正在执行安装的实例)知道旧软件包的卸载已完成? 现在发生的事情是它能够成功卸载旧软件包,但是没有执行新版本的安装。

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

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

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

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

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);
    }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM