Tuesday, 19 August 2008

Customised UI's for WiX

I recently needed to add a dialog to my setup and customise the welcome dialog slightly. I wanted to use one of the standard WiX UI templates but with a few tweaks. I thought this was going to be quite hard and involve recompling the WiXUIExtension but it turned out to be relatively easy. Note: this applies to WiX v3.0.4415.0 or later.

First you need to download the WiX source and locate the UI code in the folder 'src\ext\UIExtension\wixlib'. Next copy the UI you want your code based on to your project, in my case this was WixUI_FeatureTree.wxs (the others are WixUI_Mondo.wxs, WixUI_Minimal.wxs, WixUI_InstallDir.wxs and WixUI_Advanced.wxs). Also copy the any dialogs you want to customise to your project, e.g. WelcomeDlg.wxs.

To customise the dialog, edit the Dialog/@Id e.g. <Dialog Id="WelcomeDlg" ...> becomes <Dialog Id="MyWelcomeDlg" ...> also edit any other references to this Id in the file to match the new Id.

Edit the template UI e.g. WixUI_FeatureTree.wxs, change the UI/@Id e.g <UI Id="WixUI_FeatureTree"> becomes <UI Id="WixUI_MyFeatureTree">.

Now change any references to your customised dialog to it's new Id.

To add your new dialog edit the <Publish> elements to modify the sequence of the "Back" and "Next" control attributes.

Finally, if you want to support localization add a wxl file to your project and enter the customisation strings.

Removing the License Dialog.

Another common request I have seen is to remove the license dialog from one of the standard templates, this can be achived in a similar way. Copy the template you want from the source folder, in this case I will edit WixUI_Mondo.wxs. Edit the <Publish> elements to modify the sequence of the "Back" and "Next" control attributes to skip the license dialog. Edit the UI/@Id to something unique e.g. <UI Id="WixUI_MondoNoLicense">. Then just include you new WixUI_Mondo.wxs in your project and reference the new dialog, <UIRef Id="WixUI_MondoNoLicense">.

A complete example of a mofified WixUI_Mondo is shown below:

<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) Microsoft Corporation. All rights reserved.

The use and distribution terms for this software are covered by the
Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
which can be found in the file CPL.TXT at the root of this distribution.
By using this software in any fashion, you are agreeing to be bound by
the terms of this license.

You must not remove this notice, or any other, from this software.
-->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI Id="WixUI_MondoNoLicense">
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />

<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
<Property Id="WixUI_Mode" Value="Mondo" />

<DialogRef Id="ErrorDlg" />
<DialogRef Id="FatalError" />
<DialogRef Id="FilesInUse" />
<DialogRef Id="MsiRMFilesInUse" />
<DialogRef Id="PrepareDlg" />
<DialogRef Id="ProgressDlg" />
<DialogRef Id="ResumeDlg" />
<DialogRef Id="UserExit" />

<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>

<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="SetupTypeDlg">1</Publish>

<Publish Dialog="SetupTypeDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
<Publish Dialog="SetupTypeDlg" Control="TypicalButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="SetupTypeDlg" Control="CustomButton" Event="NewDialog" Value="CustomizeDlg">1</Publish>
<Publish Dialog="SetupTypeDlg" Control="CompleteButton" Event="NewDialog"
Value
="VerifyReadyDlg">1</Publish>

<Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg"
Order
="1">WixUI_InstallMode = "Change"</Publish>
<Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="SetupTypeDlg"
Order
="2">WixUI_InstallMode = "InstallCustom"</Publish>
<Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>

<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg"
Order
="1">WixUI_InstallMode = "InstallCustom"</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="SetupTypeDlg"
Order
="2">WixUI_InstallMode = "InstallTypical" OR WixUI_InstallMode = "InstallComplete"</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg"
Order
="3">WixUI_InstallMode = "Change"</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg"
Order
="4">WixUI_InstallMode = "Repair" OR WixUI_InstallMode = "Remove"</Publish>

<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog"
Value
="MaintenanceTypeDlg">1</Publish>

<Publish Dialog="MaintenanceTypeDlg" Control="ChangeButton" Event="NewDialog"
Value
="CustomizeDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog"
Value
="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog"
Value
="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog"
Value
="MaintenanceWelcomeDlg">1</Publish>
</UI>

<UIRef Id="WixUI_Common" />
</Fragment>
</Wix>

16 comments:

kunal said...

Hi sir,

I have a question?I have to create a msi which is having a same product but having three button through which we can install three separate instance of same product.The product contains three windows service one asp web project one windows utility.Could you please help me for making this successful.

Thanks.

Neil Sleightholm said...

I don't really know how you would do this. I suggest you post a comment on the WiX mailing list.

Mike Anker said...

Thanks for the Post Neil, the example was exactly what I needed and worked perfectly!!

cheers
Mike Anker

Anonymous said...

Great post, just wanted to say thanks.

Christopher said...

Many thanks, this makes it a lot easier! Chris

Anonymous said...

hi,
I'm having a problem with the example, when i run it on VS2008 an compiler error appear:

error LGHT0094 : Unresolved reference to symbol 'WixUI:MyWixUI_FeatureTree' in section 'Product:*'

Neil Sleightholm said...

Have you included your modified WixUI_FeatureTree.wxs in your project?

PostScriptum said...

Thanks, exactly what I wanted. Full customization with any existing code reuse possibility!!!

Andrew said...

This was a really great tutorial, much easier to understand than a couple of the others that I read. Thanks for including a link to the source code as well. Using this I was able to redo all of my dialog screens. The only thing that gave me trouble was replacing some of the string constants in some of the dialogs. To do this I had to add this command line argument to the Linker dialog under Properties, Tool Settings, Linker in my WiX Project ... -loc StringOverrides.wxl

Then I pulled the appropriate constants out of src\ext\UIExtension\wixlib\WixUI_en-us.wxl

and replaced them in my one file like this



Sample Text

amey said...

Hi,
i have installed wix35 setup on my machine. I can not find source code or .wsx files as you mentioned.

I know its been migrated to codeplex and i could see a src/ext folder there..

I created .msi file still want some UI changes,
Can u please tell me from where to get souce files

Neil Sleightholm said...

You used to be able to download a source zip file but this seems to have gone now. If you go to the source code on codeplex you can download the latest code which should be ok even though it is WiX3.6. Alternatively you can get the WiX3.5 code using Mercurial.

Gab Martínez said...

Excellent just what I needed thanks for posting

MarcusUA said...

Hi, I can't modify WixUI_Advanced.
I need to modify AdvancedWelcomeEulaDlg so it doesn't have I Agree check-box.
I have copied everything from WixUI_Advanced.wxs, changed IDs for UI and Custom Actions, created MyAdvancedWelcomeEulaDlg and modified all Publish to use it.
But now I am getting error:
"error LGHT0130: The primary key 'ExitDialog/Finish/EndDialog/Return/1' is duplicated in table 'ControlEvent'. Please remove one of the entries or rename a part of the primary key to avoid the collision."
I seems as if I still have reference to standard WixUI dialog set, but I can't locate it.
This method works well for any other dialog set, except for advanced.
Please advice! Thanks in adcvance!

MarcusUA said...

Hi, I can't modify WixUI_Advanced.
I need to modify AdvancedWelcomeEulaDlg so it doesn't have I Agree check-box.
I have copied everything from WixUI_Advanced.wxs, changed IDs for UI and Custom Actions, created MyAdvancedWelcomeEulaDlg and modified all Publish to use it.
But now I am getting error:
"error LGHT0130: The primary key 'ExitDialog/Finish/EndDialog/Return/1' is duplicated in table 'ControlEvent'. Please remove one of the entries or rename a part of the primary key to avoid the collision."
I seems as if I still have reference to standard WixUI dialog set, but I can't locate it.
This method works well for any other dialog set, except for advanced.
Please advice! Thanks in advance!

Neil Sleightholm said...

You should only need to copy WixUI_Advanced.wxs and AdvancedWelcomeEulaDlg.wxs then rename the AdvancedWelcomeEulaDlg to MyAdvancedWelcomeEulaDlg in both files. In your cloned WixUI_Advanced.wxs you need to change Id="WixUI_Advanced" and then add this reference to your project.

MarcusUA said...

Thanks for response, I finally found where there problem was, another wxs file in this wix-project referenced original WixUI_Advanced:
<InstallExecuteSequence> <Custom Action="ResetWixSetDefaultPerMachineFolder" Before="WixSetPerMachineFolder" />
</InstallExecuteSequence>


Changed it to Before="WixSetPerMachineFolder2"
and now everything works!