Wix, show custom status message in ProgressDlg

2019-06-11 07:17发布

问题:

I'm trying to show a custom status message in default wix's ProgressDlg, following this answer:

WiX: dynamically changing the status text during CustomAction

So far, I got this code in my custom action:

public class CustomActions
    {
        [CustomAction]
        public static ActionResult CustomAction1(Session session)
        {
            Debugger.Launch();
            session.Log("Begin CustomAction1");
            MessageTest(session);
            return ActionResult.Success;
        }


        private static void MessageTest(Session session)
        {
            for (int i = 0; i < 10; i++)
            {
                using (Record r = new Record(0))
                {
                    r.SetString(0, $"Hello worls {i}");
                    session.Message(InstallMessage.ActionData, r);
                }
                Thread.Sleep(1000);
            }
        }
    }

Then, in Product.wxs have the following xml fragment:

<Binary Id="CuCustomInstallActionsBinary" SourceFile="$(var.ConsoleApplication1_TargetDir)CustomAction1.CA.dll" />
<CustomAction Id="CuCustomActionOnAfterInstall" BinaryKey="CuCustomInstallActionsBinary" DllEntry="CustomAction1" Execute="deferred" HideTarget="no" Return="check" Impersonate="no" />

    <InstallExecuteSequence>
      <Custom Action="CuCustomActionOnAfterInstall" Before="InstallFinalize"><![CDATA[(NOT Installed) AND (NOT REMOVE)]]></Custom>
    </InstallExecuteSequence>

But nothing is been shown in UI. The status message remains empty while the custom action runs.

Is there anything else that should be done to acomplish this? Maybe suscribing to <Subscribe Event="ActionData" Attribute="Text" /> Do I have to implement my own custom ProgressDlg for this?

回答1:

I found the answer after @jbudreau tips. The Record instance must have 3 fields, it's the same number of columns in ActionText MSI table. The first field must be set to custom action name, second is the UI message to show, and the third is the template value, not used in my case. Also, call to session.Message() must include parameter InstallMessage.ActionStart. So, the final code is:

public void UpdateStatus(string message)
{
   using (Record r = new Record(3))
   {
     r.SetString(1, "CuCustomActionOnAfterInstall");
     r.SetString(2, message);
     session.Message(InstallMessage.ActionStart, r);
   }
}

I haven't tested if it's necessary to have an entry in ActionText, what is accomplished by placing in Product.wxs file a ProgressText inside Product tag. Without this, the resulting MSI file won't contain the ActionText table

<UI>
      <ProgressText Action="CuCustomActionOnAfterInstall">Running post install configuration.</ProgressText>
</UI>