Is it possible to have a custom action in Wix update text on a dialog? I've been searching various methods of doing this, but nothing has worked for me yet.
I have a PushButton control defined with
<Control Id="RunButton" Type="PushButton" X="0" Y="0" Height="18" Width="56" Text="Run">
<Publish Event="DoAction" Value="CustomAction">1</Publish>
</Control>
and a Text control that has
<Control Id="MessageText" X="0" Y="20" Width="100" Height="18">
<Subscribe Event="ActionData" Attribute="Text" />
</Control>
In my custom action, I have
using(var rec = new Record(0)){
rec.SetString(0, "Starting...");
session.Message(InstallMessage.ActionData, rec);
}
This is the basic process I've found on numerous forums, but it isn't working for me.
The action is defined as Execute="immediate" and Return="Check".
I have also tried changing the "Record" object to be 3 fields, and set the same property to fields 1, 2 and 3. That did not work either.
Could anyone explain what I'm doing wrong? Is this just not doable in Wix? Essentially I am trying to set up a long running process in a custom action and want to be able to report back to the user the progress of the action.
If you check the docs for DoAction:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa368322(v=vs.85).aspx
it says that you can't send a message via MsiProcessMessage, which is what session.message actually is underneath, so that's the most likely reason for it not working. I suspect that the forums you're looking at describe general use of MsiProcessMessage without the caveat of this particular case.
Without knowing what the custom action is doing I can't suggest anything. In the execute sequence you can integrate your CA with the progress bar, but you're in the UI sequence, presumably collecting a lot of data or checking something.
If your custom action updates the system it should be in the execute sequence as a deferred custom action. Not only does that let you influence the progress bar and supply text saying what's going on, but the install could fail, or the user could cancel it, the whole point of a transactional install is that failure will roll it back as if the install never started. That means you should save the database and restore it in a rollback custom action. The other issue you might have is that immediate custom actions in the UI are not elevated, so you may not be able to update the database. Not only that, but a silent install bypasses the UI so your custom action won't be called and your product cannot be rolled out using group policy or SCCM methods.
The internal UI of Windows Installer doesn't update much indirectly. Fundamentally you have to decide if you want a single update (more like your description), or if you're looking for progress messages (more like your approach). For progress messages, you should heed PhilDW's answer, as this will need to be part of the execute sequence. For one-time updates in response to UI events (such as the user clicking a button), consider using properties and SetProperty control events:
- Your control should show text including a property reference such as
Pudding: [FLAVOR]
.
- Your DoAction control event can set some property, perhaps even
FLAVOR
itself, but for clarity I might suggest FLAVOR_FROMDOACTION
.
- Then add a SetProperty control event that sets
FLAVOR
to [FLAVOR_FROMDOACTION]
. This will update the control's text.