我想在我们的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升级的理解是否正确? :)
答案 0 :(得分:0)
正在发生的事情是您的旧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);
}
您可以看到它正在检查卸载命令行选项,并立即开始卸载。