我正在尝试使用PowerShell来更新Windows系统path:
$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”被添加到path中。 问题是,然后我启动一个新的PowerShell控制台或命令行控制台,并input“nuget”,我仍然得到“术语'Nuget'不被识别为cmdlet,函数,脚本文件或可操作程序的名称”
在新的PowerShell控制台中,如果我重新运行Get-ItemProperty,它显示新的path在那里,它只是不会立即在当前用户会话中生效。 如果我在cmd控制台中运行“set”,PATHvariables中没有新的Path。
顺便说一下,Set-ItemProperty运行后,我检查了控制面板 – >系统 – >高级系统设置 – >环境variables,我添加的新path在那里。
我发现如果我手动修改path通过Windows系统设置,它会立即生效(新的CMD / PowerShell的将有); 但如果path被powershell Set-ItemProperty命令修改,那么我必须注销,然后login,然后新的path才会生效。
感觉像系统pathcaching在当前用户login会话。
当您使用控制面板更改PATHvariables时,当您单击“确定”时,控制面板将向所有打开的窗口发送WM_SETTINGCHANGE消息,以便他们知道环境variables已更改。
因此,如果您不想注销,则必须根据以下文档创build/查找发送此消息的小程序,从而自己发送WM_SETTINGCHANGE: https : //msdn.microsoft.com/zh-cn/library/windows/桌面/ ms725497%28V = vs.85%29.aspx?F = 255&MSPPError = -2147217396
Set-ItemProperty -Path'Registry :: HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment'-Name PATH -Value $ newPath -Force $ HWND_BROADCAST = [IntPtr] 0xffff; $ WM_SETTINGCHANGE = 0x1a; $ result = [UIntPtr] :: Zero 如果(-not(“Win32.NativeMethods”-as [Type])) { #从win32导入sendmessagetimeout 添加types-Namespace Win32 -Name NativeMethods -MemberDefinition @“ [DllImport(“user32.dll”,SetLastError = true,CharSet = CharSet.Auto)] 公共静态extern IntPtr SendMessageTimeout( IntPtr hWnd,uint Msg,UIntPtr wParam,stringlParam, uint fuFlags,uint uTimeout,out UIntPtr lpdwResult); “@ } #通知所有窗口的环境块更改 [Win32.Nativemethods] :: SendMessageTimeout($ HWND_BROADCAST,$ WM_SETTINGCHANGE,[UIntPtr] :: Zero,“Environment”,2,5000,[ref] $ result);