How to check if a directory exists in %PATH%
Asked Answered
V

22

76

How does one check if a directory is already present in the PATH environment variable? Here's a start. All I've managed to do with the code below, though, is echo the first directory in %PATH%. Since this is a FOR loop you'd think it would enumerate all the directories in %PATH%, but it only gets the first one.

Is there a better way of doing this? Something like FIND or FINDSTR operating on the %PATH% variable? I'd just like to check if a directory exists in the list of directories in %PATH%, to avoid adding something that might already be there.

FOR /F "delims=;" %%P IN ("%PATH%") DO (
    @ECHO %%~P
)
Villada answered 26/9, 2008 at 19:12 Comment(1)
A corresponding question for PowerShell nearly 14 years later (but there may have been many already).Sanctitude
G
107

First I will point out a number of issues that make this problem difficult to solve perfectly. Then I will present the most bullet-proof solution I have been able to come up with.

For this discussion I will use lower case path to represent a single folder path in the file system, and upper case PATH to represent the PATH environment variable.

From a practical standpoint, most people want to know if PATH contains the logical equivalent of a given path, not whether PATH contains an exact string match of a given path. This can be problematic because:

  1. The trailing \ is optional in a path
    Most paths work equally well both with and without the trailing \. The path logically points to the same location either way. The PATH frequently has a mixture of paths both with and without the trailing \. This is probably the most common practical issue when searching a PATH for a match.

    • There is one exception: The relative path C: (meaning the current working directory of drive C) is very different than C:\ (meaning the root directory of drive C)

  2. Some paths have alternate short names
    Any path that does not meet the old 8.3 standard has an alternate short form that does meet the standard. This is another PATH issue that I have seen with some frequency, particularly in business settings.

  3. Windows accepts both / and \ as folder separators within a path.
    This is not seen very often, but a path can be specified using / instead of \ and it will function just fine within PATH (as well as in many other Windows contexts)

  4. Windows treats consecutive folder separators as one logical separator.
    C:\FOLDER\\ and C:\FOLDER\ are equivalent. This actually helps in many contexts when dealing with a path because a developer can generally append \ to a path without bothering to check if the trailing \ already exists. But this obviously can cause problems if trying to perform an exact string match.

    • Exceptions: Not only is C:, different than C:\, but C:\ (a valid path), is different than C:\\ (an invalid path).

  5. Windows trims trailing dots and spaces from file and directory names.
    "C:\test. " is equivalent to "C:\test".

  6. The current .\ and parent ..\ folder specifiers may appear within a path
    Unlikely to be seen in real life, but something like C:\.\parent\child\..\.\child\ is equivalent to C:\parent\child

  7. A path can optionally be enclosed within double quotes.
    A path is often enclosed in quotes to protect against special characters like <space> , ; ^ & =. Actually any number of quotes can appear before, within, and/or after the path. They are ignored by Windows except for the purpose of protecting against special characters. The quotes are never required within PATH unless a path contains a ;, but the quotes may be present never-the-less.

  8. A path may be fully qualified or relative.
    A fully qualified path points to exactly one specific location within the file system. A relative path location changes depending on the value of current working volumes and directories. There are three primary flavors of relative paths:

    • D: is relative to the current working directory of volume D:
    • \myPath is relative to the current working volume (could be C:, D: etc.)
    • myPath is relative to the current working volume and directory

    It is perfectly legal to include a relative path within PATH. This is very common in the Unix world because Unix does not search the current directory by default, so a Unix PATH will often contain .\. But Windows does search the current directory by default, so relative paths are rare in a Windows PATH.

So in order to reliably check if PATH already contains a path, we need a way to convert any given path into a canonical (standard) form. The ~s modifier used by FOR variable and argument expansion is a simple method that addresses issues 1 - 6, and partially addresses issue 7. The ~s modifier removes enclosing quotes, but preserves internal quotes. Issue 7 can be fully resolved by explicitly removing quotes from all paths prior to comparison. Note that if a path does not physically exist then the ~s modifier will not append the \ to the path, nor will it convert the path into a valid 8.3 format.

The problem with ~s is it converts relative paths into fully qualified paths. This is problematic for Issue 8 because a relative path should never match a fully qualified path. We can use FINDSTR regular expressions to classify a path as either fully qualified or relative. A normal fully qualified path must start with <letter>:<separator> but not <letter>:<separator><separator>, where <separator> is either \ or /. UNC paths are always fully qualified and must start with \\. When comparing fully qualified paths we use the ~s modifier. When comparing relative paths we use the raw strings. Finally, we never compare a fully qualified path to a relative path. This strategy provides a good practical solution for Issue 8. The only limitation is two logically equivalent relative paths could be treated as not matching, but this is a minor concern because relative paths are rare in a Windows PATH.

There are some additional issues that complicate this problem:

9) Normal expansion is not reliable when dealing with a PATH that contains special characters.
Special characters do not need to be quoted within PATH, but they could be. So a PATH like C:\THIS & THAT;"C:\& THE OTHER THING" is perfectly valid, but it cannot be expanded safely using simple expansion because both "%PATH%" and %PATH% will fail.

10) The path delimiter is also valid within a path name
A ; is used to delimit paths within PATH, but ; can also be a valid character within a path, in which case the path must be quoted. This causes a parsing issue.

jeb solved both issues 9 and 10 at 'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell

So we can combine the ~s modifier and path classification techniques along with my variation of jeb's PATH parser to get this nearly bullet proof solution for checking if a given path already exists within PATH. The function can be included and called from within a batch file, or it can stand alone and be called as its own inPath.bat batch file. It looks like a lot of code, but over half of it is comments.

@echo off
:inPath pathVar
::
::  Tests if the path stored within variable pathVar exists within PATH.
::
::  The result is returned as the ERRORLEVEL:
::    0 if the pathVar path is found in PATH.
::    1 if the pathVar path is not found in PATH.
::    2 if pathVar is missing or undefined or if PATH is undefined.
::
::  If the pathVar path is fully qualified, then it is logically compared
::  to each fully qualified path within PATH. The path strings don't have
::  to match exactly, they just need to be logically equivalent.
::
::  If the pathVar path is relative, then it is strictly compared to each
::  relative path within PATH. Case differences and double quotes are
::  ignored, but otherwise the path strings must match exactly.
::
::------------------------------------------------------------------------
::
:: Error checking
if "%~1"=="" exit /b 2
if not defined %~1 exit /b 2
if not defined path exit /b 2
::
:: Prepare to safely parse PATH into individual paths
setlocal DisableDelayedExpansion
set "var=%path:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
set "var=!var:"S"S=";"!"
::
:: Remove quotes from pathVar and abort if it becomes empty
set "new=!%~1:"=!"
if not defined new exit /b 2
::
:: Determine if pathVar is fully qualified
echo("!new!"|findstr /i /r /c:^"^^\"[a-zA-Z]:[\\/][^\\/]" ^
                           /c:^"^^\"[\\][\\]" >nul ^
  && set "abs=1" || set "abs=0"
::
:: For each path in PATH, check if path is fully qualified and then do
:: proper comparison with pathVar.
:: Exit with ERRORLEVEL 0 if a match is found.
:: Delayed expansion must be disabled when expanding FOR variables
:: just in case the value contains !
for %%A in ("!new!\") do for %%B in ("!var!") do (
  if "!!"=="" endlocal
  for %%C in ("%%~B\") do (
    echo(%%B|findstr /i /r /c:^"^^\"[a-zA-Z]:[\\/][^\\/]" ^
                           /c:^"^^\"[\\][\\]" >nul ^
      && (if %abs%==1 if /i "%%~sA"=="%%~sC" exit /b 0) ^
      || (if %abs%==0 if /i "%%~A"=="%%~C" exit /b 0)
  )
)
:: No match was found so exit with ERRORLEVEL 1
exit /b 1

The function can be used like so (assuming the batch file is named inPath.bat):

set test=c:\mypath
call inPath test && (echo found) || (echo not found)



Typically the reason for checking if a path exists within PATH is because you want to append the path if it isn't there. This is normally done simply by using something like path %path%;%newPath%. But Issue 9 demonstrates how this is not reliable.

Another issue is how to return the final PATH value across the ENDLOCAL barrier at the end of the function, especially if the function could be called with delayed expansion enabled or disabled. Any unescaped ! will corrupt the value if delayed expansion is enabled.

These problems are resolved using an amazing safe return technique that jeb invented here: http://www.dostips.com/forum/viewtopic.php?p=6930#p6930

@echo off
:addPath pathVar /B
::
::  Safely appends the path contained within variable pathVar to the end
::  of PATH if and only if the path does not already exist within PATH.
::
::  If the case insensitive /B option is specified, then the path is
::  inserted into the front (Beginning) of PATH instead.
::
::  If the pathVar path is fully qualified, then it is logically compared
::  to each fully qualified path within PATH. The path strings are
::  considered a match if they are logically equivalent.
::
::  If the pathVar path is relative, then it is strictly compared to each
::  relative path within PATH. Case differences and double quotes are
::  ignored, but otherwise the path strings must match exactly.
::
::  Before appending the pathVar path, all double quotes are stripped, and
::  then the path is enclosed in double quotes if and only if the path
::  contains at least one semicolon.
::
::  addPath aborts with ERRORLEVEL 2 if pathVar is missing or undefined
::  or if PATH is undefined.
::
::------------------------------------------------------------------------
::
:: Error checking
if "%~1"=="" exit /b 2
if not defined %~1 exit /b 2
if not defined path exit /b 2
::
:: Determine if function was called while delayed expansion was enabled
setlocal
set "NotDelayed=!"
::
:: Prepare to safely parse PATH into individual paths
setlocal DisableDelayedExpansion
set "var=%path:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
set "var=!var:"S"S=";"!"
::
:: Remove quotes from pathVar and abort if it becomes empty
set "new=!%~1:"^=!"
if not defined new exit /b 2
::
:: Determine if pathVar is fully qualified
echo("!new!"|findstr /i /r /c:^"^^\"[a-zA-Z]:[\\/][^\\/]" ^
                           /c:^"^^\"[\\][\\]" >nul ^
  && set "abs=1" || set "abs=0"
::
:: For each path in PATH, check if path is fully qualified and then
:: do proper comparison with pathVar. Exit if a match is found.
:: Delayed expansion must be disabled when expanding FOR variables
:: just in case the value contains !
for %%A in ("!new!\") do for %%B in ("!var!") do (
  if "!!"=="" setlocal disableDelayedExpansion
  for %%C in ("%%~B\") do (
    echo(%%B|findstr /i /r /c:^"^^\"[a-zA-Z]:[\\/][^\\/]" ^
                           /c:^"^^\"[\\][\\]" >nul ^
      && (if %abs%==1 if /i "%%~sA"=="%%~sC" exit /b 0) ^
      || (if %abs%==0 if /i %%A==%%C exit /b 0)
  )
)
::
:: Build the modified PATH, enclosing the added path in quotes
:: only if it contains ;
setlocal enableDelayedExpansion
if "!new:;=!" neq "!new!" set new="!new!"
if /i "%~2"=="/B" (set "rtn=!new!;!path!") else set "rtn=!path!;!new!"
::
:: rtn now contains the modified PATH. We need to safely pass the
:: value accross the ENDLOCAL barrier
::
:: Make rtn safe for assignment using normal expansion by replacing
:: % and " with not yet defined FOR variables
set "rtn=!rtn:%%=%%A!"
set "rtn=!rtn:"=%%B!"
::
:: Escape ^ and ! if function was called while delayed expansion was enabled.
:: The trailing ! in the second assignment is critical and must not be removed.
if not defined NotDelayed set "rtn=!rtn:^=^^^^!"
if not defined NotDelayed set "rtn=%rtn:!=^^^!%" !
::
:: Pass the rtn value accross the ENDLOCAL barrier using FOR variables to
:: restore the % and " characters. Again the trailing ! is critical.
for /f "usebackq tokens=1,2" %%A in ('%%^ ^"') do (
  endlocal & endlocal & endlocal & endlocal & endlocal
  set "path=%rtn%" !
)
exit /b 0
Goldarn answered 8/11, 2011 at 5:54 Comment(13)
1) My original post had a bogus statement about consecutive dots in a path. This was replaced by a correct issue concerning trailing dots. 2) Originally forgot about the short name issue so I used the ~f modifier. The change to the ~s modifier is a significant improvement.Goldarn
Made significant changes to code to support relative paths and to allow calling of function while delayed expansion is enabled. Also added more explanation as well as extensive comments to code.Goldarn
++ This is the most complete description about path issues I've ever seen :-)Pyrethrin
the example call inPath test && (echo found) || (echo not found) is not quite right, test should be %test%Riot
@mattwilkie - No, the example is correct. The script expects the name of a variable that contains the path to test. It is not expecting the string literal. It is a way of passing a value by reference in batch.Goldarn
oh. thanks for the clarification (and that also explains why I wasn't getting the right results). Triple thanks for this answer in the first place. +10 if I could.Riot
@Goldarn if not defined %~1 exit /b 2 always kicks in for me.Aristotelian
@AlexOkrushko - Did you read the instructions on how to call the routines? Did you read the 2 comments prior to yours? You are probably passing the path as a string literal instead of passing the name of a variable that contains the path info.Goldarn
@Goldarn Yep, it was my bad. I was using the string literal. But since other people also had the same problem it means that the answer is not very presentable. I understand that a lot of work (and good work) was done, however 99.9% percent of people who got to this page were probably looking for something as simple as echo ;%PATH%; | find /C /I ";<string>;" (as in @Andriy M comment to Randy's answer)Aristotelian
Thank you dbenham. I happen to have the same requirement recently, and I found your information EXCELLENT. Really appreciate your contribution and effort.Educatory
addPath will only add the path for the current batch file. If you want to add a path permanently add setx path "%rtn%" /M after set "path=%rtn%" ! You'll need admin rights for that to work.Pterous
I have a UNC path like \\NetworkPath\Folder\Sub Folder (Please note that there is space between Sub and Folder). I am using the following regular expression /^\\(\\[^\s\\]+)+(\\)?$/ but it does not handle spaces (Except for space issue, this works absolutely fine) in folder names. How do I handle this ?Sansculotte
@Sansculotte - What the hell does a regex issue have to do with this answer (or original question)? Hint - Nothing what-so-ever.Goldarn
R
45

This may work:

echo ;%PATH%; | find /C /I ";<string>;"

It should give you 0 if the string is not found and 1 or more if it is.

Richthofen answered 26/9, 2008 at 19:19 Comment(10)
To be complete add the case-insensitive flag /I to find.Digit
Does this really solve Axl's problem? He wants to check if adding a directory, say C:\foo\bar to PATH would be redundant. Let's say his PATH already contained c:\foo, your check would say "yes, it's redundant" when it's actually not.Jasper
Actually this elegant one-liner can be easily fixed: echo ;%PATH%; | find /C /I ";<string>;".Aforementioned
@AndriyM: I took the liberty of editing your comment into the answer, seeing as it was extremely helpful.Prelate
@Jon: Yup, something I myself should have had courage to do at the time, thanks.Aforementioned
How do you get the result of that command from within a batch file? I tried to call this from within a FOR /F construct, but since my path variable includes directories with parentheses (C:\Program Files (x86)\...), I am getting the error "... was unexpected at this time."Tuberculous
@JeffG: If I'm not too late with my suggestion, you could try enclosing the ;%PATH%; in quotation marks: echo ";%PATH%;" | find /C /I ";<string>;".Aforementioned
@JeffG: you need ^ before pipeUncertain
Example of use: for /f "delims=" %%A in ('echo ";%PATH%;" ^| find /C /I ";<string>;"') do set "TimesFound=%%A"Uncertain
echo %PATH% | find /C /I "jdk" works just fine.Pavlov
L
23

Another way to check if something is in the path is to execute some innocent executable that is not going to fail if it's there, and check the result.

As an example, the following code snippet checks if Maven is in the path:

mvn --help > NUL 2> NUL
if errorlevel 1 goto mvnNotInPath

So I try to run mvn --help, ignore the output (I don't actually want to see the help if Maven is there) (> NUL), and also don't display the error message if Maven was not found (2> NUL).

Lifelike answered 1/4, 2010 at 9:24 Comment(0)
N
13

After reading the answers here I think I can provide a new point of view: if the purpose of this question is to know if the path to a certain executable file exists in %PATH% and if not, insert it (and this is the only reason to do that, I think), then it may solved in a slightly different way: "How to check if the directory of a certain executable program exist in %PATH%"? This question may be easily solved this way:

for %%p in (programname.exe) do set "progpath=%%~$PATH:p"
if not defined progpath (
   rem The path to programname.exe don't exist in PATH variable, insert it:
   set "PATH=%PATH%;C:\path\to\progranname"
)

If you don't know the extension of the executable file, just review all of them:

set "progpath="
for %%e in (%PATHEXT%) do (
   if not defined progpath (
      for %%p in (programname.%%e) do set "progpath=%%~$PATH:p"
   )
)
Neustria answered 28/10, 2013 at 19:6 Comment(1)
+1, If you don't know the name of a program in the folder, then you can simply create a dummy file in that location (assuming you have write access). It need not have a PATHEXT extension. Just remember to delete the dummy file when done.Goldarn
D
6

Using for and delims, you cannot capture an arbitrary number of fields (as Adam pointed out as well) so you have to use a looping technique instead. The following command script will list each path in the PATH environment variable on a separate line:

@echo off 
setlocal 
if "%~1"=="" (
    set PATHQ=%PATH%
) else (
    set PATHQ=%~1 ) 
:WHILE
    if "%PATHQ%"=="" goto WEND
    for /F "delims=;" %%i in ("%PATHQ%") do echo %%i
    for /F "delims=; tokens=1,*" %%i in ("%PATHQ%") do set PATHQ=%%j
    goto WHILE 
:WEND

It simulates a classical whilewend construct found in many programming languages. With this in place, you can use something like findstr to subsequently filter and look for a particular path. For example, if you saved the above script in a file called tidypath.cmd then here is how you could pipe to findstr, looking for paths under the standard programs directory (using a case-insensitive match):

> tidypath | findstr /i "%ProgramFiles%"
Dogtrot answered 1/10, 2008 at 14:4 Comment(1)
Seems like the two for loops could be merged into one: for /F "delims=; tokens=1,*" %%i in ("%PATHQ%") do (echo %%i&set PATHQ=%%j).Aforementioned
M
5

Just to elaborate on Heyvoon's response (2015-06-08) using PowerShell, this simple PowerShell script should give you detail on %path%:

$env:Path -split ";" | % {"$(test-path $_); $_"}

It is generating this kind of output which you can independently verify:

True;C:\WINDOWS
True;C:\WINDOWS\system32
True;C:\WINDOWS\System32\Wbem
False;C:windows\System32\windowsPowerShell\v1.0\
False;C:\Program Files (x86)\Java\jre7\bin

To reassemble for updating Path:

$x = $null; foreach ($t in ($env:Path -split ";") ) {if (test-path $t) {$x += $t + ";"}}; $x
Maugre answered 5/5, 2017 at 23:51 Comment(0)
U
4

This will look for an exact but case-insensitive match, so mind any trailing backslashes etc.:

for %P in ("%path:;=";"%") do @if /i %P=="PATH_TO_CHECK" echo %P exists in PATH

or, in a batch file (e.g. checkpath.bat) which takes an argument:

@for %%P in ("%path:;=";"%") do @if /i %%P=="%~1" echo %%P exists in PATH

In the latter form, one could call e.g. checkpath "%ProgramFiles%" to see if the specified path already exists in PATH.

Please note that this implementation assumes no semicolons or quotes are present inside a single path item.

Unexpressive answered 6/4, 2011 at 21:10 Comment(1)
Unfortunately this cannot deal with ++ in the path environment variable (as in Notepad++).Danger
B
3

You can also use substring replacement to test for the presence of a substring. Here I remove quotes to create PATH_NQ, then I remove "c:\mydir" from the PATH_NQ and compare it to the original to see if anything changed:

set PATH_NQ=%PATH:"=%
if not "%PATH_NQ%"=="%PATH_NQ:c:\mydir=%" goto already_in_path
set PATH=%PATH%;c:\mydir
:already_in_path
Broderickbrodeur answered 23/7, 2011 at 18:40 Comment(0)
J
2

If your question was "why doesn't this cmd script fragment work?" then the answer is that for /f iterates over lines. The delims split lines into fields, but you're only capturing the first field in %%P. There is no way to capture an arbitrary number of fields with a for /f loop.

Jasper answered 26/9, 2008 at 22:36 Comment(0)
R
2

I took your implementation using the for loop and extended it into something that iterates through all elements of the path. Each iteration of the for loop removes the first element of the path (%p) from the entire path (held in %q and %r).

@echo off
SET MYPATHCOPY=%PATH%

:search
for /f "delims=; tokens=1,2*" %%p in ("%MYPATHCOPY%") do (
   @echo %%~p
   SET MYPATHCOPY=%%~q;%%~r
)

if "%MYPATHCOPY%"==";" goto done;
goto search;

:done

Sample output:

Z:\>path.bat
C:\Program Files\Microsoft DirectX SDK (November 2007)\Utilities\Bin\x86
c:\program files\imagemagick-6.3.4-q16
C:\WINDOWS\system32
C:\WINDOWS
C:\SFU\common\
c:\Program Files\Debugging Tools for Windows
C:\Program Files\Nmap
Ramon answered 27/9, 2008 at 0:26 Comment(0)
S
2

This version works fairly well. It simply checks whether executable vim71 (Vim 7.1) is in the path, and prepends it if not.

@echo off
echo %PATH% | find /c /i "vim71" > nul
if not errorlevel 1 goto jump
PATH = C:\Program Files\Vim\vim71\;%PATH%
:jump

This demo is to illustrate the errorlevel logic:

@echo on
echo %PATH% | find /c /i "Windows"
if "%errorlevel%"=="0" echo Found Windows
echo %PATH% | find /c /i "Nonesuch"
if "%errorlevel%"=="0" echo Found Nonesuch

The logic is reversed in the vim71 code since errorlevel 1 is equivalent to errorlevel >= 1. It follows that errorlevel 0 would always evaluate true, so "not errorlevel 1" is used.

Postscript: Checking may not be necessary if you use SETLOCAL and ENDLOCAL to localise your environment settings, e.g.,

@echo off
setlocal
PATH = C:\Program Files\Vim\vim71\;%PATH%
rem your code here
endlocal

After ENDLOCAL you are back with your original path.

Swage answered 7/10, 2011 at 9:15 Comment(1)
setlocal/endlocal is a great suggestion.Softball
F
2

I've combined some of the above answers to come up with this to ensure that a given path entry exists exactly as given with as much brevity as possible and no junk echos on the command line.

set myPath=<pathToEnsure | %1>
echo ;%PATH%; | find /C /I ";%myPath%;" >nul
if %ERRORLEVEL% NEQ 0 set PATH=%PATH%;%myPath%
Flense answered 11/10, 2011 at 19:44 Comment(0)
J
1

Building on Randy's answer, you have to make sure a substring of the target isn't found.

if a%X%==a%PATH% echo %X% is in PATH
echo %PATH% | find /c /i ";%X%"
if errorlevel 1 echo %X% is in PATH
echo %PATH% | find /c /i "%X%;"
if errorlevel 1 echo %X% is in PATH
Jasper answered 26/9, 2008 at 22:44 Comment(0)
T
1

You mention that you want to avoid adding the directory to search path if it already exists there. Is your intention to store the directory permanently to the path, or just temporarily for batch file's sake?

If you wish to add (or remove) directories permanently to PATH, take a look at Path Manager (pathman.exe) utility in Windows Resource Kit Tools for administrative tasks, http://support.microsoft.com/kb/927229. With that you can add or remove components of both system and user paths, and it will handle anomalies such as duplicate entries.

If you need to modify the path only temporarily for a batch file, I would just add the extra path in front of the path, with the risk of slight performance hit because of duplicate entry in the path.

Tini answered 1/10, 2008 at 13:43 Comment(1)
The link is broken: "Sorry, page not found"Sanctitude
E
1

Add the directory to PATH if it does not already exist:

set myPath=c:\mypath
For /F "Delims=" %%I In ('echo %PATH% ^| find /C /I "%myPath%"') Do set pathExists=%%I 2>Nul
If %pathExists%==0 (set PATH=%myPath%;%PATH%)
Evelyn answered 14/3, 2011 at 9:23 Comment(1)
This overly simplistic "solution" falsely detects presence of c:\abc if c:\abcd exists. This problem is not easily fixed without introducing other problems.Goldarn
A
1

Just as an alternative:

  1. In the folder you are going to search the PATH variable for, create a temporary file with such an unusual name that you would never ever expect any other file on your computer to have.

  2. Use the standard batch scripting construct that lets you perform the search for a file by looking up a directory list defined by some environment variable (typically PATH).

  3. Check if the result of the search matches the path in question, and display the outcome.

  4. Delete the temporary file.

This might look like this:

@ECHO OFF
SET "mypath=D:\the\searched-for\path"
SET unusualname=nowthisissupposedtobesomeveryunusualfilename
ECHO.>"%mypath%\%unusualname%"
FOR %%f IN (%unusualname%) DO SET "foundpath=%%~dp$PATH:f"
ERASE "%mypath%\%unusualname%"
IF "%mypath%" == "%foundpath%" (
  ECHO The dir exists in PATH
) ELSE (
  ECHO The dir DOES NOT exist in PATH
)

Known issues:

  1. The method can work only if the directory exists (which isn't always the case).

  2. Creating / deleting files in a directory affects its 'modified date/time' attribute (which may be an undesirable effect sometimes).

  3. Making up a globally unique file name in one's mind cannot be considered very reliable. Generating such a name is itself not a trivial task.

Aforementioned answered 6/4, 2011 at 22:59 Comment(0)
Q
1

In general, this is to add an EXE or DLL file on the path. As long as this file won’t appear anywhere else:

@echo off
where /q <put filename here>
if %errorlevel% == 1 (
    setx PATH "%PATH%;<additional path stuff>"
) else (
    echo "already set path"
)
Quinquereme answered 13/6, 2012 at 15:37 Comment(0)
S
1

This is a variation of Kevin Edwards's answer using string replacement.

The basic pattern is:

IF "%PATH:new_path=%" == "%PATH%" PATH=%PATH%;new_path

For example:

IF "%PATH:C:\Scripts=%" == "%PATH%" PATH=%PATH%;C:\Scripts

In a nutshell, we make a conditional test where we attempt to remove/replace new_path from our PATH environment variable. If new_path doesn't exist, the condition succeeds and the new_path will be appended to PATH for the first time. If new_path already exists then the condition fails and we will not add new_path a second time.

Santalaceous answered 28/4, 2014 at 23:58 Comment(0)
T
1

You can accomplish this using PowerShell;

Test-Path $ENV:SystemRoot\YourDirectory
Test-Path C:\Windows\YourDirectory

This returns TRUE or FALSE

Short, simple and easy!

Thiamine answered 8/6, 2015 at 14:6 Comment(0)
H
0

This routine will search for a path\ or file.ext in the path variable. It returns 0 if found. Path\ or file may contain spaces if quoted. If a variable is passed as the last argument, it will be set to d:\path\file.

@echo off&goto :PathCheck
:PathCheck.CMD
echo.PathCheck.CMD: Checks for existence of a path or file in %%PATH%% variable
echo.Usage: PathCheck.CMD [Checkpath] or [Checkfile] [PathVar]
echo.Checkpath must have a trailing \ but checkfile must not
echo.If Checkpath contains spaces use quotes ie. "C:\Check path\"
echo.Checkfile must not include a path, just the filename.ext
echo.If Checkfile contains spaces use quotes ie. "Check File.ext"
echo.Returns 0 if found, 1 if not or -1 if checkpath does not exist at all
echo.If PathVar is not in command line it will be echoed with surrounding quotes
echo.If PathVar is passed it will be set to d:\path\checkfile with no trailing \
echo.Then %%PathVar%% will be set to the fully qualified path to Checkfile
echo.Note: %%PathVar%% variable set will not be surrounded with quotes
echo.To view the path listing line by line use: PathCheck.CMD /L
exit/b 1

:PathCheck
if "%~1"=="" goto :PathCheck.CMD
setlocal EnableDelayedExpansion
set "PathVar=%~2"
set "pth="
set "pcheck=%~1"
if "%pcheck:~-1%" equ "\" (
  if not exist %pcheck% endlocal&exit/b -1
  set/a pth=1
)
for %%G in ("%path:;=" "%") do (
  set "Pathfd=%%~G\"
  set "Pathfd=!Pathfd:\\=\!"
  if /i "%pcheck%" equ "/L" echo.!Pathfd!
  if defined pth (
    if /i "%pcheck%" equ "!Pathfd!" endlocal&exit/b 0
  ) else (
    if exist "!Pathfd!%pcheck%" goto :CheckfileFound
  )
)
endlocal&exit/b 1

:CheckfileFound
endlocal&(
  if not "%PathVar%"=="" (
    call set "%~2=%Pathfd%%pcheck%"
  ) else (echo."%Pathfd%%pcheck%")
  exit/b 0
)
Hbeam answered 14/10, 2012 at 17:7 Comment(0)
C
0

-contains worked for me

$pathToCheck = "c:\some path\to\a\file.txt"

$env:Path - split ';' -contains $pathToCheck

To add the path when it does not exist yet I use

$pathToCheck = "c:\some path\to\a\file.txt"

if(!($env:Path -split ';' -contains $vboxPath)) {
  $documentsDir = [Environment]::GetFolderPath("MyDocuments")
  $profileFilePath = Join-Path $documentsDir "WindowsPowerShell/profile.ps1"
  Out-File -FilePath $profileFilePath -Append -Force -Encoding ascii -InputObject "`$env:Path += `";$pathToCheck`""
  Invoke-Expression -command $profileFilePath
}
Classless answered 4/7, 2019 at 8:3 Comment(0)
S
0
rem https://mcmap.net/q/13212/-how-do-i-add-to-the-windows-path-variable-using-setx-having-weird-problems
rem Don't get mess with %PATH%, it is a concatenation of USER+SYSTEM, and will cause a lot of duplication in the result. 
for /f "usebackq tokens=2,*" %%A in (`reg query HKCU\Environment /v PATH`) do set userPATH=%%B
rem userPATH should be %USERPROFILE%\AppData\Local\Microsoft\WindowsApps

rem https://stackoverflow.com/questions/141344
for /f "delims=" %%A in ('echo ";%userPATH%;" ^| find /C /I ";%WINAPPS%;"') do set pathExists=%%A
If %pathExists%==0 (
    echo Inserting user path...
    setx PATH "%WINAPPS%; %userPATH%"
)
Sapotaceous answered 7/1, 2022 at 6:44 Comment(1)
An explanation would be in order. E.g., what is the idea/gist? From the Help Center: "...always explain why the solution you're presenting is appropriate and how it works". Please respond by editing (changing) your answer, not here in comments (without "Edit:", "Update:", or similar - the answer should appear as if it was written today).Sanctitude

© 2022 - 2024 — McMap. All rights reserved.