Skip to content

PlanPhase Class

Richard Martin edited this page Mar 25, 2024 · 2 revisions

Bootstrapper.Phases.PlanPhase

The sample code doesn't do much during the plan phase.

OnPlanComplete method

When planning completes, we first check to see if it failed because it was cancelled. When the user cancels, the AppState.CancelRequested property is set to true. But this is only a request that gets honored later. It's not safe to check the value of this when plan or apply phases complete, since the phases may have completed successfully before this value is checked. When the install is cancelled, WiX's BootstrapperApplication.Error event could get triggered. In the handler for this event, we set the AppState.BaStatus property to BaStatus.Cancelled. We can check the value of this property. But it's also possible for Windows Installer to return an HRESULT of ERROR_INSTALL_USEREXIT. So, we also need to check the HRESULT.

Either way, we want to ensure BaStatus is set to Cancelled so the UI will know why the plan failed.

if (_model.State.BaStatus == BaStatus.Cancelled || e.Status == ErrorHelper.CancelHResult)
{

    ...


    _model.State.BaStatus = BaStatus.Cancelled;
}

After checking for cancellation, we want to check HRESULT for an error like we do when completing any phase. If the plan failed, we want to shut the app down if it's running silently.

if (ErrorHelper.HResultIsFailure(e.Status))
{
    _model.State.BaStatus = BaStatus.Failed;
    var msg = $"Plan failed - {ErrorHelper.HResultToMessage(e.Status)}";
    
    if (string.IsNullOrEmpty(_model.State.ErrorMessage))
        _model.State.ErrorMessage = msg;

    if (!_model.UiFacade.IsUiShown)
        _model.UiFacade.ShutDown();
}

If everything looks good, we want to start the apply phase. Starting with WiX 4, a valid window handle is required even when not displayed, so we'll supply that.

_model.Engine.Apply(_model.UiFacade.ShellWindowHandle);

Previous: DetectPhase Class || Next: ApplyPhase Class

Clone this wiki locally