views:

13980

answers:

5

If I modify or add an environment variable I have to restart the command prompt (minor inconvenience). Is there a command I could execute that would do this without restarting CMD?

+2  A: 

By design there isn't a built in mechanism for Windows to propagate an environment variable add/change/remove to an already running cmd.exe, either from another cmd.exe or from "My Computer -> Properties ->Advanced Settings -> Environment Variables".

If you modify or add a new environment variable outside of the scope of an existing open command prompt you either need to restart the command prompt, or, manually add using SET in the existing command prompt.

The latest accepted answer shows a partial work-around by manually refreshing all the environment variables in a script. The script handles the use case of changing environment variables globally in "My Computer...Environment Variables", but if an environment variable is changed in one cmd.exe the script will not propagate it to another running cmd.exe.

Kev
If anyone has a working solution to this problem I will periodically checkin and may change the accepted answer.
spoon16
This should not be the accepted answer simply because it does not answer the question asked. this question should remain without an accepted answer until one is found.
shoosh
And annoyingly, extra instances of cmd.exe don't count. They *all* have to be killed before the change is reflected in any new cmd.exe's.
The negative comments and down marking of this answer shows how broken stack overflow is at times. Kev has given the correct answer. Just because you don't like it is no reason to mark it down.
David Arno
I really don't mind if spoon16 marks another answer as correct. But without hacking around with scripts (ala itsadok) there isn't a built in mechanism for the OS propagate an environment variable add/change in an already running cmd.exe. @Shy - calm down mate, it's only a website :).
Kev
Kev definitely does answer the question. The question is there is no built-in solution.
spoon16
+1  A: 

no, I don't think so... you can set them manually though. So you can put them in a batch file or something.

probably could make a utility/script (if someone hasn't already) that queries the registry and sets the current enviroment to be the same

Keith Nicholas
+11  A: 

You can capture the system environment variables with a vbs script, but you need a bat script to actually change the current environment variables, so this is a combined solution.

Create a file named resetvars.vbs containing this code, and save it on the path:

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("System")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
path = oEnv("PATH")

set oEnv=oShell.Environment("User")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next

path = path & ";" & oEnv("PATH")
oFile.WriteLine("SET PATH=" & path)
oFile.Close

create another file name resetvars.bat containing this code, same location:

resetvars.vbs
call "%TEMP%\resetvars.bat"

When you want to refresh the environment variables, just run resetvars.bat.


Apologetics:

The two main problems I had coming up with this solution were a. I couldn't find a straightforward way to export environment variables from a vbs script back to the command prompt, and b. the PATH environment variable is a concatenation of the user and the system PATH variables.

I'm not sure what the general rule is for conflicting variables between user and system, so I elected to make user override system, except in the PATH variable which is handled specifically.

I use the weird vbs+bat+temporary bat mechanism to work around the problem of exporting variables from vbs.

Note: this script does not delete variables.

This can probably be improved.

ADDED

If you need to export the environment from one cmd window to another, use this script (let's call it exportvars.vbs):

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("Process")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
oFile.Close

Run exportvars.vbs in the window you want to export from, then switch to the window you want to export to, and type:

"%TEMP%\resetvars.bat"
itsadok
Perhaps you can avoid the temporary file using the FOR /F "tokens=1,*" %%c IN ('resetvars.vbs') DO construct
ΤΖΩΤΖΙΟΥ
As I did say in my answer "or, manually add using SET in the existing command prompt." which is what this is effectively doing. Good answer though.
Kev
@itsadok - given that this is now the accepted answer, you should add a brief explaination at the start to put the script in context. i.e point out that it isn't possible to propagate an env var change to an open cmd.exe without manually updating as above or by restarting cmd.exe.
Kev
The script handles the use case of changing environment variables globally in "My Computer...Environment Variables", but if an environment variable is changed in one cmd.exe the script will not propagate it to another running cmd.exe which I think is probably a common scenario.
Kev
A: 

There is no straight way, as Kev said. In most cases, it is simpler to spawn another CMD box. More annoyingly, running programs are not aware of changes either (although IIRC there might be a broadcast message to watch to be notified of such change).

It have been worse: in older versions of Windows, you had to log off then log back to take in account the changes...

PhiLho
+1  A: 

Calling this function has worked for me:

VOID Win32ForceSettingsChange() { DWORD dwReturnValue; ::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue); }

Brian Weed
+1 but it only works for GUI programs.
Hugh Allen