V této části se podíváme nato, jak je možné ve WiXu upravit design obrazovek, případně udělat obrazovku celou novou. Jako příklad konkrétně v naší instalaci upravíme druhou obrazovku tj. zobrazení licenčního ujednání.
Ať již provádíme vytvoření celé nové obrazovky nebo jen modifikaci některé existující, musíme vždy naší obrazovku vytvořit jako novou (např. jako kopii), tedy vždy s novým ID. Proto budeme muset změnit i sekvenci (sadu - UI set) obrazovek, kde obrazovku přeměníme na nové ID. Prvním krokem tedy bude, že do našeho projektu místo použití sekvence z knihovny vložíme sekvenci naší.
K tomu budeme potřebovat zdrojové wxs soubory standardních WiX sekvencí a obrazovek. K tomu je nutné stáhnou WiX 3.5 zdrojové soubory wix35-sources.zip.
Postup úpravy našeho projektu je následující:
- V projektu vytvoříme nový wxs soubor, nazveme ho např. CustomUI.wxs.
- Najdeme zdrojový kód WiX sady obrazovek, kterou používáme v instalaci a umístíme ho do tohoto souboru. V našem případě používáme WixUI_InstallDir, proto vyhledáme soubor:
\wix35-sources\src\ext\UIExtension\wixlib\WixUI_InstallDir.wxs
a jeho obsah zkopírujeme do souboru CustomUI.wxs.
- Změníme ID elementu UI na WixUI_Custom.
- Jednotlivé sekvence (posloupnost obrazovek) jsou v souboru definovány elementy Publish. Pozměníme sekvence tak jak potřebujeme, v našem případě stačí provést pouze záměnu dialogu LicenseAgreementDlg např. na LicenseAgreementDlgModified, to bude id našeho zmodifikovaného dialogu licenčního ujednání, který později doplníme. Podobně by zde šlo udělat také zařazení nové obrazovky nebo např. některou obrazovku ze sekvence odebrat.
- V souboru instalace Product.wxs zaměníme odkaz sady obrazovek UIRef z původního WixUI_InstallDir na náš nový WixUI_Custom.
Soubor vypadá po úpravě takto:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI Id="WixUI_Custom">
<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="InstallDir" />
<DialogRef Id="BrowseDlg" />
<DialogRef Id="DiskCostDlg" />
<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="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlgModified">NOT Installed</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
<Publish Dialog="LicenseAgreementDlgModified" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
<Publish Dialog="LicenseAgreementDlgModified" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlgModified">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">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>
<Property Id="ARPNOMODIFY" Value="1" />
</UI>
<UIRef Id="WixUI_Common" />
</Fragment>
</Wix>
Nyní doplníme dialog LicenseAgreementDlgModified. Ve zdrojových souborech wxs WiXu najdeme dialog, který chceme zkopírovat, v našem případě je to dialog LicenseAgreementDlg, v souboru:
\wix35-sources\src\ext\UIExtension\wixlib\LicenseAgreementDlg.wxs.
Zdrojový kód ze souboru vykopírujeme do nového wxs souboru, který přidáme do projektu, v mém případě jsem soubor nazval LicenseDialog.wxs a ještě změníme hodnotu původního Id elementu Dialog z LicenseAgreementDlg na LicenseAgreementDlgModified.
Ve vnořených elementech elementu Dialog je definice celého dialogu. Změnou těchto elementů Control, Text apod. můžeme nyní provádět požadované změny designu dialogu. My zde provedeme následující dvě změny:
- Změníme polohu Tlačítka Print, aby bylo hned pod textem, vedle checkboxu pro potvrzení licence.
- Změníme zdroj textu licence, na nový string, který zavedeme do lokalizačních souborů, tím budeme mít rozdílné licenční soubory podle jazyka instalace (provedeme tím lokalizaci licence).
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI>
<Dialog Id="LicenseAgreementDlgModified" Width="370" Height="270" Title="!(loc.LicenseAgreementDlg_Title)">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.LicenseAgreementDlgBannerBitmap)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="340" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgDescription)" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgTitle)" />
<Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="207" Width="271" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.LicenseAgreementDlgLicenseAcceptedCheckBox)" />
<Control Id="Print" Type="PushButton" X="294" Y="207" Width="56" Height="17" Text="!(loc.WixUIPrint)">
<Publish Event="DoAction" Value="WixUIPrintEula">1</Publish>
</Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1</Publish>
<Condition Action="disable"><![CDATA[LicenseAccepted <> "1"]]></Condition>
<Condition Action="enable">LicenseAccepted = "1"</Condition>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Id="LicenseText" Type="ScrollableText" X="20" Y="60" Width="330" Height="140" Sunken="yes" TabSkip="no">
<!-- To enable EULA localization we change SourceFile location -->
<!--<Text SourceFile="!(wix.WixUILicenseRtf=$(var.licenseRtf))" />-->
<Text SourceFile="$(var.ProjectDir)\!(loc.LicenseRtf)" />
<!-- In each of localization files (wxl) put line like this:
<String Id="LicenseRtf" Overridable="yes">EULA_en.rtf</String>-->
</Control>
</Dialog>
</UI>
</Fragment>
</Wix>
K dokončení lokalizace licence ještě musíme provést následující změny:
-Do podadresáře projektu Binary přidáme soubor EULA_en.rtf s licencí v angličtině.
-V souboru Product.wxs odstraníme proměnnou <WixVariable Id="WixUILicenseRtf"
-Do souboru Strings.cs.wxl přidáme string LicenseRtf takto:
<String Id="LicenseRtf" Overridable="yes">Binary\EULA_cz.rtf</String>
-A do souboru Strings.en.wxl takto:
<String Id="LicenseRtf" Overridable="yes">Binary\EULA_en.rtf</String>
Nyní jsme zdroj rtf souboru nastavili na $(var.ProjectDir)\!(loc.LicenseRtf), kde LicenseRtf je string z lokalizačních souborů, tím bude soubor licence měněn podle jazyka instalace. Dříve se licence plnila z proměnné, a tu nešlo měnit z lokalizačního stringu. Výsledek nové licenční obrazovky včetně změny tlačítka Tisk vidíme na obrázku (při nastavení angličtiny).
Ukázali jsme si jak postupovat, pokud potřebujeme změnit design nebo sekvenci obrazovek. Také jsme tím zároveň vyřešili problém lokalizace textu licence. V následující části ještě do instalace doplníme některé další funkčnosti, jako je kontrola podmínek spuštění instalace, vložení Merge Modulu nebo vlastní (Custom) akce.
Některé odkazy ke customizaci dialogů:
http://www.merlinia.com/mdt/WiXTutorial2.msl
http://neilsleightholm.blogspot.com/2008/08/customised-uis-for-wix.html
http://www.dizzymonkeydesign.com/blog/misc/adding-and-customizing-dlgs-in-wix-3/
http://wix.sourceforge.net/manual-wix3/WixUI_customizations.htm
A k lokalizaci licence:
http://sqlserverpedia.com/blog/sql-server-bloggers/wix-3-tutorial-custom-eula-license-and-msi-localization
http://stackoverflow.com/questions/3627633/is-it-possible-to-localize-eula-in-wix-using-wxl-file