Thank you everyone for comments. Inspired by How to perform Wix Upgrade with custom bootstrapper I understood I didn't handle situation when installer is run quietly.
So I prepared another class for SilentUninstall and did it in my Bootstrapper class:
public class BootstrapperApp : BootstrapperApplication
{
public static Dispatcher Dispatcher { get; set; }
protected override void Run()
{
Dispatcher = Dispatcher.CurrentDispatcher;
var model = new BootstrapperApplicationModel(this);
var command = model.BootstrapperApplication.Command;
if (command.Action == LaunchAction.Uninstall && (command.Display == Display.None || command.Display == Display.Embedded))
{
model.LogMessage("Starting silent uninstaller.");
var viewModel = new SilentUninstallViewModel(model, Engine);
Engine.Detect();
}
else
{
model.LogMessage("Starting installer.");
var viewModel = new InstallViewModel(model);
var view = new InstallView(viewModel);
view.Closed += (sender, e) => Dispatcher.InvokeShutdown();
model.SetWindowHandle(view);
Engine.Detect();
view.Show();
}
Dispatcher.Run();
Engine.Quit(model.FinalResult);
}}
and my SilentUninstaller class:
public class SilentUninstallViewModel
{
private BootstrapperApplicationModel model;
private Engine engine;
public SilentUninstallViewModel(BootstrapperApplicationModel model, Engine engine)
{
this.model = model;
this.engine = engine;
WireUpEventHandlers();
}
private void WireUpEventHandlers()
{
this.model.BootstrapperApplication.PlanComplete += PlanCompleted;
this.model.BootstrapperApplication.DetectComplete += DetectCompleted;
this.model.BootstrapperApplication.ApplyComplete += ApplyCompleted;
}
private void DetectCompleted(object sender, DetectCompleteEventArgs e)
{
this.model.LogMessage("Detecting has been completed for silent uninstallation.");
this.model.PlanAction(LaunchAction.Uninstall);
}
private void ApplyCompleted(object sender, ApplyCompleteEventArgs e)
{
this.model.LogMessage("Applying has been completed for silent uninstallation.");
this.model.FinalResult = e.Status;
this.engine.Quit(this.model.FinalResult);
}
private void PlanCompleted(object sender, PlanCompleteEventArgs e)
{
this.model.LogMessage("Planning has been started for silent uninstallation.");
model.ApplyAction();
}
}
and it seems to works properly. Even property _UPGRADE is raised in particular MSIs ;)