是否有一个命令来刷新Windows中的命令提示符下的环境variables?

如果我修改或添加一个环境variables,我必须重新启动命令提示符。 有没有一个命令,我可以执行这将做到这一点,而无需重新启动CMD?

您可以使用vbs脚本捕获系统环境variables,但是需要使用bat脚本来实际更改当前环境variables,所以这是一个综合解决scheme。

创build一个名为resetvars.vbs的文件, resetvars.vbs包含此代码,并将其保存在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 

创build包含此代码的另一个文件名resetvars.bat,位置相同:

 @echo off %~dp0resetvars.vbs call "%TEMP%\resetvars.bat" 

当你想刷新环境variables,只需运行resetvars.bat。


护教

我提出这个解决scheme的两个主要问题是

一个。 我无法find一个简单的方法将环境variables从vbs脚本导出回命令提示符

PATH环境variables是用户和系统PATHvariables的串联。

我不确定用户和系统之间冲突variables的一般规则是什么,所以我select使用户覆盖系统,除了在PATHvariables中被特别处理。

我使用奇怪的vbs + bat +临时bat机制来解决从vbs导出variables的问题。

注意 :这个脚本不会删除variables。

这可能可以改善。

添加

如果您需要将环境从一个cmd窗口导出到另一个窗口,请使用以下脚本(我们称之为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 

在要导出的窗口中运行exportvars.vbs ,然后切换到要导出的窗口,然后键入:

 "%TEMP%\resetvars.bat" 

这是巧克力使用的。

https://github.com/chocolatey/chocolatey/blob/master/src/redirects/RefreshEnv.cmd

 @echo off :: :: RefreshEnv.cmd :: :: Batch file to read environment variables from registry and :: set session variables to these values. :: :: With this batch file, there should be no need to reload command :: environment every time you want environment changes to propagate echo | set /p dummy="Reading environment variables from registry. Please wait... " goto main :: Set one environment variable from registry key :SetFromReg "%WinDir%\System32\Reg" QUERY "%~1" /v "%~2" > "%TEMP%\_envset.tmp" 2>NUL for /f "usebackq skip=2 tokens=2,*" %%A IN ("%TEMP%\_envset.tmp") do ( echo/set %~3=%%B ) goto :EOF :: Get a list of environment variables from registry :GetRegEnv "%WinDir%\System32\Reg" QUERY "%~1" > "%TEMP%\_envget.tmp" for /f "usebackq skip=2" %%A IN ("%TEMP%\_envget.tmp") do ( if /I not "%%~A"=="Path" ( call :SetFromReg "%~1" "%%~A" "%%~A" ) ) goto :EOF :main echo/@echo off >"%TEMP%\_env.cmd" :: Slowly generating final file call :GetRegEnv "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" >> "%TEMP%\_env.cmd" call :GetRegEnv "HKCU\Environment">>"%TEMP%\_env.cmd" >> "%TEMP%\_env.cmd" :: Special handling for PATH - mix both User and System call :SetFromReg "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" Path Path_HKLM >> "%TEMP%\_env.cmd" call :SetFromReg "HKCU\Environment" Path Path_HKCU >> "%TEMP%\_env.cmd" :: Caution: do not insert space-chars before >> redirection sign echo/set Path=%%Path_HKLM%%;%%Path_HKCU%% >> "%TEMP%\_env.cmd" :: Cleanup del /f /q "%TEMP%\_envset.tmp" 2>nul del /f /q "%TEMP%\_envget.tmp" 2>nul :: Set these variables call "%TEMP%\_env.cmd" echo | set /p dummy="Done" echo . 

根据devise,没有内置的机制让Windows将一个环境variablesadd / change / remove传播到已经运行的cmd.exe,或者从另一个cmd.exe或从“我的电脑 – >属性 – >高级设置 -环境variables”。

如果修改或添加新的环境variables超出现有打开命令提示符的范围,则需要重新启动命令提示符,或者在现有命令提示符下手动添加使用SET。

最新接受的答案通过手动刷新脚本中的所有环境variables来显示部分解决方法。 脚本在“我的电脑…环境variables”中处理全局更改环境variables的用例,但如果在一个cmd.exe中更改了环境variables,则该脚本不会将其传播到另一个正在运行的cmd.exe。

这适用于Windows 7: SET PATH=%PATH%;C:\CmdShortcuts

通过键入echo%PATH%进行testing,它工作,很好。 也设置,如果你打开一个新的CMD,不需要那些麻烦的重新启动:)

我终于find一个更简单的解决scheme之前遇到了这个答案

只需在任务pipe理器中重新启动explorer.exe

我没有testing,但你可能还需要重新打开你的命令提示符。

在这里信任Timo Huovinen : 虽然成功安装了Node,但是Node没有被识别 (如果这对你有帮助,请给这个人的评论信用)。

使用“setx”并重新启动cmd提示符

这个作业有一个名为“ setx ”的命令行工具。 它用于读写 envvariables。 命令窗口closures后,variables仍然存在。

它“在用户或系统环境中创build或修改环境variables,而不需要编程或编写脚本。setx命令还检索registry项的值并将其写入文本文件。

注意:通过此工具创build或修改的variables将在将来的命令窗口中可用,但不在当前的CMD.exe命令窗口中。 所以,你必须重新启动。

如果setx缺失:


或者修改registry

MSDN说:

要以编程方式添加或修改系统环境variables,请将它们添加到HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environmentregistry项中,然后广播一个WM_SETTINGCHANGE消息,并将lParam设置为string“ Environment ”。

这使应用程序(如shell)能够获取更新。

调用这个函数对我有用:

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

在Windows 7/8/10中,

只需input“refreshenv”而不用引号。 它适用于我的机器win8.1

我想出的最好的方法是做一个registry查询。 这是我的例子。

在我的例子中,我使用添加了新环境variables的batch file进行了安装。 一旦安装完成,我需要做这些事情,但是无法用这些新variables产生新的进程。 我testing了产生另一个资源pipe理器窗口,并调用回cmd.exe,这工作,但在Vista和Windows 7上,资源pipe理器只作为一个单一的实例运行,通常作为人login。这将失败与自动化,因为我需要我的pipe理员信用不pipe是从本地系统运行还是作为pipe理员运行。 对此的限制是它不处理像path这样的事情,这只适用于简单的环境variables。 这使我可以使用批处理过渡到一个目录(包含空格)并复制文件运行.exes等。这是今天写的可能在stackoverflow.com上的资源

原始批次调用新的批次:

testenvget.cmd SDROOT(或任何variables)

 @ECHO OFF setlocal ENABLEEXTENSIONS set keyname=HKLM\System\CurrentControlSet\Control\Session Manager\Environment set value=%1 SET ERRKEY=0 REG QUERY "%KEYNAME%" /v "%VALUE%" 2>NUL| FIND /I "%VALUE%" IF %ERRORLEVEL% EQU 0 ( ECHO The Registry Key Exists ) ELSE ( SET ERRKEY=1 Echo The Registry Key Does not Exist ) Echo %ERRKEY% IF %ERRKEY% EQU 1 GOTO :ERROR FOR /F "tokens=1-7" %%A IN ('REG QUERY "%KEYNAME%" /v "%VALUE%" 2^>NUL^| FIND /I "%VALUE%"') DO ( ECHO %%A ECHO %%B ECHO %%C ECHO %%D ECHO %%E ECHO %%F ECHO %%G SET ValueName=%%A SET ValueType=%%B SET C1=%%C SET C2=%%D SET C3=%%E SET C4=%%F SET C5=%%G ) SET VALUE1=%C1% %C2% %C3% %C4% %C5% echo The Value of %VALUE% is %C1% %C2% %C3% %C4% %C5% cd /d "%VALUE1%" pause REM **RUN Extra Commands here** GOTO :EOF :ERROR Echo The the Enviroment Variable does not exist. pause GOTO :EOF 

还有另一种方法,我从各种不同的想法。 请参阅下文。 这基本上会从registry中获取最新的pathvariables,但是,这将导致一些问题,因为registry查询本身会给variables,这意味着处处有一个variables,这是行不通的,所以要解决这个问题,我基本上双倍的path。 非常讨厌。 设置Path =%Path%; C:\ Program Files \ Software …. \

不pipe这里是新的batch file,请小心使用。

 @ECHO OFF SETLOCAL ENABLEEXTENSIONS set org=%PATH% for /f "tokens=2*" %%A in ('REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path ^|FIND /I "Path"') DO ( SET path=%%B ) SET PATH=%org%;%PATH% set path 

可以通过在指定的进程本身内覆盖环境表来执行此操作。

作为概念certificate,我编写了这个示例应用程序,它只是在cmd.exe过程中编辑一个(已知的)环境variables:

 typedef DWORD (__stdcall *NtQueryInformationProcessPtr)(HANDLE, DWORD, PVOID, ULONG, PULONG); int __cdecl main(int argc, char* argv[]) { HMODULE hNtDll = GetModuleHandleA("ntdll.dll"); NtQueryInformationProcessPtr NtQueryInformationProcess = (NtQueryInformationProcessPtr)GetProcAddress(hNtDll, "NtQueryInformationProcess"); int processId = atoi(argv[1]); printf("Target PID: %u\n", processId); // open the process with read+write access HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, 0, processId); if(hProcess == NULL) { printf("Error opening process (%u)\n", GetLastError()); return 0; } // find the location of the PEB PROCESS_BASIC_INFORMATION pbi = {0}; NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL); if(status != 0) { printf("Error ProcessBasicInformation (0x%8X)\n", status); } printf("PEB: %p\n", pbi.PebBaseAddress); // find the process parameters char *processParamsOffset = (char*)pbi.PebBaseAddress + 0x20; // hard coded offset for x64 apps char *processParameters = NULL; if(ReadProcessMemory(hProcess, processParamsOffset, &processParameters, sizeof(processParameters), NULL)) { printf("UserProcessParameters: %p\n", processParameters); } else { printf("Error ReadProcessMemory (%u)\n", GetLastError()); } // find the address to the environment table char *environmentOffset = processParameters + 0x80; // hard coded offset for x64 apps char *environment = NULL; ReadProcessMemory(hProcess, environmentOffset, &environment, sizeof(environment), NULL); printf("environment: %p\n", environment); // copy the environment table into our own memory for scanning wchar_t *localEnvBlock = new wchar_t[64*1024]; ReadProcessMemory(hProcess, environment, localEnvBlock, sizeof(wchar_t)*64*1024, NULL); // find the variable to edit wchar_t *found = NULL; wchar_t *varOffset = localEnvBlock; while(varOffset < localEnvBlock + 64*1024) { if(varOffset[0] == '\0') { // we reached the end break; } if(wcsncmp(varOffset, L"ENVTEST=", 8) == 0) { found = varOffset; break; } varOffset += wcslen(varOffset)+1; } // check to see if we found one if(found) { size_t offset = (found - localEnvBlock) * sizeof(wchar_t); printf("Offset: %Iu\n", offset); // write a new version (if the size of the value changes then we have to rewrite the entire block) if(!WriteProcessMemory(hProcess, environment + offset, L"ENVTEST=def", 12*sizeof(wchar_t), NULL)) { printf("Error WriteProcessMemory (%u)\n", GetLastError()); } } // cleanup delete[] localEnvBlock; CloseHandle(hProcess); return 0; } 

示例输出:

 >set ENVTEST=abc >cppTest.exe 13796 Target PID: 13796 PEB: 000007FFFFFD3000 UserProcessParameters: 00000000004B2F30 environment: 000000000052E700 Offset: 1528 >set ENVTEST ENVTEST=def 

笔记

这种方法也仅限于安全限制。 如果目标是在较高的海拔或较高的帐户(如SYSTEM)运行,那么我们将无权编辑其内存。

如果你想这样做到一个32位的应用程序,上面的硬编码偏移将分别变为0x10和0x48。 这些偏移量可以通过在debugging器中抛出_PEB和_RTL_USER_PROCESS_PARAMETERS结构来find(例如,在WinDbg dt _PEBdt _RTL_USER_PROCESS_PARAMETERS

要将概念certificate转换为OP需要的内容,只需枚举当前系统和用户环境variables(如@ tsadok的答案所记载),并将整个环境表写入目标进程的内存。

编辑:环境块的大小也存储在_RTL_USER_PROCESS_PARAMETERS结构中,但内存分配在进程的堆上。 所以从外部过程来看,我们将无法调整它的大小,并使其变大。 我使用VirtualAllocEx为环境存储的目标进程分配额外的内存,并能够设置和读取一个全新的表。 不幸的是,任何试图从正常的方式修改环境的尝试都会崩溃并烧毁,因为地址不再指向堆(它会在RtlSizeHeap中崩溃)。

环境variables保存在HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet \ Control \ Session Manager \ Environment中。

许多有用的环境,例如Path,被存储为REG_SZ。 有几种方法可以访问registry,包括REGEDIT:

REGEDIT /E &lt;filename&gt; "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment"

输出以幻数开始。 所以用find命令search它需要input和redirect: type <filename> | findstr -c:\"Path\" type <filename> | findstr -c:\"Path\"

所以,如果你只想刷新当前命令会话中的pathvariables和系统属性中的内容,那么下面的批处理脚本就可以正常工作:

RefreshPath.cmd:


     @echoclosures

     REM此解决scheme请求提升以便从registry读取。

    如果存在%temp%\ env.reg del%temp%\ env.reg / q / f

     REGEDIT / E%temp%\ env.reg“HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ Control \ Session Manager \ Environment”

    如果不存在%temp%\ env.reg(
       回声“无法将registry写入临时位置”
       出口1
        )

     SETLOCAL EnableDelayedExpansion

     ('type%temp%\ env.reg ^ | findstr -c:\“Path \”=')do(for / f“tokens = 1,2 * delims ==”%%
        set upath = %%〜j
       回声!upath:\\ = \!  >%TEMP%\ NEWPATH
        )

      ENDLOCAL

      for / f“tokens = *”%% i in(%temp%\ newpath)do set path = %% i 

尝试以pipe理员身份打开新的命令提示符。 这对我在Windows 10上工作。(我知道这是一个旧的答案,但我不得不分享这个,因为不得不写一个VBS脚本只是为了这个是荒谬的)。

我在批处理脚本中使用以下代码:

 if not defined MY_ENV_VAR ( setx MY_ENV_VAR "VALUE" > nul set MY_ENV_VAR=VALUE ) echo %MY_ENV_VAR% 

通过在SETX之后使用SET ,可以直接使用“本地”variables而无需重新启动命令窗口。 在下一次运行中,将使用环境variables。

只需重新启动explorer.exe >>testing胜利8 X64

在不重新启动当前会话的情况下,将variables添加到path的最简单方法是打开命令提示符并键入:

 PATH=(VARIABLE);%path% 

然后按回车

检查你的variables是否加载,键入

 PATH 

然后按回车 。 但是,只有重新启动之前,variables才会成为path的一部分。

正如Kev所说,没有一条直线。 在大多数情况下,产生另一个CMD盒子更简单。 更烦人的是,正在运行的程序也不知道有任何变化(尽pipeIIRC可能有广播消息要注意这样的变化)。

更糟糕的是:在较旧版本的Windows中,您必须注销然后重新login以考虑更改…

我喜欢巧克力的方法,正如匿名懦夫的回答中所发表的,因为这是一种纯粹的批量方法。 但是,它留下了临时文件和一些临时variables。 我为自己做了一个更清洁的版本。

在你的PATH某个地方build立一个文件refreshEnv.bat 。 通过执行refreshEnv刷新您的控制台环境。

 @ECHO OFF REM Source found on https://github.com/DieterDePaepe/windows-scripts REM Please share any improvements made! REM Code inspired by http://stackoverflow.com/questions/171588/is-there-a-command-to-refresh-environment-variables-from-the-command-prompt-in-w IF [%1]==[/?] GOTO :help IF [%1]==[/help] GOTO :help IF [%1]==[--help] GOTO :help IF [%1]==[] GOTO :main ECHO Unknown command: %1 EXIT /b 1 :help ECHO Refresh the environment variables in the console. ECHO. ECHO refreshEnv Refresh all environment variables. ECHO refreshEnv /? Display this help. GOTO :EOF :main REM Because the environment variables may refer to other variables, we need a 2-step approach. REM One option is to use delayed variable evaluation, but this forces use of SETLOCAL and REM may pose problems for files with an '!' in the name. REM The option used here is to create a temporary batch file that will define all the variables. REM Check to make sure we don't overwrite an actual file. IF EXIST %TEMP%\__refreshEnvironment.bat ( ECHO Environment refresh failed! ECHO. ECHO This script uses a temporary file "%TEMP%\__refreshEnvironment.bat", which already exists. The script was aborted in order to prevent accidental data loss. Delete this file to enable this script. EXIT /b 1 ) REM Read the system environment variables from the registry. FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"`) DO ( REM /I -> ignore casing, since PATH may also be called Path IF /I NOT [%%I]==[PATH] ( ECHO SET %%I=%%K>>%TEMP%\__refreshEnvironment.bat ) ) REM Read the user environment variables from the registry. FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY HKCU\Environment`) DO ( REM /I -> ignore casing, since PATH may also be called Path IF /I NOT [%%I]==[PATH] ( ECHO SET %%I=%%K>>%TEMP%\__refreshEnvironment.bat ) ) REM PATH is a special variable: it is automatically merged based on the values in the REM system and user variables. REM Read the PATH variable from the system and user environment variables. FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH`) DO ( ECHO SET PATH=%%K>>%TEMP%\__refreshEnvironment.bat ) FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY HKCU\Environment /v PATH`) DO ( ECHO SET PATH=%%PATH%%;%%K>>%TEMP%\__refreshEnvironment.bat ) REM Load the variable definitions from our temporary file. CALL %TEMP%\__refreshEnvironment.bat REM Clean up after ourselves. DEL /Q %TEMP%\__refreshEnvironment.bat ECHO Environment successfully refreshed. 

我使用这个Powershell脚本来添加到PATHvariables。 有一点调整,它可以在你的情况下工作,我相信。

 #REQUIRES -Version 3.0 if (-not ("win32.nativemethods" -as [type])) { # import sendmessagetimeout from win32 add-type -Namespace Win32 -Name NativeMethods -MemberDefinition @" [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout( IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult); "@ } $HWND_BROADCAST = [intptr]0xffff; $WM_SETTINGCHANGE = 0x1a; $result = [uintptr]::zero function global:ADD-PATH { [Cmdletbinding()] param ( [parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0)] [string] $Folder ) # See if a folder variable has been supplied. if (!$Folder -or $Folder -eq "" -or $Folder -eq $null) { throw 'No Folder Supplied. $ENV:PATH Unchanged' } # Get the current search path from the environment keys in the registry. $oldPath=$(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path # See if the new Folder is already in the path. if ($oldPath | Select-String -SimpleMatch $Folder){ return 'Folder already within $ENV:PATH' } # Set the New Path and add the ; in front $newPath=$oldPath+';'+$Folder Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -ErrorAction Stop # Show our results back to the world return 'This is the new PATH content: '+$newPath # notify all windows of environment block change [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [uintptr]::Zero, "Environment", 2, 5000, [ref]$result) } function global:REMOVE-PATH { [Cmdletbinding()] param ( [parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0)] [String] $Folder ) # See if a folder variable has been supplied. if (!$Folder -or $Folder -eq "" -or $Folder -eq $NULL) { throw 'No Folder Supplied. $ENV:PATH Unchanged' } # add a leading ";" if missing if ($Folder[0] -ne ";") { $Folder = ";" + $Folder; } # Get the Current Search Path from the environment keys in the registry $newPath=$(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path # Find the value to remove, replace it with $NULL. If it's not found, nothing will change and you get a message. if ($newPath -match [regex]::Escape($Folder)) { $newPath=$newPath -replace [regex]::Escape($Folder),$NULL } else { return "The folder you mentioned does not exist in the PATH environment" } # Update the Environment Path Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -ErrorAction Stop # Show what we just did return 'This is the new PATH content: '+$newPath # notify all windows of environment block change [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [uintptr]::Zero, "Environment", 2, 5000, [ref]$result) } # Use ADD-PATH or REMOVE-PATH accordingly. #Anything to Add? #Anything to Remove? REMOVE-PATH "%_installpath_bin%" 

Restarting explorer did this for me, but only for new cmd terminals.

The terminal I set the path could see the new Path variable already (in Windows 7).

 taskkill /f /im explorer.exe && explorer.exe 

The confusing thing might be that there are a few places to start the cmd from. In my case I ran cmd from windows explorer and the environment variables did not change while when starting cmd from the "run" (windows key + r) the environment variables were changed .

In my case I just had to kill the windows explorer process from the task manager and then restart it again from the task manager .

Once I did this I had access to the new environment variable from a cmd that was spawned from windows explorer.

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

Edit: this only works if the environment changes you're doing are as a result of running a batch file.

If a batch file begins with SETLOCAL then it will always unravel back to your original environment on exit even if you forget to call ENDLOCAL before the batch exits, or if it aborts unexpectedly.

Almost every batch file I write begins with SETLOCAL since in most cases I don't want the side-effects of environment changes to remain. In cases where I do want certain environment variable changes to propagate outside the batch file then my last ENDLOCAL looks like this:

 ENDLOCAL & ( SET RESULT1=%RESULT1% SET RESULT2=%RESULT2% ) 

If it concerns just one (or a few) specific vars you want to change, I think the easiest way is a workaround : just set in in your environment AND in your current console session

  • Set will put the var in your current session
  • SetX will put the var in the environment, but NOT in your current session

I have this simple batch script to change my Maven from Java7 to Java8 (which are both env. vars) The batch-folder is in my PATH var so I can always call ' j8 ' and within my console and in the environment my JAVA_HOME var gets changed:

j8.bat:

 @echo off set JAVA_HOME=%JAVA_HOME_8% setx JAVA_HOME "%JAVA_HOME_8%" 

Till now I find this working best and easiest. You probably want this to be in one command, but it simply isn't there in Windows…

To solve this I have changed the environment variable using BOTH setx and set, and then restarted all instances of explorer.exe. This way any process subsequently started will have the new environment variable.

My batch script to do this:

 setx /M ENVVAR "NEWVALUE" set ENVVAR="NEWVALUE" taskkill /f /IM explorer.exe start explorer.exe >nul exit 

The problem with this approach is that all explorer windows that are currently opened will be closed, which is probably a bad idea – But see the post by Kev to learn why this is necessary

Or you can just do it manually via

To view or change environment variables: Right-click My Computer, and then click Properties. Click the Advanced tab. Click Environment variables. Click one the following options, for either a user or a system variable: Click New to add a new variable name and value. Click an existing variable, and then click Edit to change its name or value. Click an existing variable, and then click Delete to remove it. http://support.microsoft.com/kb/310519

Windows XP Environment variables

 %ALLUSERSPROFILE% (%PROGRAMDATA%) C:\Documents and Settings\All Users %APPDATA% C:\Documents and Settings\{username}\Application Data %COMPUTERNAME% {computername} %COMMONPROGRAMFILES% C:\Program Files\Common Files %COMMONPROGRAMFILES(x86)% C:\Program Files (x86)\Common Files %COMSPEC% C:\Windows\System32\cmd.exe %HOMEDRIVE% C: %HOMEPATH% \Documents and Settings\{username} %LOCALAPPDATA% Not available %LOGONSERVER% \\{domain_logon_server} %PATH% C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;{plus program paths} %PATHEXT% .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.WSF;.WSH %PROGRAMFILES% C:\Program Files %PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version) %PROMPT% Code for current command prompt format. Code is usually $P$G %SystemDrive% C: %SystemRoot% The Windows directory, usually C:\Windows, formerly C:\WINNT %TEMP% and %TMP% C:\Documents and Settings\{username}\Local Settings\Temp %USERDOMAIN% {userdomain} %USERNAME% {username} %USERPROFILE% C:\Documents and Settings\{username} %WINDIR% C:\Windows %PUBLIC% %PROGRAMDATA% Only available in Windows Vista and newer versions %PSModulePath% 

Windows 7 Environment variables

 %ALLUSERSPROFILE% (%PROGRAMDATA%) C:\ProgramData %APPDATA% C:\Users\{username}\AppData\Roaming %COMPUTERNAME% {computername} %COMMONPROGRAMFILES% C:\Program Files\Common Files %COMMONPROGRAMFILES(x86)% C:\Program Files (x86)\Common Files %COMSPEC% C:\Windows\System32\cmd.exe %HOMEDRIVE% C: %HOMEPATH% \Users\{username} %LOCALAPPDATA% C:\Users\{username}\AppData\Local %LOGONSERVER% \\{domain_logon_server} %PATH% C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;{plus program paths} %PATHEXT% .com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc %PROGRAMFILES% C:\Program Files %PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version) %PROMPT% Code for current command prompt format. Code is usually $P$G %SystemDrive% C: %SystemRoot% C:\Windows %TEMP% and %TMP% C:\Users\{username}\AppData\Local\Temp %USERDOMAIN% {userdomain} %USERNAME% {username} %USERPROFILE% C:\Users\{username} %WINDIR% C:\Windows %PUBLIC% C:\Users\Public %PROGRAMDATA% C:\ProgramData %PSModulePath% %SystemRoot%\system32\WindowsPowerShell\v1.0\Modules\ 

http://www.binbert.com/blog/2010/09/default-environment-variable-values-of-windows-7-xp/

希望这可以帮助。

Just type "# -r" (without quotes # with -r option) in your terminal. And you're all set to default paths 🙂