如何使用 setx 添加到 Windows PATH 变量? 有奇怪的问题吗

我想使用 setx修改 Windows PATH 变量。以下内容在 Windows8上至少有50% 的时间可用:

setx PATH %PATH%;C:\Python27\;C:\Python27\Scripts\

如果它给出错误“默认参数只能使用2次”,那么下面的代码在某些时候是有效的:

setx PATH "%PATH%;C:\Python27\;C:\Python27\Scripts\"

区别在于我们用引号包装了第二个参数。我相信当 %PATH%扩展到包含空格时,引号是必要的。

然而,我在 Windows7上遇到了一些奇怪的问题,在一台特殊的 Windows7机器上,我遇到了这个问题:

echo %PATH%

它打印:

C:\Foo\;C:\Bar\;[...lots of stuff...]C:\Baz\

然后我这样做:

setx PATH "%PATH%;C:\Quux\"

然后它会说“ Error: Truncated at 1,024字符。”现在让我们检查 PATH 包含什么:

echo %PATH%

它打印:

C:\Foo\;C:\Foo\;C:\Bar\;C:\Bar\;[...lots of stuff, now duplicated...]C:\B

截止到一千零二十四个字。因为复制品,它跑过去了。同样有趣的是: PATH 的值发生了变化,尽管 setx提出了一个错误并且没有说“ Success”。

我能够多次重复这种奇怪的行为(幸运的是,我保存了 PATH 的原始内容)。

目前,我所知道的唯一可靠的方法是在 PATH 中添加以下内容:

  1. 路径。

  2. 将 PATH 的内容复制到一个文本文件中,并手动将 ;C:\Python27\;C:\Python27\Scripts\添加到 PATH 的末尾。

  3. 从文本文件中复制整个内容。

  4. setx PATH "<paste the string here>"

这个过程在 Windows7和 Windows8上每次都能奏效。

我应该只需要一个命令就能做到,我做错了什么?

226926 次浏览

If you're not beholden to setx, you can use an alternate command line tool like pathed. There's a more comprehensive list of alternative PATH editors at https://superuser.com/questions/297947/is-there-a-convenient-way-to-edit-path-in-windows-7/655712#655712

You can also edit the registry value directly, which is what setx does. More in this answer.

It's weird that your %PATH% is getting truncated at 1024 characters. I thought setx didn't have that problem. Though you should probably clean up the invalid path entries.

Run cmd as administrator, then:

setx /M PATH "%PATH%;<your-new-path>"

The /M option sets the variable at SYSTEM scope. The default behaviour is to set it for the USER.

TL;DR

The truncation happens because when you echo %PATH% you get the concatenation of SYSTEM and USER values so, when you add it in your second argument to setx, the command will try to fit the contents of both SYSTEM and USER within the USER var. When you echo again, the result will be doubled.

The /M option requires administrator privilege, so you need to open your terminal with "run as administrator" otherwise setx will fail with "access to registry path is denied".

Note: You won't see the new value when you echo %PATH% just after setting it this way, you need to close cmd and open again.

If you want to check the actual values stored in registry check this question.

I was facing the same problems and found a easy solution now.

Using pathman.

pathman /as %M2%

Adds for example %M2% to the system path. Nothing more and nothing less. No more problems getting a mixture of user PATH and system PATH. No more hardly trying to get the correct values from registry...

Tried at Windows 10

Steps: 1. Open a command prompt with administrator's rights.

Steps: 2. Run the command: setx /M PATH "path\to;%PATH%"

[Note: Be sure to alter the command so that path\to reflects the folder path from your root.]

Example : setx /M PATH "C:\Program Files;%PATH%"

This works perfectly:

for /f "usebackq tokens=2,*" %A in (`reg query HKCU\Environment /v PATH`) do set my_user_path=%B


setx PATH "C:\Python27;C:\Python27\Scripts;%my_user_path%"

The 1st command gets the USER environment variable 'PATH', into 'my_user_path' variable

NOTE: Make sure 1st line works without error

The 2nd line prepends the 'C:\Python27;C:\Python27\Scripts;' to the USER environment variable 'PATH'

If someone want to run it in PowerShell it works like below,

Run Powershell as Administrator

Then

setx /M PATH "$Env:PATH;<path to add>"

To verify, open another Powershell and view PATH as below,

$Env:PATH

I was having such trouble managing my computer labs when the %PATH% environment variable approached 1024 characters that I wrote a Powershell script to fix it.

You can download the code here: https://gallery.technet.microsoft.com/scriptcenter/Edit-and-shorten-PATH-37ef3189

You can also use it as a simple way to safely add, remove and parse PATH entries. Enjoy.

Without admin rights the only way that worked for me is a bat file that contains the following code:

for /F "tokens=2* delims= " %%f IN ('reg query HKCU\Environment /v PATH ^| findstr /i path') do set OLD_SYSTEM_PATH=%%g
setx PATH "%USERPROFILE%\wev-tools;%OLD_SYSTEM_PATH%"

The code is the combination of the answers https://stackoverflow.com/a/45566845/4717152 and https://stackoverflow.com/a/10292113/4717152

Sadly with OOTB tools, you cannot append either the system path or user path directly/easily. If you want to stick with OOTB tools, you have to query either the SYSTEM or USER path, save that value as a variable, then appends your additions and save it using setx. The two examples below show how to retrieve either, save them, and append your additions. Don't get mess with %PATH%, it is a concatenation of USER+SYSTEM, and will cause a lot of duplication in the result. You have to split them as shown below...

Append to System PATH

for /f "usebackq tokens=2,*" %A in (`reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH`) do set SYSPATH=%B


setx PATH "%SYSPATH%;C:\path1;C:\path2" /M

Append to User PATH

for /f "usebackq tokens=2,*" %A in (`reg query HKCU\Environment /v PATH`) do set userPATH=%B


setx PATH "%userPATH%;C:\path3;C:\path4"

This vbscript/batch hybrid "append_sys_path.vbs" is not intuitive but works perfectly:

If CreateObject("WScript.Shell").Run("%ComSpec% /C ""NET FILE""", 0, True) <> 0 Then
CreateObject("Shell.Application").ShellExecute WScript.FullName, """" & WScript.ScriptFullName & """", , "runas", 5
WScript.Quit
End If
Set Shell = CreateObject("WScript.Shell")
Cmd = Shell.Exec("%ComSpec% /C ""REG QUERY ""HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"" /v Path | FINDSTR /I /C:""REG_SZ"" /C:""REG_EXPAND_SZ""""").StdOut.ReadAll
Cmd = """" & Trim(Replace(Mid(Cmd, InStr(1, Cmd, "_SZ", VBTextCompare) + 3), vbCrLf, ""))
If Right(Cmd, 1) <> ";" Then Cmd = Cmd & ";"
Cmd = "%ComSpec% /C ""REG ADD ""HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"" /v Path /t REG_EXPAND_SZ /d " & Replace(Cmd & "%SystemDrive%\Python27;%SystemDrive%\Python27\Scripts"" /f""", "%", """%""")
Shell.Run Cmd, 0, True

Advantages of this approach:

1) It doesn't truncate the system path environment at 1024 characters.
2) It doesn't concatenate the system and user path environment.
3) It's automatically run as administrator.
4) Preserve the percentages in the system path environment.
5) Supports spaces, parentheses and special characters.
6) Works on Windows 7 and above.

setx path "%PATH%; C:\Program Files (x86)\Microsoft Office\root\Office16" /m

This should do the appending to the System Environment Variable Path without any extras added, and keeping the original intact without any loss of data. I have used this command to correct the issue that McAfee's Web Control does to Microsoft's Outlook desktop client.

The quotations are used in the path value because command line sees spaces as a delimiter, and will attempt to execute next value in the command line. The quotations override this behavior and handles everything inside the quotations as a string.

Just wanted to reiterate: the earlier answer from Manohar Reddy Poreddy is the correct one.

There are a number of improvements that can be made, that I thought might be helpful to share:

@echo off


REM -- Use directory where script is located. For current working directory, use %CD%
set CURRENT_DIR=%~dp0
REM -- Great example from Strawberry Perl's portable shell launcher:
if #%CURRENT_DIR:~-1%# == #\# set CURRENT_DIR=%CURRENT_DIR:~0,-1%


REM -- Load the user PATH from the registry, making sure it is not blank
reg query HKCU\Environment /v PATH 1>nul 2>&1
if ERRORLEVEL 1 goto skipLoadPath
for /f "usebackq tokens=2,*" %%A in (`reg query HKCU\Environment /v PATH`) do set MY_USER_PATH=%%B


REM -- Optionally, checks if this directory is already part of the user PATH
REM -- This will avoid duplication, and allow this to be run multiple times,
REM -- but if a sub-directory of the current is already part of the user PATH,
REM -- this script will simply not do anything
echo %MY_USER_PATH%|find "%CURRENT_DIR%" >nul
if errorlevel 1 (goto skipLoadPath) else (goto skipSetXPath)
:skipLoadPath


REM -- Avoid adding a useless semicolon to the previous user PATH
if not "" == "%MY_USER_PATH%" set "MY_USER_PATH=%MY_USER_PATH%;"
REM -- Permanently set the following location as part of the system path
setx PATH "%MY_USER_PATH%%CURRENT_DIR%" >nul 2>&1
REM -- This will update the current environment, since SETX only updates the registry
set "PATH=%PATH%;%MY_USER_PATH%%CURRENT_DIR%"
:skipSetXPath