The main page for the series is here.
Introduction
I am beginning a mini-series on installable items. Today's topic - environment variables.
MSI story
In order to install an environment variable we need to add a record into the Environment table. Here are the fields we need to fill:
Also, WriteEnvironmentStrings and RemoveEnvironmentStrings standard actions must be scheduled in the InstallExecuteSequence table. If we are setting the value of the environment variable to the value of some property, make sure that this property gets its value before WriteEnvironmentStrings action.
What we can do with environment variable?
These are the options we have when we install/delete an environment variable:
In MSI we are using prefixes to the name of the variabble and prefixes and suffixes to the variable's value to indicate what we want to do with the variable. In WiX, we are using attributes of <Environment> element for that.
How it translates to WiX?
Next table shows MSI's prefixes and suffixes for Environment table and their attribute equivalents in <Environment> element:
empty column
Also, WiX will schedule WriteEnvironmentStrings and RemoveEnvironmentStrings standard actions for you. If you want to put conditions on these actions, their WiX counterparts are <WriteEnvironmentStrings> and <RemoveEnvironmentStrings> respectively. They must be scheduled in the Execute sequence tables.
Examples
Let's start with something simple:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
<Product Id="{A25A5612-112C-4052-BD79-AA2767F3443C}"
Name="Minimal Windows Installer Sample"
Language="1033"
Version="1.0.0.0"
Manufacturer="Acme Corporation"
UpgradeCode="{A9B4BC63-1AE8-4E9D-9101-0A37F4293BB7}" >
<Package Id="????????-????-????-????-????????????"
Description="Minimal Windows Installer Sample"
Comments="This installer database contains the logic and data required to install Minimal Windows Installer Sample."
InstallerVersion="200"
Compressed="yes"
Languages="1033" />
<Media Id="1" Cabinet="Product.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION"
Name="Minimal"
LongName="MinimalInstallation">
<Component Id="Component1"
Guid="{1781A625-8ACB-45E7-A8BA-219D81760B2E}">
<CreateFolder />
<Environment Id="TestMinVar"
Action="set"
Part="all"
Name="MinEnvVar"
Permanent="no"
System="no"
Value="123" />
</Component>
</Directory>
<Feature Id="Feature1"
Title="Feature1 Title"
Level="1">
<ComponentRef Id="Component1" />
</Feature>
</Product>
</Wix>
This sample will create new User's variable TestMinVar with the value "123". Let's compile and install the sample application. Make sure that new environment variable has been created. Uninstall the Minimal application.
Remember that at the beginning I said that the Value column of the Environment table is a formatted field. That means that we can set the value of the environment variable to the value of property, another environment variable, or anything that can be represented by formatted string. Let's use our environment variable to preserve INSTALLLOCATION:
Value="[INSTALLLOCATION]" />
We also saw, that we can add the new value to existing variable. Let's make our original sample's variable permanent:
Permanent="yes"
Now, compile, install, and uninstall the sample. That will leave the environment variable in the User's profile. Let's add string "456" at the end of the TestMinVar variable (don't forget to set Permanent attribute to "no" again):
Part="last"
Value="456" />
What if we want to add "456" and "789"? Can we do that:
Value="456;789" />
If you compile, install, and uninstall the sample you will see that it appears to work, but still don't install two values using one <Environment> element. This is what MSDN is saying (Environment table):
"Each row can contain only one value. For example, the entry Value;Value;[~] is more than one value and should not be used because it causes unpredictable results. The entry Value;[~] is just one value."
Use two separate records to add two values to environment variable:
Value="789" />
To test conditions on standard actions you can use this sample:
<Property Id="EnableEV" Value="1" />
<InstallExecuteSequence>
<WriteEnvironmentStrings>EnableEV=1</WriteEnvironmentStrings>
</InstallExecuteSequence>
Here the installation of environment variables depends on the value of EnableEV property. If in your real life program you'll set this variable during user interface phase (in the client process), you might want to change the declaration of this variable to make it public and secure:
<Property Id="ENABLEEV" Value="1" Secure="yes" />
. . .
<WriteEnvironmentStrings>ENABLEEV=1</WriteEnvironmentStrings>
That will ensure that ENABLEEV property will be passed from client to server process and will preserve its value. See here for more details.