如果修改或添加环境变量,则必须重新启动命令提示符。是否有一个命令,我可以执行,将这样做而不重新启动CMD?


当前回答

编辑:只有当您所做的环境更改是运行批处理文件的结果时,这才有效。

如果批处理文件以SETLOCAL开始,那么即使您在批处理退出前忘记调用ENDLOCAL,或者它意外中止,它也总是会在退出时解开回到原始环境。

几乎我编写的每个批处理文件都是从SETLOCAL开始的,因为在大多数情况下,我不希望环境更改的副作用仍然存在。在某些情况下,我确实希望某些环境变量的变化传播到批处理文件之外,那么我的最后一个ENDLOCAL看起来像这样:

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

其他回答

以下是Chocolatey使用的方法。

https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/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 "RefreshEnv.cmd only works from cmd.exe, please install the Chocolatey Profile to take advantage of refreshenv from PowerShell"
echo | set /p dummy="Refreshing environment variables from registry for cmd.exe. 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

    :: capture user / architecture
    SET "OriginalUserName=%USERNAME%"
    SET "OriginalArchitecture=%PROCESSOR_ARCHITECTURE%"

    :: Set these variables
    call "%TEMP%\_env.cmd"

    :: Cleanup
    del /f /q "%TEMP%\_env.cmd" 2>nul

    :: reset user / architecture
    SET "USERNAME=%OriginalUserName%"
    SET "PROCESSOR_ARCHITECTURE=%OriginalArchitecture%"

    echo | set /p dummy="Finished."
    echo .

更有可能的是,您希望已打开和/或正在运行的应用程序可以访问更新的环境变量。因此,最好和最简单的操作方法是关闭/重新打开应用程序,以便它接收更新后的环境变量。

幕后的细节是非常微妙的,但是上面的内容应该适用于大多数用例。

我喜欢巧克力之后的方法,就像匿名懦夫的回答,因为这是一个纯粹的批量处理方法。但是,它会留下一个临时文件和一些临时变量。我给自己做了一个更干净的版本。

在路径的某个地方创建一个文件refreshv .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.

在不重启当前会话的情况下,向路径中添加变量的最简单方法是打开命令提示符并输入:

PATH=(VARIABLE);%path%

并按enter键。

要检查变量是否已加载,请键入

PATH

并按enter键。但是,在重新启动之前,该变量将只是路径的一部分。

您可以使用vbs脚本捕获系统环境变量,但是需要使用bat脚本来实际更改当前环境变量,因此这是一种组合解决方案。

创建一个名为resetvars的文件。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("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

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

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

当您想要刷新环境变量时,只需运行resetvars.bat


护教学:

我提出这个解决方案时遇到的两个主要问题是

a.我找不到一个直接的方法将环境变量从vbs脚本导出回命令提示符,并且

b. PATH环境变量是用户变量和系统PATH变量的连接。

我不确定用户和系统之间的冲突变量的一般规则是什么,所以我选择让用户覆盖系统,除了在PATH变量中,它是专门处理的。

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

注意:此脚本不删除变量。

这可能是可以改进的。

添加

如果你需要将环境从一个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"