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


当前回答

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

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

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

其他回答

谢谢你提出这个非常有趣的问题,即使在2019年(事实上,更新shell cmd并不容易,因为如上所述,它是一个单一的实例),因为在windows中更新环境变量允许完成许多自动化任务,而无需手动重新启动命令行。

例如,我们使用它来允许在我们定期重新安装的大量机器上部署和配置软件。我必须承认,在软件部署期间重新启动命令行是非常不切实际的,而且需要我们找到不一定令人愉快的变通办法。 让我们来解决问题。 我们按以下步骤进行。

1 -我们有一个批处理脚本,它依次调用powershell脚本

(文件:task.cmd)。

cmd > powershell.exe -executionpolicy unlimited -File C:\path_here\refresh.ps1 .exe

2 -在此之后,刷新。ps1脚本使用注册表键(GetValueNames()等)更新环境变量。 然后,在同一个powershell脚本中,我们只需要调用新的环境变量即可。 例如,在一个典型的情况下,如果我们之前刚刚用静默命令用cmd安装了nodeJS,在函数被调用后,我们可以直接调用npm来安装,在同一个会话中,如下所示的特定包。

(文件:refresh.ps1)

function Update-Environment {
    $locations = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session  Manager\Environment',
                 'HKCU:\Environment'
    $locations | ForEach-Object {
        $k = Get-Item $_
        $k.GetValueNames() | ForEach-Object {
            $name  = $_
            $value = $k.GetValue($_)

            if ($userLocation -and $name -ieq 'PATH') {
                $env:Path += ";$value"
            } else {

                Set-Item -Path Env:\$name -Value $value
            }
        }
        $userLocation = $true
    }
}
Update-Environment
#Here we can use newly added environment variables like for example npm install.. 
npm install -g create-react-app serve

powershell脚本结束后,cmd脚本继续执行其他任务。 现在,要记住的一件事是,在任务完成后,cmd仍然不能访问新的环境变量,即使powershell脚本在它自己的会话中更新了这些变量。这就是为什么我们在powershell脚本中完成所有需要的任务,它当然可以调用与cmd相同的命令。

调用这个函数对我来说很有用:

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

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

有一个名为“setx”的命令行工具用于此作业。 它用于读取和写入env变量。 这些变量在命令窗口关闭后仍然存在。

创建或修改用户或系统环境中的环境变量,而不需要编程或脚本。setx命令还检索注册表项的值,并将它们写入文本文件。

注意:通过此工具创建或修改的变量将在以后的命令窗口中可用,但在当前CMD.exe命令窗口中不可用。所以,你必须重新开始。

如果缺少setx:

http://download.microsoft.com/download/win2000platform/setx/1.00.0.1/nt5/en-us/setx_setup.exe


或修改注册表

MSDN说:

若要以编程方式添加或修改系统环境变量,请使用add 他们去 HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ \控制会话 Manager\Environment注册表项,然后广播一个WM_SETTINGCHANGE 消息,lParam设置为字符串“环境”。 这允许应用程序(如shell)接收您的更新。

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

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

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

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

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

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