Elena
Elena

Reputation: 366

Is it possible to pass variable to WIX localization file?

I need to use variable in WIX localization file WIXUI_en-us.wxl. I tried use it like this:

<String Id="Message_SomeVersionAlreadyInstalled" Overridable="yes">A another version of product $(var.InstallationVersionForGUI) is already installed</String>

But it doesn't work. And when I declared property and used it this way:

<String Id="Message_SomeVersionAlreadyInstalled" Overridable="yes">A another version of product [InstallationVersionForGUI] is already installed</String>

doesn't work either.

Where was I wrong?

Thanks for help and your time.

Upvotes: 14

Views: 9490

Answers (4)

Chirayu Shishodiya
Chirayu Shishodiya

Reputation: 554

I was trying to get localization file to use variables. Came across this post:

There are different layers of variables in WiX (candle's preprocessor variables, Light's WixVariables/localization variables/binder variables, and MSI's properties). Each have different syntax and are evaluated at different times:

Candle's preprocessor variables "$(var.VariableName)" are evaluated when candle runs, and can be set from candle's commandline and from "" statements. Buildtime environment properties as well as custom variables can also be accessed similarly (changing the "var." prefix with other values).

Light's variables accessible from the command-line are the WixVariables, and accessing them is via the "!(wix.VariableName)" syntax. To access your variable from your commandline, you would need to change your String to: This build was prepared on !(wix.BuildMachine)

If you instead need to have the BuildMachine value exist as an MSI property at installation time (which is the "[VariableName]" syntax) you would need to add the following to one of your wxs files in a fragment that is already linked in:

<Property Id="BuildMachine" Value="!(wix.BuildMachine)"/>

Now, the environment variable COMPUTERNAME always has held the name of my build machines in the past, and you can access that this way: $(env.COMPUTERNAME). So, you can get rid of the commandline addition to light.exe and change your wxs file like this:

<WixVariable Id="BuildMachine" Value="$(env.COMPUTERNAME)"/>

Upvotes: 1

Noman_1
Noman_1

Reputation: 530

Preprocessor variables $(var.VariableName) are are processed at link time, so ideally you would use [PropertyName] which would be defined on the main Product element.

The issue sometimes is that property is not yet defined, for instance using the product name on the localization file seems not posible.

This solution was done aiming to only type the product name once given "Super product" as product name:

  • In case of running through visual studio extension:
    • Project properties -> Build -> Define variables -> "MyProductName=Super product" (No quotes)
  • In case of runing from cmd or some other place:
    • On Light.exe, add -d"MyProductName=Super product"

Into the localization .wxl file:

<String Id="Description" Overridable="yes">Description of !(wix.MyProductName) 
 to make it more interesting</String>

I have an aditional config file .wxi I include on other files to have some vars, for instance, here i had hardcoded the value but now it's harcoded on the variable definition and I use the given value:

<?xml version="1.0" encoding="utf-8"?>
<Include>
    <!-- Define the product name preprocesor variable -->
    <?define ProductName="!(wix.ProductNameDefVar)" ?>
    <!-- From this point, can use the preprocesor var -->
    <?define ProductName_x64="$(var.ProductName) (64bit)" ?>
    <?define ProductName_x32="$(var.ProductName) (32bit)" ?>
    <?define CompanyDirName = "My company name" ?>
</Include>

Finally, the place where the localization value where the localization text was not interpolating, is like this:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <!-- Include the config file with the preprocesor var -->
  <?include $(sys.CURRENTDIR)\Config.wxi?>
 
  
  <!-- Main product definition -->
  <Product  Id="$(var.ProductCode)"
    Name="$(var.ProductName)"
    Language="!(loc.Language)"
    Version="$(var.BuildVersion)"
    Manufacturer="!(loc.Company)"
    UpgradeCode="$(var.UpgradeCode)">
    
    <!-- Package details -->
    <!-- Here, Description was not interpolating -->
    <Package InstallerVersion="200"
             Compressed="yes" 
             InstallScope="perMachine" 
             Platform="$(var.Platform)"
             Manufacturer="!(loc.Company)"
             Description="!(loc.Description)"
             Keywords="!(loc.Keywords)"
             Comments="!(loc.Comments)"
             Languages="!(loc.Language)"
             />
[...]

Upvotes: 1

saschabeaumont
saschabeaumont

Reputation: 22446

Your second method should work just fine. This is the same method used by the default .wxl files.

For example, in your .wxl file you would declare your string:

<String Id="Message_Foo">Foo blah blah [Property1]</String>

And in your .wxs file, you declare the property. If you wish, you can declare the property to match a WiX variable (which it sounds like you're trying to do)

<Property Id="Property1">$(var.Property1)</Property>

Upvotes: 16

Bob Arnson
Bob Arnson

Reputation: 21896

Localization strings are processed at link time, so you can't use $(var) preprocessor variables. Using a [property] reference is supported, as long as the place where the localization string is used supports run-time formatting (e.g., using the Formatted field type).

Upvotes: 20

Related Questions