[英]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.