Search code examples
wixwindows-installer

Wix: How can I set, at runtime, the text to be displayed in VerifyReadyDlg?


After the user goes through the Setup Wizard, and makes a few choices, the usual thing is to display the VerifyReadyDlg to say "Are you ready to install?"

The built-in VerifyReadyDlg is static. It does not present a summary of the choices he made previously. I'd like to modify it so that it does.

How can I do that?


Example

"Static" text:
alt text

Intelligent text:
alt text

I don't believe I can modify the Control table in the MSI, because mods during the installation process are not allowed. I found MsiViewModifyInsertTemporary, but I don't think that will work either. The relevant row in the Control table is already present, and it contains static data. I want to modify the data, just before VerifyReadyDlg is displayed.


Solution

  • You may not be able to modify existing rows in the MSI tables, but you can insert new "temporary" rows.

    So, in a custom action, at runtime, insert one or more temporary rows into the Control table. In Javascript, it looks like this:

    var controlView = Session.Database.OpenView("SELECT * FROM Control");
    controlView.Execute();
    
    var record             = Session.Installer.CreateRecord(12);
    record.StringData(1)   = "VerifyReadyDlg";    // Dialog_ - the dialog to mod
    record.StringData(2)   = "CustomVerifyText1"; // Control - any unique name will do
    record.StringData(3)   = "Text";              // Type
    record.IntegerData(4)  = 25;                  // X
    record.IntegerData(5)  = 70;                  // Y
    record.IntegerData(6)  = 320;                 // Width
    record.IntegerData(7)  = 65;                  // Height
    record.IntegerData(8)  = 2;                   // Attributes
    record.StringData(9)   = "";                  // Property
    record.StringData(10)  = text1;               // Text - the text to be displayed
    record.StringData(11)  = "";                  // Control_Next
    record.StringData(12)  = "";                  // Help
    controlView.Modify(MsiViewModify.InsertTemporary, record);
    controlView.Close();    
    

    You probably want that custom text to be displayed only upon INSTALL. In that case, add a condition, in the same way:

    var controlCondView    = Session.Database.OpenView("SELECT * FROM ControlCondition");
    controlCondView.Execute();
    
    record                 = Session.Installer.CreateRecord(4);
    record.StringData(1)   = "VerifyReadyDlg";    // Dialog_
    record.StringData(2)   = "CustomVerifyText1"; // Control_ - same name as above
    record.StringData(3)   = "Show";              // Action
    record.StringData(4)   = "NOT Installed";     // Condition
    controlCondView.Modify(MsiViewModify.InsertTemporary, record);
    controlCondView.Close();
    

    The Msi constants are defined like this:

    // http://msdn.microsoft.com/en-us/library/aa372516(VS.85).aspx
    var MsiViewModify = 
    {
        Refresh          : 0,
        Insert           : 1,
        Update           : 2,
        Assign           : 3,
        Replace          : 4,
        Merge            : 5,
        Delete           : 6,
        InsertTemporary  : 7,   // cannot permanently modify the MSI during install
        Validate         : 8,
        ValidateNew      : 9,
        ValidateField    : 10,
        ValidateDelete   : 11
    };
    

    A couple notes:

    1. The InstallText in the Control table is normally displayed. It can be customized with a .wxl file, inserting something like this:

      <String Id="VerifyReadyDlgInstallText">Whatever.</String>

      This results in a row in the Control table. But you cannot remove rows from the table at runtime.
      If you choose the X,Y and Height,Width for your new custom text to be the same as for the static InstallText, the InstallText will be obscured.

    2. It may seem counter-intuitive to use "NOT Installed" as the condition - but remember, this is the state of the world prior to running the Setup Wizard. If the MSI is Installed prior to running the Wizard, then you're probably not installing it, which means you don't need to display the choices being made in the wizard.

    3. Of course you can add multiple controls this way. You could add multiple Text controls, or...You can add lines, buttons, checkboxes, whatever. For each one, you'll have to set the control type and geometry appropriately. Use Orca to examine the Control table to figure out how.

    4. This approach works for any Dialog. You only have to be sure to run the custom action to insert the temp rows into the Control table, at some point in the InstallUISequence, before the Dialog is rendered.