3

I looked through a few solutions here and found an almost working script to append to the user Environment Variable PATH without overwriting the existing path and not clutter it with system's EV's PATH.

I wanted to add 4 paths, 2 from Python and 2 from Anaconda. The first 3 locations work perfectly (Python311, Python312, conda.exe), but it keeps duplicating the 4th path (_conda.exe) even though the script sequence is the same.

Thoughts?

@echo off
REM usage: append_user_path "path"
SET Key="HKCU\Environment"
FOR /F "usebackq tokens=2*" %%A IN (`REG QUERY %Key% /v PATH`) DO Set CurrPath=%%B
echo Add %appdata%\Python\Python311\Scripts to PATH
@echo off
set "newPath=%appdata%\Python\Python311\Scripts"
echo %CurrPath% | findstr /i /c:"%newPath%" >nul
if errorlevel 1 (
    setx PATH "%CurrPath%;%newPath%"
    echo Path updated successfully.
) else (
    echo Path already contains the directory.
)

REM usage: append_user_path "path"
SET Key="HKCU\Environment"
FOR /F "usebackq tokens=2*" %%A IN (`REG QUERY %Key% /v PATH`) DO Set CurrPath=%%B
echo Add %appdata%\Python\Python312\Scripts to PATH
@echo off
set "newPath=%appdata%\Python\Python312\Scripts"
echo %CurrPath% | findstr /i /c:"%newPath%" >nul
if errorlevel 1 (
    setx PATH "%CurrPath%;%newPath%"
    echo Path updated successfully.
) else (
    echo Path already contains the directory.
)

REM usage: append_user_path "path"
SET Key="HKCU\Environment"
FOR /F "usebackq tokens=2*" %%A IN (`REG QUERY %Key% /v PATH`) DO Set CurrPath=%%B
echo Add %ProgramFiles%\Continuum\Anaconda3\conda.exe to PATH
@echo off
set "newPath=%ProgramFiles%\Continuum\Anaconda3\conda.exe"
echo %CurrPath% | findstr /i /c:"%newPath%" >nul
if errorlevel 1 (
    setx PATH "%CurrPath%;%newPath%"
    echo Path updated successfully.
) else (
    echo Path already contains the directory.
)

REM usage: append_user_path "path"
SET Key="HKCU\Environment"
FOR /F "usebackq tokens=2*" %%A IN (`REG QUERY %Key% /v PATH`) DO Set CurrPath=%%B
echo Add %ProgramFiles%\Continuum\Anaconda3\_conda.exe to PATH
@echo off
set "newPath=%ProgramFiles%\Continuum\Anaconda3\_conda.exe"
echo %CurrPath% | findstr /i /c:"%newPath%" >nul
if errorlevel 1 (
    setx PATH "%CurrPath%;%newPath%"
    echo Path updated successfully.
) else (
    echo Path already contains the directory.
)
Pause

Append path works as intended for the first 3 paths if they already exist. But even if the 4th path exists, it appends/adds/duplicates it anyway:

Screenshot of above's explanation:

5
  • 2
    Why don’t you just use something easier to work with than batch script to modify the variable like PowerShell? Why don’t you just modify the variable by hand? I can’t even tell what variable your modifying. Anyways this seems more like a programming Stack Overflow question than a Super User question. You shouldn’t have to add the path and the file name to the PATH variable. You also appear to be missing the majority of the default values if this actually is PATH and not a different user variable Commented Jul 29 at 22:40
  • 5
    Why is the executable being added to %PATH%? AFAIK, only the directory path, not the executable Commented Jul 30 at 1:04
  • 1
    As JW0914 points out, Path needs directories. Drop the 3x exe and add one folder: set "newPath=%ProgramFiles%\Continuum\Anaconda3". Commented Jul 30 at 10:17
  • There is also a flaw in your checks for existing entries. The strings you should have in the 'Edit environment variable' list should read as %AppData%\Python\Python312\Scripts, %AppData%\Python\Python311\Scripts, and %ProgramFiles%\Continuum\Anaconda3, not the expanded variable form. The reason is that the variable registry entries are of the form REG_EXPAND_SZ, which is designed to expand variables when read. Also IMO, any executable file located within a directory accessible by all users, (Anaconda), should be added to the System PATH, not the User PATH ... Commented Sep 12 at 13:31
  • ... So when you do your checks for the first one for example, you'd need to look for each of %UserProfile%\AppData\Roaming\Python\Python311\Scripts, %Appdata%\Python\Python311\Scripts, %SystemDrive%\Users\tknguye\AppData\Roaming\Python\Python311\Scripts and C:\Users\tknguye\AppData\Roaming\Python\Python311\Scripts, to cover each of the most likely existing entries for just that one location. Commented Sep 12 at 13:32

1 Answer 1

3

This is a quirk of findstr:

The findstr string parser handles a backslash followed by a non alphanumeric character as a single escaped character. That is

REM searches for just _, finds it
echo _ | findstr \_
_

REM searches for literally \a, finds nothing
echo a | findstr \a

\_ becomes just _ in the search string, so the script searches the path for ...Anaconda3_conda.exe which is not there. Escape the backslash to search for a backslash followed by a non alphanumeric character: \\_ becomes \_ in the search string.

set "newPath=%ProgramFiles%\Continuum\Anaconda3\\_conda.exe"

would do what you want, but you only need directory entries in the path. Which I would not let end on a trailing backslash because of such problems.

Sign up to request clarification or add additional context in comments.

Comments