我正在尝试使用 powershell 通过以下方式更新 Windows 系统路径:
$oldpath = (Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
$newpath = "$oldpath;C:\nuget"
Write-Output "PATH:$newpath"
Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -Force
Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH
似乎有效,Get-ItemProperty 确实显示“C:\nuget”已添加到路径中。问题是,然后我启动一个新的 powershell 控制台或命令行控制台,并输入“nuget”,我仍然得到“术语‘nuget’未被识别为 cmdlet、函数、脚本文件或可操作程序的名称”
在新的 powershell 控制台中,如果我重新运行 Get-ItemProperty,它会显示新路径存在,但它不会立即在当前用户会话中生效。如果我在 cmd 控制台中运行“set”,则 PATH 变量中不存在新路径。
顺便说一句,运行 Set-ItemProperty 后,我检查了控制面板->系统->高级系统设置->环境变量,我添加的新路径就在那里。
我发现如果我通过Windows系统设置手动修改Path,它会立即生效(新的cmd / powershell会有它);但如果通过powershell Set-ItemProperty命令修改路径,那么我必须注销,然后登录,然后新的Path才会生效。
感觉系统路径缓存在当前用户登录会话中。
答案1
当您使用控制面板更改 PATH 变量时,单击“确定”时,控制面板会向所有打开的窗口发送 WM_SETTINGCHANGE 消息,以便它们知道环境变量已被更改。
因此,如果您不想注销,则必须通过创建/查找根据文档发送此消息的小程序来自己发送 WM_SETTINGCHANGE:https://msdn.microsoft.com/en-us/library/windows/desktop/ms725497%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
答案2
只想发布一个完整的答案https://mnaoumov.wordpress.com/2012/07/24/powershell-add-directory-to-environment-path-variable/ ,下面的 powershell 脚本可以解决这个问题:
设置项属性-路径'注册表::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment'-名称 PATH-值 $newPath-Force $HWND_BROADCAST = [IntPtr] 0xffff; $WM_SETTINGCHANGE = 0x1a; $result = [UIntPtr]::零 如果(-not(“Win32.NativeMethods”-as [类型])) { # 从 win32 导入 sendmessagetimeout 添加类型-命名空间 Win32-名称 NativeMethods-成员定义@” [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 公共静态外部IntPtr SendMessageTimeout( IntPtr hWnd,uint Msg,UIntPtr wParam,字符串 lParam, uint fuFlags,uint uTimeout,out UIntPtr lpdwResult); “@ } # 通知所有窗口环境块改变 [Win32.Nativemethods]::SendMessageTimeout($HWND_BROADCAST,$WM_SETTINGCHANGE,[UIntPtr]::Zero,"环境",2,5000,[ref] $result);