Monday, 30 March 2015

Replacing a standard WelcomeDlg with a custom one.

We all sometimes looking for solution how to customize the standard dialog in Windows Installer XML (WiX).

Overview

Usually we can easy select any of WiX standard dialog sets, from the WiX UI assembly. It could be one of these sets:
        <UIRef Id="WixUI_Minimal" />
        <UIRef Id="WixUI_Advanced" />
        <UIRef Id="WixUI_FeatureTree" />
        <UIRef Id="WixUI_InstallDir" />
        <UIRef Id="WixUI_Mondo" />
I selected one of them, it was WixUI_InstallDir dialog set. In case when I want add a new dialog I just following the manual on the WiX Toolset site where described how to customize the WixUI Dialog Sets.
It is not very hard.
As result I got a Welcome dialog:

On this dialog I see Major.Minor version of my "Super Product". But I want more...
I want to see which version of this product will be installed exactly. In the same time I don't like to change my Product Name for whole project.
    <Product Id="*"
             Name="$(var.ProductName)"
             Language="1033"
             Version="$(var.Version)"
             Manufacturer="$(var.Manufacturer)"
             UpgradeCode="$(var.UpgradeCode)">
Well, to avoid this I will replace my Welcome dialog with a custom one.

Replacing the first dialog

Replacing any dialog of this set is not problem, so lets do it. First of all I checked the first-time install dialog sequence. To do it I downloaded the source code of WiX. It's an open source project located on SourceForge. Once that's done, I located the file WixUI_InstallDir.wxs in the source folder (currently it is here \src\ext\UIExtension\wixlib\). So it is a sequence:

  • WixUI_WelcomeDlg
  • WixUI_LicenseAgreementDlg
  • WixUI_InstallDirDlg
  • WixUI_VerifyReadyDlg
  • WixUI_DiskCostDlg

Then I copied the original WelcomeDlg code into my project, gave it a new id, then made some modifications. I replaced InstallUISequence from
            <InstallUISequence>
                <Show Dialog="WelcomeDlg" Before="ProgressDlg" Overridable="yes">NOT Installed OR PATCH</Show>
            </InstallUISequence>
to my custom file name (new id)
            <InstallUISequence>
                <Show Dialog="CustomWelcomeDlg" Before="ProgressDlg" >NOT Installed OR PATCH</Show>
            </InstallUISequence>

Then I fixed up Back/Next buttons on neighboring dialogs so they ended up at my dialog instead of the built-in ones:
        <UI>
            <DialogRef Id="CustomWelcomeDlg" />
 
            <Publish Dialog="CustomWelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
            <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="CustomWelcomeDlg">1</Publish>
        </UI>

So, currently I initiated my CustomWelcomeDlg before ProgressDlg, and published new events for buttons on both dialogs Next for CustomWelcomeDlg and Back for LicenceAgreementDlg.

Now when I will run my Setup.msi I should got a new Welcome dialog. And of course I could not avoid some problem: all looked great, but after I pressed "Install" button I got a new window with an old Welcome dialog.

I don't want to describe all my steps to find a solution of this problem, just want to show how it could be fixed. So, I added a new row into InstallUISequence, where turned off event to show original Welcome dialog:
            <InstallUISequence>
                <Show Dialog="WelcomeDlg" Before="ProgressDlg" Overridable="no">0</Show>
                <Show Dialog="CustomWelcomeDlg" Before="ProgressDlg" >NOT Installed OR PATCH</Show>
            </InstallUISequence>
So as a result of my manipulations I got a Welcome dialog with some customization:
Work is done.

Interesting links to documentation about WiX.