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


当前回答

根据设计,Windows没有内置机制来将环境变量添加/更改/删除传播到已经运行的cmd.exe中,无论是从另一个cmd.exe还是从“我的电脑->属性->高级设置->环境变量”。

如果在现有的开放命令提示符范围之外修改或添加新的环境变量,则需要重新启动命令提示符,或者在现有的命令提示符中使用SET手动添加。

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

其他回答

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

如果批处理文件以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 .

为了解决这个问题,我使用setx和set改变了环境变量,然后重新启动explorer.exe的所有实例。这样,随后启动的任何进程都将拥有新的环境变量。

我的批处理脚本这样做:

setx /M ENVVAR "NEWVALUE"
set ENVVAR="NEWVALUE"

taskkill /f /IM explorer.exe
start explorer.exe >nul
exit

这种方法的问题是当前打开的所有资源管理器窗口都将被关闭,这可能是一个坏主意-但请参阅Kev的帖子来了解为什么这是必要的

在Windows 7/8/10上,你可以安装Chocolatey,它有一个内置的脚本。

安装Chocolatey后,只需输入RefreshEnv.cmd。

重新启动资源管理器为我做到了这一点,但只对新的cmd终端。

我设置路径的终端已经可以看到新的path变量了(在Windows 7中)。

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