dspiegs
dspiegs

Reputation: 568

How can I show information from WiX Custom Actions in Burn Managed Bootstrapper Application

So basically I am trying to be able to show custom messages to the Burn UI during a custom action. (In this case show progress from DISM running in the background. This is the code I tried:

public static class CAExtensions
{
    public static void SendMessage(this Session session, string message)
    {
        var record = new Record();
        record.SetString(0, message);
        session.Message(InstallMessage.Info, record);
    }
}

This in my custom action I do this:

session.SendMessage("Message goes here");

I subscribe to the ExecuteMsiMessage event:

model.BootstrapperApplication.ExecuteMsiMessage += HandleMessage;

private void HandleMessage(object sender, ExecuteMsiMessageEventArgs e)
{
    Installer.Dispatcher.Invoke((Action) (() =>
    {
        var rawMessage = string.Empty;

        var app = model.GetAppData(e.PackageId);
        if (app != null)
        {
            rawMessage = app.Item1.DisplayName + ": ";
        }
        rawMessage += e.Message;

        InstallMessage = rawMessage;
    }));
}

InstallMessage is bound to a Label in the UI. This shows all the standard messages, but not the ones I send in my custom actions.

Any idea what I am doing wrong?

Upvotes: 0

Views: 1072

Answers (1)

John Wright
John Wright

Reputation: 4607

The main issue is that Info level messages don't get passed to the ExecuteMsiMessage event. From my testing, I found that Warning was the only level that reliable were passed through.

I implemented this by adding an additional flag to the message so I could tell which messages were mine and which were real warning messages (which I didn't want to show in the UI). However, I don't show that here for simplicity:

In the CustomAction:

    public virtual void SendMessage(string message, string[] data)
    {
        var fields = new List<object>(data);

        using (var record = new Record(fields.ToArray()) { FormatString = message })
        {
            _session.Message(InstallMessage.Warning, record);
        }
    }

In the Bootstrapper:

    private void EventProviderOnExecuteMsiMessage(object sender, ExecuteMsiMessageEventArgs executeMsiMessageEventArgs)
    {   
        if (executeMsiMessageEventArgs.MessageType == InstallMessage.Warning)
        {            
                var theActualMessage = executeMsiMessageEventArgs.Data.ToList();
                //do something with theActualMessage here...
        }

    }

Upvotes: 2

Related Questions