Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

My colleague and I have identical Dell workstations with Windows XP Professional x64 edition installed.

My Path environment variable starts with:

%JAVA_HOME%\bin;...

My colleague's Path variable includes the same directory, specified using the same environment variable, but it is not the first item in his Path.

If I access system properties -> environment variables and change the value of my JAVA_HOME variable, the version of java found from the command-line changes as I expect. This is starting a brand new console window, to be sure to pick up the changes.

But on my colleague's machine, it does not. He continues to find his previous version of Java until he brings up his Path variable and saves it (even if he makes no changes to it). (Again, this is when starting a brand new console window.)

I have been observing this inconsistency on Windows for about 6 months now and very curious about it. We have way too many versions of Windows in our office, so rarely have I had a chance to see this happening on two machines running the exact same OS version, until now.

What is causing this? Why does his machine not re-evaluate Path, using the new JAVA_HOME, when mine does?

(Is it because it's not the first thing in the Path? If so, how could that be, and why? I'd do more tests to check, but I think he's now fed up with it and would like to get back to work.)

share|improve this question

migrated from stackoverflow.com Aug 22 '09 at 17:20

This question came from our site for professional and enthusiast programmers.

1  
For all you guys voting to close (3 at the moment) ... if there's a dup somewhere, a comment pointing me to it sure would be nice. If it's not a dupe ... then telling me what you think is wrong with this question would also be nice. –  skiphoppy Aug 21 '09 at 18:40
1  
Perhaps because it is more a system question than a programming one, although it has a direct impact on programming, that's why I don't vote to close it... :) –  PhiLho Aug 21 '09 at 18:49
2  
Attenion close-nazis: I'd like to promote the view that if a question was appropriate on Stack Overflow before superuser.com and serverfault.com arrived, then it is still appropriate today. This is a programming question. –  skiphoppy Aug 21 '09 at 19:12
    
Do you mean that programmers are only users of Windows, who may have this problem? Shut up you, programmer-nazi! Secondly, before more appropriate Q&A site arrived, you had no option to post question here. The hospitality of SO must be not an argument for abusing it. –  Val Jul 7 '13 at 15:54
add comment

13 Answers 13

Your path is the concatenation of the system path followed by the user path. Additionally, system environment variables may not contain references to user environment variables, and any such references will not be expanded. To get the desired result, insert the reference to %JAVA_HOME% in the user environment variable PATH, or create such a variable if it doesn't already exist.

Perhaps a simplified example will make this clearer. Suppose the SYSTEM environment is

ProgramFiles = C:\Program Files
SystemRoot = C:\WINDOWS
PATH = %SystemRoot%\SYSTEM32

and the User JSmith's environment is

JAVA_HOME = %ProgramFiles%\Java\bin
USERPROFILE = C:\USERS\JSmith
PATH = %JAVA_HOME%\bin;%USERPROFILE%\bin

then the resulting path would be

C:\WINDOWS\SYSTEM32;C:\Program Files\Java\bin;C:\Users\JSmith\bin

as desired.

share|improve this answer
add comment

There is a definite problem with expanding environment variables within the PATH variable when the variable expands to a path that contains spaces.

We created our own system level variables like "OUR_ROOT=c:\MyRoot" and then used it in system PATH like "PATH=;%OUR_ROOT%\bin;" and that gets expanded correctly to "PATH=;c:\MyRoot\bin;". So far no problem.

But, on Windows 7 (32-bit), I had a product install itself and create system environment variables like this:

STUDIO_BIN=C:\program files\Company Name\Product Name 10.4\bin

and it added it to the system PATH variable:

PATH=<other path elements>;%STUDIO_BIN%;<more path elements>

But the PATH values shown in CMD contained "%STUDIO_BIN%;" and not the expanded path. The value in My Computer > Properties > Advanced > Env.Vars remained unexpanded as well. This meant I couldn't run programs that required a DLL in that directory.

By just changing STUDIO_BIN (via My Computer>Properties>Advanced ...>Env Vars) to a name without embedded spaces :

STUDIO_BIN=C:\ProductName\bin

and then restarting the CMD window, the PATH is now:

PATH=<other path elements>;C:\ProductName\bin;<more path elements>

Another solution is to sufficiently edit the system variable you are using in the PATH using the My Computer > Properties > Advanced... > Environment Variables dialog. I tried adding a character and removing it to make a 'change' and then OK'd out, started a new CMD prompt and PATH was NOT correctly expanded. I then tried deleting part of the path so it was

STUDIO_BIN=C:\Program Files\Company Name

(omitting "Product Name 10.4") and lo, and behold, the next CMD prompt showed PATH with STUDIO_BIN properly expanded!

Strangely enough, if I went back in and added the "Product Name 10.4" to STUDIO_BIN (including all the spaces that were originally there before I started mucking with it) and PATH was STILL correctly expanded.

Evidently with enough change to its contents, the PATH variable undergoes some extra processing in the Environment Variables dialog that allows it to work. Processing that's not done when the variable was added by the product's installer (which probably just modified PATH in the registry directly).

I'm almost positive this was a problem with XP as well. It just resurfaced for me in Windows 7 as I was putting together a new development machine. Apparently it has not been fixed by Microsoft.

Apparently even MS defined variables like %ProgramFiles% won't expand correctly in the PATH.

This page provides a possible answer if you're setting PATH via the command-line or batch file. (Enclose the whole command after SET in quotation marks.) I don't know what installer the product I installed used to set the environment variables, but it evidently went around whatever processing is needed to properly expand the paths with spaces.

So - to summarize, you can either:

  • change the paths (and move all associated files) to paths without spaces, or

  • edit the variables that are failing to expand in the Environment Variables dialog (changing them enough to get them to process correctly - I'm not positive how much is enough).

share|improve this answer
    
+1 for Microsoft answers. –  leewangzhong Apr 28 at 2:33
add comment

Check in the Windows registry under this key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

IF the environment variable needs to be expanded (here: %JAVA_HOME%)

then the variable must be set as a REG_EXPAND_SZ value.

If using reg.exe via command-line to add/edit registry values, it defaults to type REG_SZ. Specify the type REG_EXPAND_SZ by using the reg add /t REG_EXPAND_SZ option.

share|improve this answer
    
yep ... this is one of those settings that I always seem to forget ... pesky registry ;-) –  Eddie B Sep 6 '13 at 5:20
add comment

there are two levels of environment variables, global and user. If he has %Java_home% set as a user environment variable but is instead changing the global one, he won't see any difference.

share|improve this answer
add comment

i asked this on the Microsoft forums in March 2009, and never got it resolved:

How to use %ProgramFiles% in the Path environment variable?:


I'm trying to add a folder to the system's Path environment variable.

i want to add %ProgramFiles%\SysInternals

to the existing path variable:

C:\PROGRA~1\Borland\Delphi5\Projects\Bpl;C:\PROGRA~1\Borland\Delphi5\Bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Program Files\Microsoft SQL Server\80\Tools\BINN;C:\Program Files\Microsoft SQL Server\80\Tools\Binn\;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Microsoft SQL Server\90\DTS\Binn\;C:\Program Files\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\

So i go into place where you edit it:

alt text

And i add my variable to the path:

%ProgramFiles%\SysInternals;C:\PROGRA~1\Borland\Delphi5\Projects\Bpl; (snip)

Then opening a new command prompt window the environment variable is not replaced with it's actual value:

Path=%ProgramFiles%\SysInternals;C:\PROGRA~1\Borland\Delphi5\Projects\Bpl(snip)>

Which you can see in the following screenshot:

alt text


But to answer your question: i don't know. Seems like it cannot be done.

share|improve this answer
add comment

Make sure there are no spaces in the PATH when you are defining your own user environment variables. eg: C:\GNAT\bin; C:\GNAT\include wont work, because of the space between the ";" and "C:\GNAT\include".

share|improve this answer
add comment

Add the environment variables whilst logged onto the /console session using MSTSC.

Reboot the machine and you will find your environment variables will have persisted.

There appears to be a quirk in the O/S depending on how you were connected to the machine when you attempted to change the environment variable.

share|improve this answer
add comment

It might be related to the "delayed environment variable expansion" feature (or lack thereof), or perhaps you can take advantage of this feature to always have a correct solution.

from a cmd prompt

set /?

and read the section describing "delayed environment variable expansion", which includes a small example to test

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "%VAR%" == "after" @echo If you see this, it worked
)

If you don't get the echo line, then that might explain it...

If, however, you start your cmd.exe with /V option, then you can use "!" instead of "%", which changes the behaivior

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

For me (running on XP), the 1st script did not work, but the second version did (with cmd.exe /V)

share|improve this answer
add comment

I've had the same problem, and I know how to fix it, its lame.

Just edit your PATH again, but make no change, and re-save PATH. For some reason this causes all nested environment variable references to get re-evaluated.

If it doesn't work do it a few more times, somehow it just works itself out.

share|improve this answer
add comment

PATH is the concatenation of the user PATH variable followed by the global PATH variable. To use one variables within another, the former must already be set. User variables are set before global variables (at least here on my 64-bit Windows 7), thus you can't use global variables in you user PATH variable. Additionally, variables are set in alphabetical order, so you must also keep that in mind.

share|improve this answer
add comment

Perhaps you are doing it wrong?

I tried with Windows XP Pro SP3 (32bit). I do have a path with several occurrences of %JAVA_HOME% (and %JAVAFX_HOME%, etc.). I go to command line, type PATH, I see the variables expanded. Good.

I change the value of JAVA_HOME. Back to the same command line window, PATH again, same value... as expected (by experience!).

I open a new command line window, type PATH, gotcha, I see the new value.

Not sure what is the exact mechanism there, but it seems that any running program, including cmd.exe, capture the values of environment variables at starting time, and doesn't look back... (although I believe a good behaved program can listen for env changes, not too sure though).

It might be seen as a feature or a bug or annoyance, but that's the way it works. Hey, at least, unlike Win9X times, we don't have to reboot the computer! And unlike NT times (IIRC), you don't have to log out and back.

Why the inconsistency? The ways of Microsoft are inscrutable... :-P

share|improve this answer
    
This isn't it. After the change we're testing in a fresh command window. We're aware of the fact that changing the system values doesn't change the values for running processes. –  skiphoppy Aug 21 '09 at 19:11
    
OK, hence the 'perhaps'... :-) And my explanation doesn't cover the inconsistency, but might be useful to some newbie... :-P I mostly wanted to point out that variable expansion works everywhere in the path... for some systems! (all those I used... always 32bit). –  PhiLho Aug 22 '09 at 8:38
add comment

I do believe what Windows fails to expand a variable in PATH because it thinks what it not defined yet. Consider:

REM Ensure variable is undefined
SET UNDEFINED=
REM And then try to expand it
ECHO UNDEFINED=%UNDEFINED%

This hypothesis conforms with my other observation - adding %ProgramFiles%\Something to the users PATH will always result in expected expansion of %ProgramFiles%, given it has been defined in machine environment at the time of variable change notification (due loading order - MACHINE and then USER). But when you modify machine environment correct variable expansion only happens at the boot time (right now I have no idea how and why this not happens on the regular basis).

share|improve this answer
add comment

I have resolved setting the environment variables in System > Advanced Settings > Environment Variables.

There's two panels, User and Global variables (user is your Windows username) and System Variables are Global variables, so if you set 'New' from User variables, such as JAVA_HOME and put your path below, you will set variables even if your global path have program files inside folder.

share|improve this answer
add comment

protected by Nifle Nov 19 '12 at 15:15

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.