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>

42 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!

Anonymous said...

Hi,

I'm not running Visual Studio. How can call your customized version of a dialog, e.g. MyWixUI_FeatureTree, without compiling it in Visual Studio?

Thanks for the tutorial.

Neil Sleightholm said...

You just build it like any other WiX source file.

Anonymous said...

So do you compile your Dialog file as a Wix sourcefile?
And keep it in your project directory?
Pardon, I just need some more info.

Thanks..

Neil Sleightholm said...

Yes, dialog source is just another type of WiX source it can all be compiled together.

Anonymous said...

I keep on getting the following error:
error LGHT0094 : Unresolved reference to symbol 'WixUI:MyWixUI_FeatureTree' in section 'XXXGUIDXXX'

Neil Sleightholm said...

Are you compiling the UI code using candle and then linking the generated wixobj file with your main code? You may need to reference the UI extension e.g. "-ext WixUIExtension".

Anonymous said...

Hi,

Yes, I am using candle with the -ext WixUIExtensions.

How do you link the wixobj files with your main code? Guess this is where I go wrong?

Thanks again..

Neil Sleightholm said...

Something like this:
light -ext WixUIExtension -out Setup.msi obj\*.wixobj

Anonymous said...

Hi,

Thanks got it working by using something like this:

Create wixobj files from the wxs source files by using candle.

Then running light on the main program as:
light -out .msi -ext WixUIExtensions .wixobj .wixobj .wixobj

Thanks for all the help.

Anonymous said...

Hi,

I am having a problem which I'm sure you have previously answered here but reading through them I still can't see where I am going wrong - pretty new to WiX!

I have a simple WiX installer, I want to insert the simple wizard so I have included "" in the code. When building it says that it is Unresolved, I have added the WixUIExtension into my References folder but don't know what I'm missing,

Thanks,

Nick

Neil Sleightholm said...

I think something was removed from your post.

Anonymous said...

Yes sorry, it was this line:


When I build the project it says that it is Unresolved,

Thanks,

Nick

Anonymous said...

Sorry, this line was removed:

UIREF Id="WiXUI_Minimal"

Thanks,

Nick

Neil Sleightholm said...

What does it say is unresolved?

Shriti said...

Hi,
Thanks for your wonderful article, it helped me alot.

I need another solution, please help.

I have created a wix setup, and on changing the directory to other folder other than default, it will install successfully, but upon removing, it says there is some problem. it will again search to default directory for removal.

Can please help me out.

Neil Sleightholm said...

What is the problem?

Shriti said...

There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package.

This message is shown. Upon watching the log file, i get that the changed destination folder is not taken by uninstall or repair.

Neil Sleightholm said...

Are you saving the folder and retrieving it on uninstall, see here for an example http://robmensching.com/blog/posts/2010/5/2/the-wix-toolsets-remember-property-pattern.

This question is better suited to the wix-users group.

Shriti said...

No not retrieving the value on uninstall. I have done a normal setup and it installs very well. But the problem comes when i change the destination folder. In this condition too, it installs well, but while uninstall it gives the message, and in uninstall log, it doesnt remember the new destination path, but the default one, that was set in the .wxs file.
How am i suppose to solve it?

Neil Sleightholm said...

I think you need to remember the destination path for uninstall but without knowing the details of you install it is hard to comment.

Shriti said...

I have another problem, that i am not able to run Excel after installing my program. I have searched for many sites, but in all sites there is given to open installed files, which was partially helpful to have a checkbox in Exitdialog.

I have added these code in my wxs file.






And a publish tag in UI node
WIXUI_EXITDIALOGOPTIONKUALCHECKBOX = 1 and NOT Installed

But this is not working.

Can you please help.

Anonymous said...

Hi Neil,

I'm trying to override the FilesInUse dialog in wix 3.5.

I copied the FilesInUse.wxs file to my project directory and renamed the file to "my_FilesInUse.wxs". In there, I changed the Dialog ID to "my_FilesInUse.wxs"

I added it to the VS Project, and added it to my_WixInstallDir.wxs file, and changed the DialogRef for "FilesInUse" to "my_FilesInUse" in there.

When I build it, I get the following ICE20 msg:

error LGHT0204: ICE20: Standard Dialog: 'FilesInUse' not found in Dialog table

What's going on? How can I fix this?

Thanks,
Greg
.

Neil Sleightholm said...

Have you also copied and modified the template e.g. WixUI_FeatureTree.wxs or which ever one you are using.

Anonymous said...

Thanks for the response, Neil. Yes, I have my_WixUI_InstallDir.wxs file that I changed around for other stuff, and it had a "Dialog Ref" in it for FilesInUse. I changed that to point to my_FilesInUse and I get the ICE20 msg.

Also, if I change my name to "FilesInUse.wxs" and use that everywhere, then I get a duplicate-symbol-for-FilesInUse error at compile time.

Neil Sleightholm said...

I think that dialog has to called FilesInUse so that other functions can reference it.

Anonymous said...

It looks that way... it's just not the answer I was hoping for... oh well.

Thanks.