SETX不会将路径附加到系统路径变量

Ham*_*ava 22 windows cmd batch-file system-variable setx

我试过下面的命令通过批处理文件将一些路径附加到系统路径变量:

setx PATH "%PATH%;C:\Program Files\MySQL\MySQL Server 5.5\bin"
Run Code Online (Sandbox Code Playgroud)

运行上面的批处理文件后,我检查了系统变量路径,上面的路径不在那里.

在此输入图像描述

您可以Variable value在下面看到所有窗口内容:

C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMDAPP\bin\x86;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\ProgramFiles (x86)\ATI Technologies\ATI.ACE\Core-Static;
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

moj*_*ojo 30

捎带@Endoro的回答(我没有回复评论):

如果要更改系统范围的环境变量,则必须使用/ M,a la:

setx PATH "%PATH%;C:\Program Files\MySQL\MySQL Server 5.5\bin" /M
Run Code Online (Sandbox Code Playgroud)

setx.exe对于放置/ M,BTW很挑剔.它需要在最后.

  • SETX无法设置超过1024个字符吗?当我执行SETX PATH"%PATH%; C:\ Temp"时,它完成了工作(对于1024个字符)但也警告:保存的数据被截断为1024个字符.有办法解决它吗?我**不要**想通过编辑注册表来实现它. (11认同)
  • @kalehv:在这种情况下,非常确定限制不是`setx`.例如,Windows上的命令行大小限制比在Linux上严重得多. (2认同)

Rob*_*Fey 10

警告!

setx会将值截断为1024个字符.

如果您使用它来修改PATH,您可能会弄乱您的系统.

您可以使用此PowerShell代码段向路径添加内容:

$new_entry = 'c:\blah'

$old_path = [Environment]::GetEnvironmentVariable('path', 'machine');
$new_path = $old_path + ';' + $new_entry
[Environment]::SetEnvironmentVariable('path', $new_path,'Machine');
Run Code Online (Sandbox Code Playgroud)

如果您不想重新添加已存在的条目,则会执行此类操作(请参阅更好的版本):

$new_entry = 'c:\blah'
$search_pattern = ';' + $new_entry.Replace("\","\\")

$old_path = [Environment]::GetEnvironmentVariable('path', 'machine');
$replace_string = ''
$without_entry_path = $old_path -replace $search_pattern, $replace_string
$new_path = $without_entry_path + ';' + $new_entry
[Environment]::SetEnvironmentVariable('path', $new_path,'Machine');
Run Code Online (Sandbox Code Playgroud)

这是我现在使用的更新版本(2017-10-23).此版本正确处理嵌套路径.例如,它处理包含"c:\ tool\foo"的PATH的情况,并且您想要添加"c:\ tool".

$desired_entry = 'C:\test'

$old_path = [Environment]::GetEnvironmentVariable('path', 'machine');

$old_path_entry_list = ($old_path).split(";")
$new_path_entry_list = new-object system.collections.arraylist

foreach($old_path_entry in $old_path_entry_list) {
    if($old_path_entry -eq $desired_entry){
        # ignore old entry
    }else{
        [void]$new_path_entry_list.Add($old_path_entry)
    }
}
[void]$new_path_entry_list.Add($desired_entry)
$new_path = $new_path_entry_list -Join ";"

[Environment]::SetEnvironmentVariable('path', $new_path,'Machine');
Run Code Online (Sandbox Code Playgroud)

  • 注册表中的原始“Path”值通常取决于其他系统变量(例如“%SystemRoot%”)和系统环境中的其他独立值。(与“REG_EXPAND_SZ”值不同,“REG_SZ”值不依赖于其他变量。重新加载环境时首先加载“REG_SZ”值,因此它们可以安全地在“PATH”中使用。)不幸的是“GetEnvironmentVariable”扩展它们,从而丢失有用的信息。这将获取原始系统值:`(get-item "HKLM:\System\CurrentControlSet\Control\Session Manager\Environment").GetValue("PATH", $null, "DoNotExpandEnvironmentNames")`。 (3认同)

End*_*oro 6

您不应该查看系统环境变量,而是查看用户环境变量:

在此输入图像描述


col*_*rre 6

切勿将 setx 用于路径,因为如上所述,它的长度限制为 1024 个字符。

可以使用reg添加:

set pathkey="HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment"
for /F "usebackq skip=2 tokens=2*" %%A IN (`reg query %pathkey% /v Path`) do (reg add %pathkey% /f /v Path /t REG_SZ /d "%%B;C:\Program Files\MySQL\MySQL Server 5.5\bin")
Run Code Online (Sandbox Code Playgroud)

或设置 pathkey="HKEY_CURRENT_USER\Environment" 作为用户路径。

然后广播更改:

powershell -command "& {$md=\"[DllImport(`\"user32.dll\"\",SetLastError=true,CharSet=CharSet.Auto)]public static extern IntPtr SendMessageTimeout(IntPtr hWnd,uint Msg,UIntPtr wParam,string lParam,uint fuFlags,uint uTimeout,out UIntPtr lpdwResult);\"; $sm=Add-Type -MemberDefinition $md -Name NativeMethods -Namespace Win32 -PassThru;$result=[uintptr]::zero;$sm::SendMessageTimeout(0xffff,0x001A,[uintptr]::Zero,\"Environment\",2,5000,[ref]$result)}"
Run Code Online (Sandbox Code Playgroud)


chi*_*.ks 5

SETX /M Path "%PATH%;%ProgramFiles%\MySQL\MySQL Server 5.5\bin\
Run Code Online (Sandbox Code Playgroud)

它会将您的路径附加到系统变量