Is it possible to localize EULA in WiX using .wxl file?
Asked Answered
C

5

9

My installer, created wth WiX is localized via .wxl files. It is possible in WiX to specify multiple cultures and light.exe will be called multiple times, creating an installer for each language (this is available while building installer from Visual Studio).

All works file except for EULA. It is defined in .wxs file via

<WixVariable Id='WixUILicenseRtf' Value='en.rtf' />

And i don't know a good way to change this value from .wxl localization file. Using

<WixVariable Id='WixUILicenseRtf' Value='!(loc.EulaFile)' />
<String Id='EulaFile'>en.rtf</String>

Is not working, sice .wxl files are used at link-time and .wxs is compiled before them, so compiler can't find !(loc.EulaFile). Searching forums i have found two workarounds. First is to create a custom license dialog for each language - it seems to work, but it's a very hard way and bloat source code a lot. Second way is to drop Visual Studio / Votive build and to call light.exe multiple times, specifying different license file each time via -d command-line key.

Is it any way to solve this problem and use localized EULA files so project can be built in VisualStudio + Voltive without a need to copy-paste lots of dialogs? Localizing installers is a very common problem, so maybe some solution exist that i don't know about?

Canella answered 2/9, 2010 at 13:38 Comment(0)
A
8

There is another way to do this, and although it is a bit messy it is less messy than the two workarounds the OP has mentioned. And credit where credit is due, this answer is almost 100% based on this post http://weblogs.sqlteam.com/mladenp/archive/2010/04/15/WiX-3-Tutorial-Custom-EULA-License-and-MSI-localization.aspx by Mladen Prajdić.

The following is based on WiX 3.5.

You create a slightly modified copy of the LicenseAgreementDlg dialog and include it in your project.

<?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/cpl1.0.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.
-->

<!-- This is a modified version of LicenseAgreementDlg to support selection of localized versions of 
     the license file. It is very much based on this article: 
     http://sqlserverpedia.com/blog/sql-server-bloggers/wix-3-tutorial-custom-eula-license-and-msi-localization/  -->

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <UI>
            <Dialog Id="LicenseAgreementKludge" 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="330" Height="18" CheckBoxValue="1" Property="LicenseAcceptedKludge" Text="!(loc.LicenseAgreementDlgLicenseAcceptedCheckBox)" />
                <Control Id="Print" Type="PushButton" X="112" Y="243" 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[LicenseAcceptedKludge <> "1"]]></Condition>
                    <Condition Action="enable">LicenseAcceptedKludge = "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">
                    <Text SourceFile="$(var.ProjectDir)\!(loc.LicenseRtf)" />  <!-- this value has been modified -->
                </Control>
            </Dialog>
        </UI>
    </Fragment>
</Wix>

In your main WiX source file you add the following code to "patch" your new dialog into the dialog sequencing instead of the original one:

  <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementKludge">1</Publish>
  <Publish Dialog="LicenseAgreementKludge" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
  <Publish Dialog="LicenseAgreementKludge" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAcceptedKludge = "1"</Publish>
  <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementKludge">1</Publish>

Note that this is based on using the WixUI_InstallDir dialog collection - for other collections, such as WixUI_Mondo, you will probably have to modify the above by looking at the source.

Finally, in each of your localization files you place one line like this:

<String Id="LicenseRtf">en-us\MerliniaSMSGatewayLicense.en-us.rtf</String>

<String Id="LicenseRtf">da-dk\MerliniaSMSGatewayLicense.da-dk.rtf</String>

And, of course, you place the localized license file as indicated. I'm placing the license files (and localization files) in subfolders, but this is not necessary.

Like I said, it's a bit messy, but it does work.

Ardath answered 9/2, 2011 at 5:41 Comment(2)
can't get it working in WiX 3.7. has the localization support been removed from Text element since WiX 3.0?Wingate
User @kadorken, in a suggested edit, noted the following: "Make sure you put the patch publish directives AFTER your UIRef ID="WixUI_InstallDir" directive for them to be effective."Ardath
A
8

Best solution is the simplest, just use the WixUILicenseRtf variable on the command line when specifying your .wxl file.

light -loc setup_fr-FR.wxl -dWixUILicenseRtf=EULA_fr-FR.rtf ...

Refer User Interface Basics at WiX Wiki for more information.

Anselm answered 10/2, 2011 at 5:32 Comment(1)
Thanks a lot! Like you said; Best solution is the simplest! You saved my day!Flinders
B
1

Localizing the EULA is very simple. Add a ScrollableText Control to one of your dialogs. Reference a localization String in the text element of the ScrollableText Control.

<Control Id="LicenseText" Type="ScrollableText" X="20" Y="60" Width="330" Height="140" Sunken="yes" TabSkip="no">
  <Text>!(loc.License)</Text>
</Control>

Next create a localization file, say for american english. Name the file en-US.wxl. Create a localization String element in the localization file which uses the identifier referenced in the Text element of the ScrollableText Control, in this case it's called License. Add the raw rtf string of your EULA as a CDATA element of the localization string.

To get the raw data, create an rtf file with wordpad, for example. Open that rtf file with notepad and copy its content. Paste that content into the CDATA element of the localization String element. Be sure to omit all whitespace between the String and CDATA Tags.

An example localized String element follows:

<String Id="License"><![CDATA[{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang7\f0\fs22 American EULA.}]]></String>

So the key to including multiple EULA's is to use the raw rtf data in the respective localization files.

Blandishment answered 21/3, 2013 at 10:8 Comment(0)
E
0

Go to Solution's Configuration Manager, on the installer project line create a new configuration for each localization you want to use, like the following for example:

Project configuration selector for Solution's Configuration Manager

Now, on the installer project properties page / Build, for each created configuration, set a single culture on "Cultures to build" and set a different value on "Define variables" box each culture:

For instance, for es-ES:

WixUILicenseRtf=.\Assets\license-es-ES.rtf

For en-US:

WixUILicenseRtf=.\Assets\license-en-US.rtf

... etc

Project properties args

To build your installers:

For each culture:

  • Go to the configuration manager,
  • Select the configuration culture for the installer, accept
  • Build

Pros:

  • No need to deal with custom actions, custom dialogs or console commands
  • Only need to config it once. Making it run is a mechanic task

Cons:

  • Needs some extra clicks for each build
  • Messy with more than three cultures
Evadne answered 28/10, 2021 at 14:20 Comment(0)
P
0

To add to Noman_1's answer, you can use the Batch Build feature of Visual Studio to mitigate the messiness and extra click problem. This is, in my opinion, the simplest and most appropriate solution since the license should logically be specified at build time.

Prefix answered 1/5, 2023 at 18:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.