114

I want to modify the Windows PATH variable using setx. The following works at least 50% of the time on Windows 8:

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

If it gives the error "the default argument can only be used 2 times", then the following works some of the time:

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

The difference is that we wrapped the second argument in quotes. I believe the quotes are necessary when %PATH% expands to include spaces.

However, I have encountered some weird problems on Windows 7. On one particular Windows 7 machine, I had this problem:

echo %PATH%

It prints:

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

Then I do this:

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

Then it says "Error: Truncated at 1,024 characters." Now let's check what PATH contains:

echo %PATH%

It prints:

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

...and it is cut off at 1,024 characters. It ran over because of the duplicates. Also interesting: The value of PATH changes despite the fact that setx raised an error and did not say "Success".

I was able to repeat this strange behavior several times (luckily I had saved the original contents of PATH).

At the moment, the only surefire way I know to append to the PATH is the following:

  1. echo the PATH.

  2. Copy the contents of PATH into a text file and manually add ;C:\Python27\;C:\Python27\Scripts\ to the end of the PATH.

  3. Copy the whole thing out of the text file.

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

That process works every single time on both Windows 7 and Windows 8.

I should really be able to do this in one command. What am I doing wrong?

11
  • 12
    Using setx is dangerous for another reason: if the path contains any environment variables, e.g., %JAVADIR%\bin, the reference will be lost, i.e., if JAVADIR changes the path will no longer change with it. If this is a software installer, it may break the end-users machines. Not a good idea. Commented Oct 11, 2013 at 2:15
  • 1
    @HarryJohnston, This is by design. Whenever you do a %, it interprets it on the spot.
    – Pacerier
    Commented Jul 29, 2017 at 7:51
  • 2
    @Pacerier, any environment variable references in the registry entries for the path will already have been expanded, this happens as the environment block is built. So when you feed %PATH% into setx you are losing this information. Plus, of course, the way the OP is doing it the system path setting is getting added to the user path setting, looking at the question again it looks like that's the real cause of the OPs problem. Commented Jul 29, 2017 at 9:03
  • 3
    @HarryJohnston, There are 4 kinds of env variable: hkcu reg_sz, hkcu reg_expand_sz, hklm reg_sz, hklm reg_expand_sz. (You can manually tweak them with regedit and run setx to complete the flush.) ~~~ Both setx and setx/m defaults to reg_sz if your input contains 2+ % char. ~~~ "expand" in both hklm and hkcu mean expand to hklm. setx/m qwe %JAVADIR%\bin and setx/m javadir asdfg in either order. Then open a new cmd and do echo %qwe%: works as expected.
    – Pacerier
    Commented Jul 29, 2017 at 11:49
  • 3
    @Pacerier, I don't see the relevance. The value of PATH is already expanded as well as containing both the HKCU and HKLM entries (the latter is a special case, it doesn't happen for any other environment variable) so if the path in HKLM originally contained %JAVADIR%\bin and the path in HKCU originally contained %JDK%\bin then PATH will be set to C:\Java\bin;C:\jdk\bin so when you say setx PATH %PATH% the value in HKCU changes to C:\Java\bin;C:\jdk\bin which (a) contains a redundant entry and (b) no longer tracks changes to the value of JDK. Commented Jul 30, 2017 at 2:36

15 Answers 15

96

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.

5
  • 44
    This solution is bogus. Executing the above command will change your Path type from REG_EXPAND_SZ to REG_SZ; and in the process, remove all environment variable references present there. Commented Feb 24, 2015 at 23:32
  • @garyM Thanks for the feedback. I didn't experience/notice the mentioned consequences in my case. Please let us know if there's a way to modify this answer that will fix it. Or if you suggest a different answer. Commented Dec 1, 2015 at 23:51
  • 2
    Hi Vituel,, The issue occurs when the variable is newly created then later modified within the same process. The newly created variable does not show up in the existing shell environment. any reference will treat the reference %var% as a text string. To avoid this issue, accessing the variable must be executed in a new process which created after the variable is created. The path variable is a special case on some version of windows. In 2008R2, modification of PATH variable is not promoted to existing processes, they need to be re-instantiated to get the changes. Based on OS, /M is at the end.
    – garyM
    Commented Dec 3, 2015 at 2:25
  • 3
    Also, this results in the user PATH variable being appended to the machine PATH, which will (a) interfere with other users; and (b) if run repeatedly, keep increasing the length of the path until it eventually overflows. Most of the time there won't be a user setting for PATH so you can get away with it, but it is dangerous. Commented Aug 9, 2017 at 2:12
  • 14
    DO NOT USE THIS. setx will truncate PATH to 1024 characters. If PATH was changed before by being prepended with more directories, you will lose most of the original PATH contents!
    – e.tadeu
    Commented Mar 8, 2018 at 16:43
41

The PATH environment variable is constructed from a system-wide part and a user-specific part that are both stored in the registry.

Following commands make sure not to interfere with the system-wide part of PATH. Only the user-specific part is read, modified and written back to the registry.

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 first command gets the user-specific part of PATH from the registry into a variable named my_user_path.

NOTE: Make sure the first command works without error

The second command prepends the C:\Python27;C:\Python27\Scripts; to the value of my_user_path and writes it back to the user-specific registry key for PATH.

NOTE: When used in a .bat file, replace % with %% in both places on the first line:

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

Only newly started programs will see the change in the PATH environment variable.

12
  • 2
    this answer is logically correct imo. why did this answer neither get more votes nor was accepted ? Did I miss anything ? Commented Jun 27, 2019 at 6:02
  • 3
    @AMVaddictionist - i think %% or % is to do with if you are running it as a .bat file or in the cmd directly. Hope that helps. Commented Aug 26, 2019 at 9:41
  • 3
    Agree. This is the correct answer. As written, it is for running in a command prompt, and the single % must be replaced with double %% to run in a batch file. Commented Sep 20, 2019 at 19:23
  • 2
    @ManoharReddyPoreddy Thanks, God saved me, though I had taken backups of environment variables, but this answer is a gem compared any other answer's. First store prev env vars and then append with new one. Works great :)
    – Mukesh Jha
    Commented Sep 6, 2020 at 20:33
  • 1
    @mozilla_firefox - yeah, we take backups then try something new :), we are proper devs? :D Commented Sep 8, 2020 at 0:38
8

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
4

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.

2
  • 6
    Thanks for the suggestions, but I really do not want to rely on third-party software. I want to use only things that come with Windows. This is because I have two major use cases: (1) setting up newbies who want to learn Python, and (2) setting up machines that are used in my company's factory. In both cases, it is a random Windows machine that will only have the PATH edited once. I want to make the PATH edit as easy as possible, and installing more software really doesn't cut it. That's why even my 4-step workaround is not good enough.
    – SerMetAla
    Commented Oct 10, 2013 at 5:26
  • So the tools I linked to have portable binaries that you can bundle in a zip file. You can have the users do something as simple as run a .bat file and have that handle PATH editing as well as setting up Python code. Commented Oct 25, 2013 at 18:06
4

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

1
  • 2
    if you want that part of the path to follow changes to %USERPROFILE%, you can use double %% in a bat file (or ^% if running the command directly - see how to escape in bat vs cmd). Commented Apr 1, 2020 at 9:27
3

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"
2
  • The only sensible answer here in 8 years. Except that the REG_EXPAND_SZ to REG_SZ issue and the 1024 character limit may still remain problems. Also look into setx /? because it can read the registry directly.
    – Amit Naidu
    Commented Mar 12, 2021 at 0:23
  • 1
    The only reason for wrapping it in a FOR loop was to put the results of the first command in a variable. Totally assbackward dos scripting, but that can't be helped. Didn't know setx could read those, so thanks for the addition. Commented Jan 25, 2022 at 18:35
3

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
5
  • For the part on finding a substring, I am indebted to this answer from Magoo Commented Mar 20, 2021 at 14:05
  • 1
    This should be the accepted answer IMHO, because it avoids duplicated paths. Minor suggestion: Consider using %1 instead of hard-coded "current directory" or any explicit policy. Leave the freedom to users.
    – kakyo
    Commented Jun 21, 2021 at 4:16
  • ... but then People From The Internet couldn't just script-kiddie this away .. might actually have to think about how it's being used Commented Jun 22, 2021 at 12:02
  • Well, I know you double-click it. Not being nit-picky, but I just turned it into a subroutine for my own usage. Thanks anyways.
    – kakyo
    Commented Jun 22, 2021 at 12:20
  • It's cool. It is a good suggestion, it is an improvement, and I appreciate it. I dislike hard-coding as much as anyone, but in this context figured it's better to focus on the heart of the problem (duplicated paths, etc), instead of adding nice peripherals that may -- or may not -- give clarity to the central issue. Commented Jun 23, 2021 at 0:54
2

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

2
1
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.

0

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.

0

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.

2
  • Please add some comments to your code to explain what it does to the path strings; it looks like it is eliminating newlines. Why is the findstr necessary ? Does the /v path query return more than one line ? Don't name the variable holding the path value 'cmd'. It makes the already hard to read code even more obfuscated. And another simplified version for HKCU would be useful to folks who don't need to (or don't have the rights to) modify the system path.
    – Amit Naidu
    Commented Mar 12, 2021 at 1:15
  • Ok, now I see that those two cmd lines are just to remove extraneous findstr output. That can be done much more simply in a single command: for /F "skip=2 tokens=2*" %a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v path') do @set currpath=%b. Or better yet, don't use cmd. When in vbscript, use vbscript. Shell.RegRead("HKLM\SOFTWARE\etc"). Also see RegWrite.
    – Amit Naidu
    Commented Mar 12, 2021 at 2:48
0

Alternativelly, if you want to set the system path, here is a solution based on JonathanDavidArndt's answer.

@echo off
setlocal
chcp 65001 >nul
call :addToSystemPath C:\Program Files\Git\cmd
exit /b

:addToSystemPath
set ADDED_FOLDER=%*
REM -- Great example from Strawberry Perl's portable shell launcher:
if #%ADDED_FOLDER:~-1%# == #\# set ADDED_FOLDER=%ADDED_FOLDER:~0,-1%

REM -- Load the SYSTEM PATH from the registry, making sure it is not blank
SET PATH_ENV_HIVE=HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
reg query "%PATH_ENV_HIVE%" /v PATH 1>nul 2>&1
if ERRORLEVEL 1 goto skipLoadPath
for /f "usebackq tokens=2,*" %%A in (`reg query "%PATH_ENV_HIVE%" /v PATH`) do set SYSTEM_PATH=%%B
REM -- Optionally, checks if this directory is already part of the SYSTEM 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 SYSTEM PATH,
REM -- this script will simply not do anything
echo %SYSTEM_PATH%|find "%ADDED_FOLDER%" >nul
if errorlevel 1 goto skipLoadPath
:skipSetXPath
echo Folder "%ADDED_FOLDER%" already in path
exit /b

:skipLoadPath
REM -- Avoid adding a useless semicolon to the previous SYSTEM PATH
if not "" == "%SYSTEM_PATH%" set "SYSTEM_PATH=%SYSTEM_PATH%;"
REM -- Permanently set the following location as part of the system path
setx /M PATH "%SYSTEM_PATH%%ADDED_FOLDER%"
rem >nul 2>&1
rem "On a local system, variables created or modified by this tool will be available in future command windows but not in the current CMD.exe command window."
REM -- This will update the current environment, since SETX only updates the registry
set "PATH=%PATH%;%ADDED_FOLDER%"
exit /b
0

I think most solutions mentioned here are bad, since they would either (like anything using setx) corrupt the Path value in the registry by converting its type from REG_EXPAND_SZ to REG_SZ, or at least replace all "template" vars inside the path value with their current values, so the user would lose the intended template functionality (Example: Path=%PYTHONHOME%\bin;%PERLHOME%\bin;... would be converted to a static Path=D:\dev\python\v3.12.2\bin;C.\perl\bin;...

Here a simple solution that keeps the REG_EXPAND_SZ type and such template vars:

@echo off

:: get current Path variable from registry (user)
for /F "usebackq tokens=1,2,*" %%a in (`reg query HKCU\Environment /v Path`) do (
    set "current=%%c"
)

:: prepend stuff, in this case "F:\bin;"
set prepend=F:\bin;
set "current=%prepend%%current%"

:: create a backup, just in case
reg export HKCU\Environment %TMP%\~env_backup.reg /y

:: overwrite current Path in registry (user) with extended version
reg add HKCU\Environment /v Path /t REG_EXPAND_SZ /d "%current%" /f >nul

:: prepend the same stuff also for the current CMD session
set "Path=%prepend%%Path%"
0
0

There are several answers here with batch file code which no user should use ever for adding a directory path to the user or system environment variable Path as resulting in a corruption of the existing persistent stored variable string value of Path.

I decided for that reason posting my long answer explaining most (perhaps all) issues which could happen on adding a directory path to user or system Path from the question What is the best practice for adding a directory to the PATH environment variable on Windows? here once again.

I wrote several batch file procedures for adding or removing a folder path to user or system environment variable PATH, see these answers. But I have not found a solution really working for every possible folder path to add or every possible existing value of the PATH variable using a batch file and only Windows commands.

Some of the problems to handle are:

  1. A folder path to add contains a semicolon requiring adding the folder path enclosed in " for a valid semicolon separated list of folder paths.
  2. A folder path to add contains an equal sign which makes checking if this folder path is already present in value of environment variable PATH very difficult or perhaps even impossible on using a batch file.
  3. The already existing PATH value contains already a folder path enclosed in " for whatever reason like the folder path contains a ; or another installer or the user made a not good job and added a folder path unnecessarily with double quotes.
  4. The already existing PATH value contains already a folder path with an equal sign which makes checking if the folder path to add is already present in value of environment variable PATH very difficult or perhaps even impossible.
  5. The Windows Command Processor cmd.exe processing a batch file uses by default a single byte per character encoding with an OEM code page according to the country/region configured for the used account. That is a problem especially in Asian countries on which users often use their real name as user account name and therefore the environment variables USERNAME and USERPROFILE contain Unicode encoded characters not available at all in the code page used by the Windows Command Processor. Updating user or system environment variable PATH using a batch file could corrupt the existing PATH value in such use cases.

A developer of a Windows application or script should always think about a design which avoids adding a folder path to user or system environment variable PATH. It is always possible coding applications and scripts for working without adding a folder path to user or system environment variable PATH during the installation. A folder path to store by the installation for usage by the installed application or script can be also stored somewhere else in the Windows registry under a registry key Software\CompanyName\ProgramName in HKEY_CURRENT_USER (current user) or HKEY_LOCAL_MACHINE (all users) as well as in a configuration file stored in the directory %APPDATA%\CompanyName\ProgramName (current user) or %ALLUSERSPROFILE%\CompanyName\ProgramName (all users). It is in general an indication of a bad application/script design if a program/script depends on a folder path added to user or system environment variable PATH during the installation for working properly.

There should be added a folder path to user or system environment variable PATH during the installation only if the user will most likely use the application/script mainly from within a console (Windows command prompt, PowerShell console, Windows Terminal) by typing its file name without file extension with various arguments, and only after asking the user during the installation if the application/script folder path should be added to the user or system environment variable PATH for easy usage of the application/script. The user might not often use the application/script and does not want for that reason adding the folder path of the application/script from the console to the user or system environment variable PATH which affects the execution time of lots of other applications and scripts and increases the number of file system accesses of nearly every process.

The main problem with using a batch file processed by cmd.exe using only internal commands of the Windows Command Processor and other Windows commands is the fact that cmd.exe is designed for executions of commands and executables and not for string processing as supported natively by more modern and much more powerful script interpreters like the Windows Script Host or PowerShell. That makes processing the existing value of a persistent stored environment variable like PATH for updating it with a folder path defined by a user respectively the user's account configuration a nightmare. The existing PATH value as well as the folder path to add could contain characters which have a special meaning for the Command Processor and that makes a pure batch file solution working really for any possible use case very hard if not even impossible.

Here is a commented batch script which works for common use cases of adding a folder path to user environment variable PATH. It works even on Windows XP with SETX not available at all and uses SETX only on resulting value is not exceeding the 1024 characters limit. Otherwise, there is used the command REG to update the registry value which has the disadvantage that the Windows shell is not informed with a message about the change of the user environment variable PATH. The user must at least sign/log out and sign/log in again for updated user environment variable PATH becoming effective for all processes running under the user account.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PathToAdd=C:\Temp\Development & Test not 100%% (!)"

set "UserPath="
for /F "skip=2 tokens=1,2*" %%G in ('%SystemRoot%\System32\reg.exe query HKCU\Environment /v Path 2^>nul') do (
    if /I "%%G" == "Path" (
        set "UserPath=%%I"
        if defined UserPath goto ProcessPath
    )
)

rem The folder path to add should not be enclosed in double quotes, except
rem on containing a semicolon, must contain \ (backslash) as directory
rem separator and not / (slash), and should not end with a backslash. A
rem path to add with a semicolon or with an equal sign is not supported
rem by this batch code. There is an error messages output to inform the
rem user about this limitation and suggesting adding the folder path
rem manually to the user environment variable PATH.
:ProcessPath
set "PathToAdd=%PathToAdd:"=%"
set "PathToAdd=%PathToAdd:/=\%"
if "%PathToAdd:~-1%" == "\" set "PathToAdd=%PathToAdd:~0,-1%"
if not "%PathToAdd:;=%" == "%PathToAdd%" set "ErrorChar=;" & goto ErrorAdd
for /F "eol=| tokens=1 delims==" %%I in ("%PathToAdd%") do if not "%%I" == "%PathToAdd%" set "ErrorChar==" & goto ErrorAdd

setlocal EnableDelayedExpansion
rem Is the user environment variable PATH not present or has an empty value?
if not defined UserPath set "PathToSet=!PathToAdd!" & goto UpdatePath
endlocal

rem It is also not possible to add a folder path to the user environment
rem variable PATH if this variable as stored in the registry contains
rem already a folder path with an equal sign or enclosed in double quotes.
set "PathCheck=%UserPath:"=%"
for /F "eol=| tokens=1 delims==" %%I in ("%PathCheck%") do if not "%%I" == "%PathCheck%" set "ErrorChar==" & goto ErrorPath
setlocal EnableDelayedExpansion
if "!PathCheck!" == "!UserPath!" goto CheckPath
endlocal
set "ErrorChar=""
goto ErrorPath

rem Determine if the user environment variable PATH ends already
rem with a semicolon in which case no additional semicolon must
rem be added left to the folder path to add.
:CheckPath
if "!UserPath:~-1!" == ";" (set "Separator=") else set "Separator=;"
set "PathCheck=!UserPath!%Separator%"

rem Do nothing if the folder path to add without or with a backslash
rem at end with a semicolon appended for entire folder path check is
rem already in the user PATH value. This code does not work on path
rem to add contains an equal sign which is fortunately very rare.
if not "!PathCheck:%PathToAdd%;=!" == "!PathCheck!" goto EndBatch
if not "!PathCheck:%PathToAdd%\;=!" == "!PathCheck!" goto EndBatch
set "PathToSet=!UserPath!%Separator%!PathToAdd!"

:UpdatePath
set "UseSetx=1"
if not "!PathToSet:~1024,1!" == "" set "UseSetx="
if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
if defined UseSetx (
    %SystemRoot%\System32\setx.exe Path "!PathToSet!" >nul
) else (
    set "ValueType=REG_EXPAND_SZ"
    if "!PathToSet:%%=!" == "!PathToSet!" set "ValueType=REG_SZ"
    %SystemRoot%\System32\reg.exe ADD  HKCU\Environment /f /v Path /t !ValueType! /d "!PathToSet!" >nul
)
goto EndBatch

:ErrorAdd
echo(
echo ERROR: Folder path to add to user environment variable PATH is:
echo(
setlocal EnableDelayedExpansion
if "%ErrorChar%" == ";"  (echo "!PathToAdd!") else echo !PathToAdd!
echo(
echo The folder path contains the character '%ErrorChar%' which is not supported
echo by this procedure for updating the user environment variable PATH.
goto Suggestion

:ErrorPath
echo(
echo ERROR: Folder path to add to user environment variable PATH is:
echo(
setlocal EnableDelayedExpansion
echo !PathToAdd!
echo(
echo The user environment variable PATH contains the character '%ErrorChar%'.
echo This procedure for updating the user environment variable PATH
echo does not support updating the variable PATH with that character.
:Suggestion
echo(
echo The folder path must be manually added to the user environment variable PATH.
echo Please click on Windows Start button, type on keyboard the word environment,
echo and click on suggested item "Edit environment variables for your account".
echo Add or edit the environment variable PATH in the upper list of user
echo environment variables and append the folder path as displayed here.
echo(
pause

:EndBatch
endlocal
endlocal

NOTE: The environment variable PathToAdd must be defined as needed in third line of this batch file.

The first four problems on updating user environment variable PATH are handled by this script with not updating the persistent stored environment variable and instead inform the user about the reason and what the user should do now for getting the folder path added to the user environment variable PATH.

The fifth problem with missing support for folder paths with Unicode characters in path to add or in existing value of user environment variable PATH is not handled at all by this batch file.

The check for folder path to add already existing in the value of user PATH is quite poor as that is done with a simple case-insensitive string comparison. It could be that the folder path to add is with a variable reference like %APPDATA%\Python as value while the same folder path exists already in user PATH value in expanded form like C:\Users\UserName\AppData\Roaming\Python. That is very common on user once used a bad coded installer which updates the persistent stored environment variable PATH with expansion of all environment variables instead of keeping the environment variable references. The batch code above would add the folder path to the persistent stored user environment variable PATH because of %APPDATA%\Python is not present in the existing value containing C:\Users\UserName\AppData\Roaming\Python.

A batch file updating user environment variable PATH during the installation should also update the local environment variable PATH outside any local environment setup by command SETLOCAL before batch file processing is exited if the installation was started by the user from within a command prompt window, i.e an already running cmd.exe process.

It would be additionally good to check if the console used by the user is in real a PowerShell console from within the batch file was executed by an implicit execution of %ComSpec% /c ""Fully qualified batch file name"". The user should be informed in this case that the PowerShell console window must be closed and a new one opened from Windows shell (Windows desktop, Windows Start menu, Windows taskbar) for getting effective the updated PATH in the PowerShell console if not a sign/log out and sign/log in or a complete Windows restart is necessary because of command REG was used to update the persistent stored environment variable instead of SETX.

An application/script depending on a specific folder path in local PATH should always inform the user to restart Windows after an installation really adding the folder path to persistent stored PATH respectively after an uninstall with a removal of the folder path from persistent stored PATH before doing anything else for making sure the modified PATH becomes really effective for the processes.

Users don't like restarting Windows after an install or uninstall of an application/script and ignore that recommendation or request quite often. But these users next often complain that the just installed application does not work properly and ask others for help, for example on Stack Overflow. The developer of such an application/script could have avoided lots of troubles on using a design for the application/script which does not depend on a folder path added to PATH during the installation.

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • reg /?
  • reg add /?
  • reg query /?
  • rem /?
  • set /?
  • setlocal /?
  • setx /?

Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on first FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded reg command line with using a separate command process started in background with %ComSpec% /c and the command line within ' appended as additional arguments.

See also:

-1

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%"

1
  • 7
    OP has decribed several details and observations for his problem. OP has described several attempts to solve his problem. Some of them are quite similar to your proposal. Can you highlight the relevant differences and explain how they solve OPs problem?
    – Yunnosch
    Commented May 29, 2017 at 16:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.