Skip to content

CancelHandler Class

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

Bootstrapper.Phases.CancelHandler

Cancellation is handled by setting the event argument's Cancel property to 'true' in WiX events that support this property. If this is done, Windows Installer will roll back the install as needed and return an HRESULT of ERROR_INSTALL_USEREXIT or WiX will raise the Error event with an error code that indicates the install was cancelled.

So, let's cover how to set that Cancel property to true, as well as an edge case you can support.

It's easy to cache a cancel request. In the sample code, this is done by setting the AppState.CancelRequested property to true. This is all the UI does when the user hits the Cancel button.

CheckForCancel method

Many of the WiX event arguments are derived from the CancellableHResultEventArgs class. Consequently, we subscribe every event whose event argument is derived from this to the CancelHandler.CheckForCancel method. This is done in WpfBaFactory.SubscribeCancelEvents. As WiX raises these events, we can check to see if a request to cancel has been cached and set the Cancel property.

if (!e.Cancel && _state.CancelRequested)
    e.Cancel = true;

That should cover cancellation, but there are a couple of edge cases that I'll mention for the sake of completion.

CheckResult method

  • ExecuteFilesInUse - If you don't handle this event, the install will require a reboot to complete. While it's a scenario you must expect, it shouldn't be a common situation for most installers.
  • ExecuteMsiMessage - This event is raised when Windows Installer emits a message about a package it is handling.

If you're supporting either of these events, you can send a request to cancel using the event arguments. But these event arguments are derived from ResultEventArgs not CancellableHResultEventArgs. So, the handling will be a little different.

You set the Result property to Cancel if it's not already set to another failure value.

if (e.Result != Result.Abort &&
    e.Result != Result.Error &&
    e.Result != Result.Cancel &&
    _model.State.CancelRequested)
{
    e.Result = Result.Cancel;
}

Previous: ApplyPhase Class || Next: ProgressHandler Class

Clone this wiki locally