68

ディレクトリがすでにPATH環境変数に存在するかどうかを確認するにはどうすればよいですか? ここから始めます。ただし、以下のコードで何とかできたのは、%PATH% の最初のディレクトリをエコーすることだけです。これは FOR ループであるため、%PATH% 内のすべてのディレクトリを列挙すると思われますが、取得できるのは最初の 1 つだけです。

これを行うより良い方法はありますか?%PATH% 変数で動作する find や findstr のようなものですか? %PATH% のディレクトリのリストにディレクトリが存在するかどうかを確認して、既に存在する可能性のあるものを追加しないようにしたいと思います。

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

23 に答える 23

103

最初に、この問題を完全に解決するのを難しくしているいくつかの問題を指摘します。次に、私が思いついた中で最も防弾のソリューションを紹介します。

この説明では、小文字のパスを使用してファイル システム内の単一のフォルダー パスを表し、大文字の PATH を使用して PATH 環境変数を表します。

実用的な観点から、ほとんどの人は、PATH に特定のパスと完全に一致する文字列が含まれているかどうかではなく、PATH に特定のパスと論理的に同等のものが含まれているかどうかを知りたいと考えています。これは、次の理由で問題になる可能性があります。

  1. パスの末尾\はオプションです
    ほとんどのパスは、末尾の があってもなくても同じように機能し\ます。パスは、どちらの方法でも同じ場所を論理的に指しています。PATH には、多くの場合、末尾に\. これは、一致する PATH を検索する際のおそらく最も一般的な実際の問題です。

    • 例外が 1 つあります。相対パス(ドライブ C の現在の作業ディレクトリを意味する) は、 (ドライブ C のルート ディレクトリを意味する C:) とは大きく異なります。C:\

  2. 一部のパスには代替短縮名
    があります 古い 8.3 標準に準拠していないパスには、標準に適合する代替短縮名があります。これは、特にビジネス環境で頻繁に見られる PATH の問題です。

  3. Windows は、パス内のフォルダー セパレーターとしてと の両方/を受け入れます。\
    これはあまり見られませんが、/代わりに を使用してパスを指定することができ\、PATH 内で (および他の多くの Windows コンテキストと同様に) 正常に機能します。

  4. Windows は、連続するフォルダー区切りを 1 つの論理区切りとして扱います。
    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. パスは、完全修飾パスまたは相対パスにすることができます。
    完全修飾パスは、ファイル システム内の特定の 1 つの場所を指します。相対パスの場所は、現在の作業ボリュームとディレクトリの値によって異なります。相対パスには主に 3 つの種類があります。

    • D:ボリューム D の現在の作業ディレクトリに相対的です。
    • \myPath現在の作業ボリュームに相対的です (C:、D: など)。
    • myPath現在の作業ボリュームとディレクトリに相対的です

    PATH 内に相対パスを含めることは完全に合法です。これは、Unix の世界では非常に一般的です。Unix はデフォルトで現在のディレクトリを検索しないため、Unix PATH には多くの場合.\. ただし、Windows は既定で現在のディレクトリを検索するため、Windows PATH で相対パスが使用されることはほとんどありません。

したがって、PATH に既にパスが含まれているかどうかを確実に確認するには、任意のパスを正規 (標準) 形式に変換する方法が必要です。FOR 変数と引数の~s展開で使用される修飾子は、問題 1 ~ 6 に対処し、問題 7 に部分的に対処する単純な方法です。~s修飾子は、囲み引用符を削除しますが、内部引用符は保持します。問題 7 は、比較の前にすべてのパスから引用符を明示的に削除することで完全に解決できます。パスが物理的に存在しない場合、~s修飾子は をパスに追加せず\、パスを有効な 8.3 形式に変換しないことに注意してください。

問題~sは、相対パスを完全修飾パスに変換することです。相対パスは完全修飾パスと一致してはならないため、これは問題 8 の問題です。FINDSTR 正規表現を使用して、パスを完全修飾パスまたは相対パスとして分類できます。通常の完全修飾パスは で始まる必要<letter>:<separator>があり<letter>:<separator><separator>ますが、<separator> は または のいずれ\/です。UNC パスは常に完全修飾パスであり、で始まる必要があり\\ます。完全修飾パスを比較するときは、~s修飾子。相対パスを比較するときは、生の文字列を使用します。最後に、完全修飾パスを相対パスと比較することはありません。この戦略は、問題 8 の優れた実用的な解決策を提供します。唯一の制限は、2 つの論理的に同等の相対パスが一致しないものとして扱われる可能性があることですが、相対パスは Windows PATH ではまれであるため、これは小さな懸念事項です。

この問題を複雑にする追加の問題がいくつかあります。

9)特殊文字を含む PATH を扱う場合、通常の展開は信頼できません。
PATH 内で特殊文字を引用する必要はありませんが、引用することはできます。したがって、 PATH like は完全に有効ですが、とC:\THIS & THAT;"C:\& THE OTHER THING"の両方が失敗するため、単純な展開を使用して安全に展開することはできません。"%PATH%"%PATH%

10)パス区切り文字はパス名内でも有効です
A;は PATH 内のパスを区切るために使用されますが、パス内;で有効な文字にすることもできます。その場合、パスを引用符で囲む必要があります。これにより、解析の問題が発生します。

jeb は、 'Pretty print' windows %PATH% variable - how to split on ';' の問題 9 と 10 の両方を解決しました。CMD シェルで

そのため、修飾子とパス分類の手法を jeb の PATH パーサーの私のバリエーションと組み合わせて~s、特定のパスが 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 は、これがいかに信頼できないかを示しています。

もう 1 つの問題は、関数の最後にある ENDLOCAL バリアを越えて最終的な PATH 値を返す方法です。特に、遅延展開を有効または無効にして関数を呼び出すことができる場合です。!遅延拡張が有効になっている場合、エスケープされていない値はすべて破損します。

これらの問題は、jeb がここで発明した驚くべきセーフ リターン テクニックを使用して解決されます

@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
于 2011-11-08T05:54:11.633 に答える
40

しばらくバッチ ファイル プログラミングを行っていませんが、

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

文字列が見つからない場合は 0 を返し、見つかった場合は 1 以上を返します。

編集: Panos のおかげで、大文字と小文字を区別しないフラグが追加されました。

于 2008-09-26T19:19:31.737 に答える
23

何かがパスにあるかどうかを確認する別の方法は、そこにある場合に失敗しない無実の実行可能ファイルを実行し、結果を確認することです。例として、次のコード スニペットはmavenがパスにあるかどうかをチェックします。

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

したがって、 mvn --helpを実行して、出力を無視し (maven が存在する場合は実際にはヘルプを表示したくありません)( > NUL)、maven が見つからない場合はエラー メッセージを表示しません (2> NUL)。

于 2010-04-01T09:24:15.493 に答える
6

とを使用するforと、( Adam も指摘したdelimsように)任意の数のフィールドをキャプチャすることはできないため、代わりにループ手法を使用する必要があります。次のコマンド スクリプトは、環境変数の各パスを別の行に一覧表示します。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

これは、多くのプログラミング言語で見られる古典的なwhile …<em>wend 構造をシミュレートします。これを使用するとfindstr、次のようなものを使用して、後で特定のパスをフィルタリングして探すことができます。たとえば、上記のスクリプトをtidypath.cmdthen というファイルに保存した場合、次のように にパイプしてfindstr、標準のプログラム ディレクトリの下のパスを探します (大文字と小文字を区別しない一致を使用)。

> tidypath | findstr /i "%ProgramFiles%"
于 2008-10-01T14:04:07.193 に答える
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にすでに存在するかどうかを確認するために呼び出すことができます。

この実装では、単一のパス項目内にセミコロンや引用符が存在しないことを前提としていることに注意してください。

于 2011-04-06T21:10:29.877 に答える
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.

于 2008-09-26T22:36:27.037 に答える
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
于 2011-07-23T18:40:48.823 に答える
2

forループを使用して実装を行い、パスのすべての要素を反復処理するものに拡張しました。for ループを反復するたびに、パス全体 (%q および %r に保持されている) からパスの最初の要素 (%p) が削除されます。

@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
于 2008-09-27T00:26:10.097 に答える
2

上記の回答のいくつかを組み合わせてこれを考え出し、特定のパスエントリが 可能な限り簡潔に指定されたとおりに存在し、コマンドラインでジャンクエコーが発生しないようにしました

set myPath=<pathToEnsure | %1>
echo ;%PATH%; | find /C /I ";%myPath%;" >nul
if %ERRORLEVEL% NEQ 0 set PATH=%PATH%;%myPath%
于 2011-10-11T19:44:38.757 に答える
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
于 2008-09-26T22:44:26.613 に答える
1

一般的に、これはパスにexe/dllを配置することです。このファイルが他の場所に表示されない限り:

@echo off
where /q <put filename here>    
if %errorlevel% == 1 (
    setx PATH "%PATH%;<additional path stuff>"
) else (
    echo "already set path"
)
于 2012-06-13T15:37:09.630 に答える
1

まだ存在しない場合は、ディレクトリを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%)
于 2011-03-14T09:23:23.083 に答える
1

「addPath」スクリプトへのコメント。パスにスペースを指定すると、スローされます。

例: addPath "c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin" を呼び出す

yields:「ファイル」は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されません。

于 2011-12-14T09:51:33.503 に答える
1

ディレクトリが既に存在する場合、ディレクトリを検索パスに追加することは避けたいと述べています。ディレクトリをパスに永続的に保存するつもりですか、それともバッチファイルのために一時的に保存するつもりですか?

ディレクトリを PATH に永続的に追加 (または削除) する場合は、管理タスク用の Windows リソース キット ツールのパス マネージャー (pathman.exe) ユーティリティ ( http://support.microsoft.com/kb/927229 ) を参照してください。これにより、システム パスとユーザー パスの両方のコンポーネントを追加または削除でき、エントリの重複などの異常を処理できます。

バッチ ファイルのパスを一時的にのみ変更する必要がある場合は、パスの前に余分なパスを追加するだけで、パスのエントリが重複するためにパフォーマンスがわずかに低下するリスクがあります。

于 2008-10-01T13:43:24.983 に答える
1

別の方法として:

  1. 変数を検索しようとしているフォルダーPATHに、コンピューター上の他のファイルが決して持つとは思わないような珍しい名前で一時ファイルを作成します。

  2. 何らかの環境変数 (通常は ) で定義されたディレクトリ リストを参照して、ファイルの検索を実行できる標準のバッチ スクリプト構成を使用しますPATH

  3. 検索結果が問題のパスと一致するかどうかを確認し、結果を表示します。

  4. 一時ファイルを削除します。

これは次のようになります。

@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. 頭の中でグローバルに一意のファイル名を作成することは、あまり信頼できるとは言えません。そのような名前を生成すること自体は簡単な作業ではありません。

于 2011-04-06T22:59:52.650 に答える
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

errorlevel 1 は errorlevel >= 1 と同等であるため、vim71 コードではロジックが逆になります。errorlevel 0 は常に true と評価されるため、" not errorlevel 1" が使用されます。

環境設定をローカライズするために setlocal と endlocal を使用する場合、Postscript Checking は必要ないかもしれません。

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

endlocal の後、元のパスに戻ります。

于 2011-10-07T09:15:02.270 に答える
0

このルーチンは、path変数でpath \または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
)
于 2012-10-14T17:07:19.937 に答える