I have recently started to use the excellent Inno Setup utility to create some install scripts for my own applications and discovered there was no way to set a system wide environment variable except by using an external application. SetEnv now supports User and System environment variables.
I began by searching for the Microsoft setex tool but couldn't find it (didn't really try that hard though), so I thought I'd write my own; hence, this article.
System Environment Variables
The method used to create a system wide environment is dependent upon the operating system in use. SetEnv will automatically detect this and use one of the following techniques to create, modify, or delete the environment variables.
Under Windows 9x, creating an environment variable requires modifying the user's autoexec.bat file and then executing it (or rebooting) before the variable is recognised by the Operating System.
SetEnv will automatically locate the autoexec.bat file itself (only if the file is on the C:\ or D:\ drives) and then add or modify the selected system variable. The one thing SetEnv will not do is reboot the PC because this should be left up to the user or the Setup Kit (from Inno Setup for example) to choose when to perform the reboot.
Under more modern (in other words, proper) operating systems, such as Windows 2000, XP, and Windows 2003 Server, environment variables are stored in the Registry under the following key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\ Environment
Variables are added by creating a new value under this key or by modifying a value if it already exists. To delete a variable, you simply delete its Registry value, unless you are removing part of an expanded value, such as PATH, in which case you only remove the part you want.
At this point, Windows will not be aware of your changes unless you log off or reboot. To get around this, SetEnv will broadcast a WM_SETTINGCHANGE to all of the windows in the system. This allows other running applications—for example, Explorer.exe—to be notified of your change. If you run SetEnv from a command prompt, this will not update the environment variable for the current DOS window. This is mainly due to the fact that a process (SetEnv) cannot change the environment of its parent (The Command Prompt). However, any new DOS/Command Prompts that you open will show the new variable/value.
Broadcasting this message results in a slight delay (whilst the open windows process it) of around 2-3 seconds, so it may appear that SetEnv has hung. This is not the case.
SetEnv is very easy to use and has only a few command line arguments. This section will describe how to use them.
Typing SetEnv at a command prompt and then pressing the Return key will make SetEnv display its usage information, which can be seen in the screen shot at the top of this page.
User environment variables
As of version 1.04, SetEnv also supports User environment variables. If you want SetEnv to either add or delete a User variable, add the -u option to the command line.
Creating a variable
SetEnv can create two types of variable, a simple one that has only a single value such as:
InstallPath = C:\Program Files\Xanya\_Bin
or more complex variables with multiple values. A good example of this is the PATH variable:
PATH = C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Xanya\_Bin
To create a simple variable, just enter in the following command line, obviously substituting your own variable name and value.
SetEnv -a InstallPath "C:\Program Files\Xanya\_Bin"
Similarly, to add a variable with multiple values, you need to type the following command line for each value ensuring you prefix the value with the % character.
SetEnv -a name %value
SetEnv -a PATH %"C:\Program Files\Xanya\_Bin SetEnv -a PATH %"C:\Bin
To add a User variable instead of a System one, add the -u option as in the following example:
SetEnv -ua PATH %"C:\Program Files\Xanya\_Bin
Modifying an existing variable
You modify variables in exactly the same way in which you would create them. If you are modifying a multi-value variable and you forget the % prefix to the value, SetEnv automatically will detect that the destination has multiple values and will modify it correctly.
Deleting a variable
To delete a variable, specify the -d option instead of the -a option as in the following example.
SetEnv -d InstallPath
To delete a value from a multi-value variable, you simply enter the following, specifying the value to remove.
SetEnv -d PATH %"C:\Program Files\Xanya\_Bin
As with modifying a multi-value variable, if you forget to specify the % prefix, SetEnv automatically will work this out and delete the specified value only.
To delete a User environment variable, simply add the -u option as follows:
SetEnv -ud PATH %"C:\Program Files\Xanya\_Bin
Running SetEnv from a batch file
SetEnv can be run sucessfully from a batch file. However, a problem was found by David Langford; it occurs when you attempt to specify the expanded variable prefix '%' to a value which contains a drive letter, as in the following example (This is only an issue when running SetEnv from a batch file).
SetEnv -d PATH %C:\Test
The Windows batch file interpreter will interpret the '%' character as prefix to a variable and will replace it with what it believes is the variable, %C:, with the contents of that variable, which of course is nothing. This results in SetEnv being passed a modified value as shown here:
SetEnv -d PATH \Test
This is obviously wrong and SetEnv will not be able to match the value to be removed in the expanded variable. Therefore, it will fail to delete the value from the variable. The workaround is to escape the '%' character with another '%' character. The following example will correctly remove the C:\Test value from the expanded variable, PATH.
SetEnv -d PATH %%C:\Test
- 1.04 (May 30, 2006) - Added support for User environment variables.
- 1.03 (May 17, 2006) - Updated the article to explain how to use SetEnv from a batch file, after a problem was found by David Langford.
- 1.03 (Apr 20, 2006) - Bug fix in ProcessWinXP() discovered by attiasr.
- 1.01 (Nov 15, 2005) - Bug fix in IsWinME() discovered by frankd.
- 1.00 (Oct 29, 2005) - Initial Public Release.
There are no known bugs, but If you do find any, please let me know.