如何检查%PATH%中是否存在目录?

时间:2008-09-26 19:12:26

标签: windows batch-file

如何检查PATH环境变量中是否已存在目录?这是一个开始。但是,我已经设法使用下面的代码,它回显了%PATH%中的第一个目录。由于这是一个FOR循环,你会认为它将枚举%PATH%中的所有目录,但它只获得第一个目录。

有更好的方法吗?像%PATH%变量上运行的find或findstr之类的东西?我只想检查%PATH%目录列表中是否存在目录,以避免添加可能已存在的目录。

FOR /F "delims=;" %%P IN ("%PATH%") DO (
    @ECHO %%~P
)

22 个答案:

答案 0 :(得分:87)

首先,我将指出一些使这个问题难以完美解决的问题。然后我将介绍我能够提出的最具防弹性的解决方案。

在本次讨论中,我将使用小写路径表示文件系统中的单个文件夹路径,使用大写PATH表示PATH环境变量。

从实际角度来看,大多数人都想知道PATH是否包含给定路径的逻辑等价物,而不是PATH是否包含给定路径的精确字符串匹配。这可能有问题,因为:

  1. 结尾\在路径中是可选的
    大多数路径在有和没有尾随\的情况下同样有效。路径逻辑上指向同一位置。 PATH经常混合使用带有和不带尾随\的路径。在搜索匹配的PATH时,这可能是最常见的实际问题。

    • 有一个例外:相对路径C:(表示驱动器C的当前工作目录)与C:\(表示驱动器C的根目录)非常不同

  2. 某些路径有备用短名称
    任何不符合旧8.3标准的路径都有一个符合标准的备用简表。这是我在某些频率上看到的另一个PATH问题,特别是在商业环境中。

  3. Windows同时接受/\作为路径中的文件夹分隔符。
    这种情况不常见,但可以使用/而不是\指定路径,它在PATH(以及许多其他Windows上下文)中运行良好

  4. Windows将连续文件夹分隔符视为一个逻辑分隔符。
    C:\ FOLDER \\和C:\ FOLDER \是等效的。在处理路径时,这实际上有助于许多上下文,因为开发人员通常可以将\附加到路径,而无需检查尾随\是否已存在。但是,如果尝试执行精确的字符串匹配,这显然会导致问题。

    • 例外:C:不仅与C:\不同,而且C:\(有效路径)与C:\\(无效路径)不同。

  5. Windows修剪文件和目录名称中的尾随点和空格。
    "C:\test. "相当于"C:\test"

  6. 当前.\和父..\文件夹说明符可能会显示在路径中
    不太可能在现实生活中看到,但像C:\.\parent\child\..\.\child\这样的东西相当于C:\parent\child

  7. 路径可以选择用双引号括起来。
    路径通常用引号括起来,以防止<space> , ; ^ & =等特殊字符。实际上,在路径之前,之内和/或之后可以出现任意数量的引号。它们被Windows忽略,除非是为了防止特殊字符。除非路径包含;,否则在PATH中永远不需要引号,但引号可能永远不会出现。

  8. 路径可能完全合格或相对。
    完全限定的路径指向文件系统中的一个特定位置。相对路径位置根据当前工作卷和目录的值而变化。相对路径有三种主要风格:

    • D: 相对于卷D的当前工作目录:
    • \myPath 相对于当前的工作量(可能是C:,D:等)
    • myPath 与当前工作量和目录相关

    在PATH中包含相对路径是完全合法的。这在Unix世界中很常见,因为Unix默认情况下不搜索当前目录,因此Unix PATH通常包含.\。但Windows默认搜索当前目录,因此Windows PATH中的相对路径很少见。

  9. 因此,为了可靠地检查PATH是否已包含路径,我们需要一种方法将任何给定路径转换为规范(标准)形式。 FOR变量和参数扩展使用的~s修饰符是解决问题1 - 6的简单方法,部分解决了问题7. ~s修饰符删除了封闭引号,但保留了内部引号。通过在比较之前显式删除所有路径中的引号,可以完全解决问题7。请注意,如果路径实际上不存在,则~s修饰符不会将\附加到路径,也不会将路径转换为有效的8.3格式。

    ~s的问题是它将相对路径转换为完全限定的路径。对于问题8,这是有问题的,因为相对路径永远不应与完全限定的路径匹配。我们可以使用FINDSTR正则表达式将路径分类为完全限定或相对。普通的完全限定路径必须以<letter>:<separator>开头,而不是<letter>:<separator><separator>,其中&lt; separator&gt;是\/。 UNC路径始终是完全限定的,必须以\\开头。在比较完全限定路径时,我们使用~s修饰符。比较相对路径时,我们使用原始字符串。最后,我们从不将完全限定的路径与相对路径进行比较。这个策略为问题8提供了一个很好的实际解决方案。唯一的限制是两个逻辑等效的相对路径可以被视为不匹配,但这是一个小问题,因为相对路径在Windows PATH中很少见。

    还有一些其他问题会使这个问题复杂化:

    9)处理包含特殊字符的PATH时,正常扩展不可靠。
     特殊字符不需要在PATH中引用,但它们可以是。所以像PATH一样 C:\THIS & THAT;"C:\& THE OTHER THING"完全有效,但无法使用简单扩展安全地展开,因为"%PATH%"%PATH%都会失败。

    10)路径分隔符在路径名称中也有效
    ;用于分隔PATH中的路径,但;也可以是路径中的有效字符,在这种情况下必须引用路径。这会导致解析问题。

    jeb在'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell

    解决了问题9和10

    因此,我们可以将~s修饰符和路径分类技术与我的jeb的PATH解析器的变体结合起来,以获得这种近乎防弹的解决方案,用于检查PATH中是否已存在给定路径。该函数可以在批处理文件中包含和调用,也可以单独使用,并作为自己的inPath.bat批处理文件调用。它看起来像很多代码,但超过一半是评论。

    @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
    

    可以像这样使用该函数(假设批处理文件名为inPath.bat):

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


    <小时/> 通常,检查路径是否存在于PATH中的原因是因为如果路径不存在则要追加路径。这通常只需使用path %path%;%newPath%之类的东西即可完成。但问题9证明了这不可靠。

    另一个问题是如何在函数末尾的ENDLOCAL屏障上返回最终的PATH值,特别是如果可以在启用或禁用延迟扩展的情况下调用该函数。如果启用延迟扩展,任何未转义的!都将破坏该值。

    使用jeb在这里发明的惊人的安全返回技术来解决这些问题: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
    

答案 1 :(得分:36)

我暂时没有做任何批处理文件编程,但是:

echo ;%PATH%; | find /C /I ";<string>;"
如果找不到字符串,

应该给你0,如果是,则给出1或更多。

编辑:感谢Panos添加了不区分大小写的标记。

答案 2 :(得分:21)

检查路径中是否存在某些内容的另一种方法是执行一些无辜的可执行文件,如果它存在则不会失败,并检查结果。 例如,下一个代码段会检查 maven 是否在路径中:

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

所以我尝试运行 mvn --help ,忽略输出(如果maven在那里,实际上不想看到帮助)(&gt; NUL),也不显示如果找不到maven,则会显示错误消息(2&gt; NUL)。

答案 3 :(得分:8)

在阅读完这里的答案后,我想我可以提供一个新的观点:如果这个问题的目的是知道 %PATH%中是否存在某个可执行文件的路径如果没有,插入它(并且这是唯一的原因这样做,我认为),然后它可能以稍微不同的方式解决:“如何检查某个可执行程序的目录存在于%PATH%“?这个问题可以通过这种方式轻松解决:

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

如果您不知道可执行文件的扩展名,请查看所有文件:

set "progpath="
for %%e in (%PATHEXT%) do (
   if not defined progpath (
      for %%p in (programname.%%e) do set "progpath=%%~$PATH:p"
   )
)

答案 4 :(得分:6)

使用fordelims,您无法捕获任意数量的字段(例如Adam pointed out),因此您必须使用循环技术。以下命令脚本将在单独的一行中列出PATH环境变量中的每个路径:

@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

它模拟了在许多编程语言中找到的经典 ... wend 构造。 有了这个,您可以使用findstr之类的内容随后过滤并查找特定路径。例如,如果您将上述脚本保存在名为tidypath.cmd的文件中,那么您可以在此处管道findstr,查找标准程序目录下的路径(使用不区分大小写的匹配):< / p>

> tidypath | findstr /i "%ProgramFiles%"

答案 5 :(得分:4)

这将寻找精确但不区分大小写的匹配,因此请注意任何尾部反斜杠等:

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

或者,在带有参数的批处理文件(例如checkpath.bat)中:

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

在后一种形式中,人们可以呼叫,例如checkpath "%ProgramFiles%"查看PATH中是否已存在指定的路径。

请注意,此实现假设单个路径项中不存在分号或引号。

答案 6 :(得分:2)

如果你的问题是“为什么这个cmd脚本片段不起作用?”然后答案是for /f遍历线。 delims分割成字段,但您只捕获%%P中的第一个字段。无法使用for /f循环捕获任意数量的字段。

答案 7 :(得分:2)

我使用 for 循环实现了您的实现,并将其扩展为迭代遍历路径的所有元素的内容。 for循环的每次迭代都会从整个路径中删除路径的第一个元素(%p)(在%q和%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

示例输出:

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

答案 8 :(得分:2)

如果目录尚未存在,则将目录添加到PATH:

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

答案 9 :(得分:2)

您还可以使用子字符串替换来测试是否存在子字符串。在这里我删除引号来创建PATH_NQ,然后从PATH_NQ中删除“c:\ mydir”并将其与原始文件进行比较以查看是否有任何更改:

set PATH_NQ=%PATH:"=%
if not "%PATH_NQ%"=="%PATH_NQ:c:\mydir=%" goto already_in_path
set PATH=%PATH%;c:\mydir
:already_in_path

答案 10 :(得分:2)

我已经将上面的一些答案结合起来,以确保给定的路径条目完全一致,尽可能简洁,并且命令上没有垃圾回声线。

set myPath=<pathToEnsure | %1>
echo ;%PATH%; | find /C /I ";%myPath%;" >nul
if %ERRORLEVEL% NEQ 0 set PATH=%PATH%;%myPath%

答案 11 :(得分:1)

此版本运行良好。它只是检查vim71是否在路径中,如果没有则预先设置。

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

此演示用于说明错误级别逻辑:

@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

vim71代码中的逻辑相反,因为错误级别1相当于errorlevel&gt; = 1.因此,错误级别0将始终评估为真,因此使用“not errorlevel 1”。

Postscript 如果您使用setlocal和endlocal来本地化您的环境设置,则可能不需要检查,例如

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

在endlocal之后,你回到原来的路径。

答案 12 :(得分:1)

仅使用Powershell详细说明Heyvoon's (2015.06.08)响应,这个简单的Powershell脚本应该为您提供%path%

的详细信息
$env:Path -split ";" | % {"$(test-path $_);$_"}

生成此类输出,您可以单独验证

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

重组以更新路径:

$x=$null;foreach ($t in ($env:Path -split ";") ) {if (test-path $t) {$x+=$t+";"}};$x

答案 13 :(得分:1)

您可以使用PoweShell完成此操作;

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

这会返回TRUEFALSE

简短,简单,轻松!

答案 14 :(得分:1)

这是Kevin Edwards使用字符串替换的答案的变体。 基本模式是:

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

例如:

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

简而言之,我们进行条件测试,尝试从new_path环境变量中删除/替换PATH。如果new_path不存在,则条件成功,new_path将首次附加到PATH。如果new_path已存在,则条件失败,我们不会再次添加new_path

答案 15 :(得分:1)

通常这是在路径上放置一个exe / dll。只要这个文件不会出现在其他任何地方:

@echo off
where /q <put filename here>    
if %errorlevel% == 1 (
    setx PATH "%PATH%;<additional path stuff>"
) else (
    echo "already set path"
)

答案 16 :(得分:1)

对“addPath”脚本的评论; 当提供带空格的路径时,它会抛出。

实施例: 调用addPath“c:\ Program Files(x86)\ Microsoft SDKs \ Windows \ v7.0A \ Bin”

收率: “文件”不被识别为内部或外部命令, 可操作程序或批处理文件。

答案 17 :(得分:1)

作为替代方案:

  1. 在您要搜索PATH变量的文件夹中,创建一个临时文件,其中包含一个您不会指望计算机上任何其他文件具有的异常名称。

  2. 使用标准批处理脚本构造,该构造允许您通过查找由某个环境变量(通常为PATH)定义的目录列表来执行文件搜索。

  3. 检查搜索结果是否与相关路径匹配,并显示结果。

  4. 删除临时文件。

  5. 这可能如下所示:

    @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
    )
    

    已知问题:

    1. 该方法只有在目录存在时才能起作用(情况并非总是如此)。

    2. 创建/删除目录中的文件会影响其“修改日期/时间”属性(有时可能会产生不良影响)。

    3. 在一个人的脑海中创建一个全球唯一的文件名不能被认为是非常可靠的。生成这样的名称本身并不是一项微不足道的任务。

答案 18 :(得分:1)

您提到要避免将目录添加到搜索路径(如果该目录已存在)。您打算将目录永久存储到路径中,还是仅暂时存储批处理文件?

如果您希望永久地将目录添加(或删除)到PATH,请查看Windows资源工具包工具中的路径管理器(pathman.exe)实用程序,以获取管理任务http://support.microsoft.com/kb/927229。有了它,您可以添加或删除系统和用户路径的组件,它将处理异常,如重复条目。

如果您只需要临时修改批处理文件的路径,我只会在路径前添加额外的路径,因为路径中有重复的条目,可能会有轻微的性能损失。

答案 19 :(得分:1)

在rcar的答案基础上,你必须确保找不到目标的子串。

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

答案 20 :(得分:0)

此例程将在路径变量中搜索路径\或file.ext 如果找到则返回0。如果引用,路径\或文件可能包含空格。 如果变量作为最后一个参数传递,则它将设置为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
)

答案 21 :(得分:0)

-contains为我工作

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

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

要添加尚不存在的路径,请使用

$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
}