Click here to Skip to main content
Click here to Skip to main content

SetEnv

By , 11 Feb 2008
 
Screenshot - SetEnv.gif

Introduction

I recently used the excellent Inno Setup utility to create some install scripts for my own applications. I discovered that there was no way to set a system-wide environment variable except by using an external application. SetEnv supports User and System environment variables.

I began by searching for the Microsoft setex tool, but couldn't find it. I didn't really try that hard though. I thought I'd write my own, hence this article.
You can find a proper setup kit for SetEnv on my website.

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 will use one of the following techniques to create/modify or delete environment variables.

Windows 95/98/ME

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 recognized by the operating system. SetEnv will automatically locate the autoexec.bat file itself -- as long as the file is on the C:\ or D:\ drive -- and then add or modify the selected system variable. The one thing SetEnv will not do is reboot the PC, as it should be left up to the user or the Setup Kit -- from Inno Setup, for example -- to choose when to perform the reboot.

Windows XP/2000/2K3/Vista

Under more modern (i.e. 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, we simply delete its registry value. That is, unless we are removing part of an expanded value such as PATH, in which case we only remove the part we want.

At this point, Windows will not be aware of our changes unless we 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 such as Explorer.exe to be notified of our change. If you run SetEnv from a command prompt, then 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 prompt that you open will show the new variable/value.

Broadcasting this message results in a slight delay of around 2-3 seconds, whilst the open Windows process it. So it may appear that SetEnv has hung, but this is not the case.

Using SetEnv

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. This can be seen in the screenshot 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, then add the -u option to the command line.

Creating a Variable

SetEnv can create two types of variables, 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, substitute 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. Ensure that you prefix the value with the % character:

SetEnv -a name %value

E.g.

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, then SetEnv will automatically detect that the destination has multiple values and will modify it correctly.

Dynamic Variable Expansion

This allows you to set a variable to always equal the value of an existing environment variable, even if that variable changes. Let me show you an example of when this would be very useful. This example was inspired by Synetech; if you mind me stealing it just let me know.

Say that you have an environment variable called MEDIADIR (set to C:\Media) and you want to create two additional variables called MUSICDIR and PICDIR (set to %MEDIADIR%\Music and %MEDIADIR%\Pics, respectively). These would be expanded by the operating system to the following:

C:\Media\Music
C:\Media\Pics

Now, say you decided to move the MEDIADIR folder to drive D (D:\Media) using dynamic variable expansion. SetEnv will ensure that your MUSICDIR and PICDIR variables are correctly relocated to the following automatically.

D:\Media\Music
D:\Media\Pics

To enable dynamic variable expansion, simply create your variables as in the following example. Use the ~ symbol to identify the existing variable name.

setenv -a MEDIADIR C:\Media
// Create the original variable

// Create our dynamic variable, when MEDIADIR changes, so will MUSICDIR
setenv -a MUSICDIR ~MEDIADIR~/Music
// Our second dynamic variable, PICDIR will change if MEDIADIR changes
setenv -a PICDIR ~MEDIADIR~/Pics

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, then SetEnv will automatically 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 successfully from a batch file. However, a problem was found by David Langford, which occurs when you attempt to specify the expanded variable prefix % to a value which contains a drive letter, as in the following example. Note that 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 a prefix to a variable. It will replace the character 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. It will thus 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

Bugs

There are no known bugs, but if you do find any, then please let me know.

History

  • 1.09 (Feb 9, 2008) - Fixed a problem on Windows 98 where it sometimes failed to open the Autoexec.bat file (Found by mulinux).
  • 1.08 (May 31, 2007) - Updated SetEnv's usage information on how to delete a user environment variable using SetEnv. The code has not changed.
  • 1.07 (Jan 25, 2007) - Fixed a bug found by depaolim
  • 1.06 (Jan 14, 2007) - Added dynamic expansion support (same as using ~ with setx), originally requested by Andre Amaral, additional request by Synetech.
  • 1.05 (Sep 06, 2006) - Added support to prepend (rather than append) a value to an expanded string, requested by Masuia.
  • 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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jonathan [Darka]
United Kingdom United Kingdom
Member

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionPossible to delete several strings from an expanded var at once?memberkj_easy26 Dec '10 - 6:06 
Hi there,
Would it be possible to delete several strings from an expanded var at once?
e.g. setenv -d PATH %"C:\abc;D:\AAA
 
I know that I can run setenv several times for each directory path, but that is in my case no option - I only have one shot, so to speak.
 
Otherwise: great helpful little tool!
Cheers,
Klaus
AnswerRe: Possible to delete several strings from an expanded var at once?memberJonathan [Darka]7 Dec '10 - 0:57 
Hi Klau,
 
It might take me a day or so but let me look into it.
 
regards,

Jonathan Wilkes
Darka[DebugSPY]
 
[My Code Project Articles]

GeneralSetEnv not setting envsmemberDennis Merritt17 Jul '10 - 14:29 
I'm running Vista, and got SetEnv to set environment variables in an install using Actual Installer as suggested by them. But it doesn't work.
 
When I try SetEnv at the command line, I get an error, and the variable is not set. (Not just then, but closing command prompt, opening, rebooting, looking at system environment variables, nothing, no DUCK_THING.)
 
>SetEnv -a DUCK_THING "testing"
Error - Set Value : The operation completed successfully.
 
I had tried writing my own environment setting setup program but was frustrated when RegQueryKeyEx could find a value just fine but when I called RegDeleteKey with the same hKey and subkey, I got the error message file not found. I was hoping SetEnv was smarter.
 
Also tried with UAC off, and still no joy.
 
I wonder if there's something wrong with my environment?
 
Thanks
GeneralRe: SetEnv not setting envsmemberJonathan [Darka]18 Jul '10 - 22:57 
Hi Dennis,
 
Sorry to hear you've had problems with SetEnv, I'll do what I can to help.
When you tried SetEnv, did you run it from a normal command prompt or an elevated one.
 
I believe this is a permissions problem and the failure is "Access Denied", for some reason the error returned to SetEnv is "The Operation Completed Successfully" which is no help at all Smile | :)
 
Can you try this, create a batch file with the following contents and see what error is returned.
 
@echo off
"c:\program files\xanya\bin\setenv" -a DUCK_THING "testing"
 
if errorlevel 0 goto end
 
if errorlevel 1 goto other
 
if errorlevel 5 goto denied
 

:denied
echo Access Denied
goto end
 
:other
echo An Error Occurred
 
:end
 
Could you confirm this and let me know, I'll then try to improve the error message handling within SetEnv.
 
regards,
Jonathan

Jonathan Wilkes
Darka[DebugSPY]
 
[My Code Project Articles]

GeneralRe: SetEnv not setting envsmemberDennis Merritt19 Jul '10 - 5:44 
Hi Jonathan,
 
Thanks for the reply. I did your test from the command line, and it returns with the same error message and with errorlevel 0. But, as you suspect, the problem is permissions.
 
When I run your batch file as administrator, the environment variable gets set correctly, and I also tested delete which works.
 
My larger problem is getting it to work with Actual Installer. I run SetEnv as an external command. It works fine on install, but doesn't do anything on uninstall. I have four commands, two to set the variables, two to remove them on uninstall. It's the uninstalls that don't happen.
 
(I also tried using Actual Installer's registry options, I can create and destroy an environment variable coming and going, but I can't add it to the PATH.)
 
So I suspect Actual Installer isn't running at administrative level when entering the commands at uninstall.
 
And I've got my own mini program that simply does the sets and unsets I want, which I was going to use with a self-extracting exe and for some reason I can create a variable, add it to the path, take it off the path, but when I call RegDeleteKey to delete the variable, it says it can't find it.
 
What a nightmare. I'm too cheap to pay the outlandish fees InstallShield wants to support 64-bit platforms, which is the next step, plus I found it very difficult to work with in any case. And I've got a really simple install, copy the directory tree to Program Files, set an environment variable pointing to it, add that variable to the PATH. And then uninstall.
 
Thanks again for your reply, you can contact me directly at dennis dot merritt at amzi dot com if wish. Any help/guidance greatly appreciated.
 
Dennis
GeneralRe: SetEnv not setting envsmemberJonathan [Darka]22 Jul '10 - 0:27 
Hi Dennis,
 
One thing you could try with SetEnv is create an empty text file called "SetEnv.manifest", then paste the following XML into it:
 
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
 <assemblyIdentity version="1.0.0.0"
                   processorArchitecture="X86"
                   name="SetEnv.exe"
                   type="win32"/>
 <description>SetEnv</description>
 
 <!-- Identify the application security requirements. -->
 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
   <security>
     <requestedPrivileges>
       <requestedExecutionLevel
         level="requireAdministrator"
         uiAccess="false"/>
     </requestedPrivileges>
   </security>
 </trustInfo>
</assembly>
 
Then install this file in the same folder as SetEnv before you run the SetEnv application, this should tell Vista to use the correct permission's, it's worth a try anyway.
 
regards,

Jonathan Wilkes
Darka[DebugSPY]
 
[My Code Project Articles]

GeneralRe: SetEnv not setting envsmemberDennis Merritt22 Jul '10 - 6:16 
Thanks Jonathan. I wonder if that works on the other platforms I'm installing on? The key is to have Actual Installer call it with the right permissions on uninstall. I've actually got something that is working now, but it's very kludgy. I let Actual Installer set and unset the environment variable, and use a bit of my own code to add it and remove it from the path.
 
I find it strange that Windows will let me override the PATH with out even a wimper, but refuses to let me remove a variable I created.
 
Thanks again for your help and providing SetEnv,
Dennis
GeneralDynamic variable expansion in a multiple valued variablemembervawdEngineer7 May '10 - 15:00 
Jonathan,
 
Excellent utility. I appreciate the addition of the ~ syntax as it was not available on a previous version I had obtained a while ago. It has helped me manage multiple installations of Xilinx and TI tools using cmd scripts.
 
Perhaps you could add another example with dynamic expansion and batch file processing of a multiple valued environment variable such as
 
SetEnv -a MYPATH C:\MyStuff
 
SetEnv -a PATH %%~MYPATH~
 
I suggest this because it was not clear that it could be done based on your article.
GeneralRe: Dynamic variable expansion in a multiple valued variablememberJonathan [Darka]7 May '10 - 21:35 
I'm glad you like it, makes writing the articles worthwhile Smile | :)
 
Thanks for the suggestion, I think it's a good idea and will update the article over the weekend, it should be up in a day or so.
 
If you need any additional features you can always let me know and I'll see what I can do.
 
regards,
Jonathan

Jonathan Wilkes
Darka[DebugSPY]
 
[My Code Project Articles]

GeneralPercent sign problems... [modified]memberSir Athos2 Feb '10 - 7:30 
Hi and thanks for this great utility!
I have a suggestion: it would be easier if the special meaning of a trailing "%" would be replaced by an option, such as "-e". The problem is, besides needing to escape it in batch scripts, that it creates confusion when trying to add a variable which is not an expanded variable, and its content starts with "%".
Example:
SetEnv -a MYSUBDIR=%MYMAINDIR%\sub
What do you think?



Edit: On second thought, I was confused. I was thinking of multi string registry entries instead of expanded variables. If your variable contains "%", it's very likely you'll want it to be an expanded variable. So, to put the above in a script, you'd write:
SetEnv -a MYSUBDIR=%%%%MYMAINDIR%%\sub
 
-=Athos=-
modified on Wednesday, February 3, 2010 6:43 PM

GeneralRe: Percent sign problems...memberJonathan [Darka]4 Feb '10 - 7:55 
Hi Athos,
 
Glad you like it and thanks for the suggestion - sorry about the confusion though Smile | :)
If you do think of any new features let me know as I will be uploading a new version very soon.
 
regards,
 

Jonathan Wilkes
Darka[DebugSPY]
 
[My Code Project Articles]

QuestionHow to get the Newly changed environment settings to current process?memberg_satish10 Jun '09 - 20:44 
I have sample which will set the environment variable and broadcast the message tat setting has been changed. Except the current process which set the environment variable all the other windows are getting the new change. How to get the new changed environment for the current process.
AnswerRe: How to get the Newly changed environment settings to current process?memberJonathan [Darka]11 Jun '09 - 7:18 
Hi g_satish,
 
The problem is not with SetEnv but with Windows itself, it will not allow a process to modify the environment of it's parent process. This is why all the other windows will get an update, just not the one you call SetEnv from.
 
The only solution I am afraid is to start a new instance of the calling process.
 
Note (From the article):
 
SetEnv will broadcast a WM_SETTINGCHANGE to all of the Windows in the system. This allows other running applications such as Explorer.exe to be notified of our change. If you run SetEnv from a command prompt, then 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 prompt that you open will show the new variable/value.
 
Hope this helps,
regards,
 

Jonathan Wilkes
Darka[Xanya.net]
 
[My Code Project Articles]

GeneralDate VariablesmemberGerard Nicol11 Feb '08 - 10:02 
It is always a pain to set dates as environmental variables.
 
While you are at it you should add the ability to create variables with a strftime-like syntax.
 
say:
 
SetEnv -a today 0 "%Y-%d-%m"
SetEnv -a tomorrow +1 "%Y-%d-%m"
 
Gerard
GeneralRe: Date VariablesmemberJonathan [Darka]13 Feb '08 - 7:19 
Hi Gerard,
 
Actually I think that's a really good idea and will try to get round to implementing it in the next week.
 
thanks
 

Jonathan Wilkes
Darka[Xanya.net]

GeneralVersion 1.09memberJonathan [Darka]10 Feb '08 - 1:04 
Version 1.09 should be uploaded in the next day or so and fixes a bug on Windows 98 where it would fail to open the Autoexec.bat file sometimes due to incorrect file permissions.
 
If any other issues are found then please let me know and I will fix them as soon as I can.
 
Latest version is always available from my web site, SetEnv[^].
 
regards,
 

Jonathan Wilkes
Darka[Xanya.net]

QuestionSetenv bust under win98membermulinux6 Jan '08 - 8:41 
Works fine under XP however under win 98 which ever option you use always gives
"Error - Open Autoexec.bat : The Parameter is incorrect"
Setenv correctly identifies OS and finds Autoexec.bat on which ever drive I place it (and gives correct not found error if autoexec doesn't exist).
Can't force error 5 access denied even if making autoexec read only so looks like setenv falling over on initial opening of autoexec. My C++ not good enough to figure it out. Bug or me being stupid ?
 
Many thanks
 
Dave
GeneralRe: Setenv bust under win98memberJonathan [Darka]6 Jan '08 - 23:00 
Hi Dave,
 
Thanks for the update, I will check it out and get back to you but it might be a day or so as we've all been made redundant here and I have to get my CV up to date.
 
regards,
 


Jonathan Wilkes
Darka[Xanya.net]

GeneralRe: Setenv bust under win98membermulinux11 Jan '08 - 1:52 
Many thanks Jonathan.
I've been in same situation for 5 months here so know exactly how you feel.
 
Dave
GeneralRe: Setenv bust under win98memberJonathan [Darka]11 Jan '08 - 3:12 
Thanks for understanding,
 
I should get time on Monday to look at this as I will be a little busy the rest of the week as I am flying to the US (Arizona) on Thursday to "transfer knowledge" to the US developers that are part of the company I work for.
 
reagards,
 


Jonathan Wilkes
Darka[Xanya.net]

GeneralRe: Setenv bust under win98memberJonathan [Darka]8 Feb '08 - 3:18 
Hi Dave,
 
Finally had time to fix it, it was a permissions problem with the CreateFile() call.
Thanks for reporting it though, I'd have never spotted it myself as I don't use Windows 98 anymore.
 
I had to hunt down a copy of 98 which is why it took me so long to fix, sorry about that.
 
I have updated the CodeProject article but that will take a day or so toget posted, in the meantime you can get the latest version from my own website[^].
 
regards,
 

Jonathan Wilkes
Darka[Xanya.net]

QuestionStrange issue using backslash and dbl quote [modified]memberFreddy99913 Oct '07 - 16:55 
I have a strange issue with the following:

command: setenv -a myvar "my path\"
result : myvar = my path"

Surprise: the saved value ends with a double quote, and the backslash disappeared, thus it acts as escape char. This happens on W2003.r2 and on XP.sp2, with both SETENV and SETX, thus is it rather a Windows issue? Or do I do something wrong?
 
P.S. I did not find a way to use the above %myvar% in an IF or a FOR command. It always results in a script error.
 
Freddy

AnswerRe: Strange issue using backslash and dbl quotememberJonathan [Darka]14 Oct '07 - 21:00 
Hi Freddy,
 
You need to escape the backslash character, try this:
 
setenv -a myvar "my path\\"
 
regards,

 

Jonathan Wilkes
Darka[Xanya.net]

GeneralRe: Strange issue using backslash and dbl quotememberFreddy99915 Oct '07 - 16:23 
Jonathan,
 
thanks - this resolves it.
 
Are there other combinations of characters in which the BS is interpreted as escape char?
 
Best, Freddy
 

GeneralRe: Strange issue using backslash and dbl quotememberJonathan [Darka]15 Oct '07 - 21:59 
You basically have to backspace any character that you do not want the shell to process, such as double quotes, etc.
 
regards,
 

Jonathan Wilkes
Darka[Xanya.net]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 11 Feb 2008
Article Copyright 2005 by Jonathan [Darka]
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid