WindowsバッチファイルのPATH環境変数に実行可能ファイルが存在するかどうかをテストする簡単な方法を探しています。
OSが提供していない外部ツールの使用は禁止されています。最小限必要なWindowsバージョンはWindows XPです。
回答:
for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)
if defined FOUND ...
異なる拡張機能でこれが必要な場合は、次のように繰り返しPATHEXT
ます。
set FOUND=
for %%e in (%PATHEXT%) do (
for %%X in (myExecutable%%e) do (
if not defined FOUND (
set FOUND=%%~$PATH:X
)
)
)
それwhere
はレガシーWindowsバージョンにもすでに存在している可能性がありますが、私はそれにアクセスすることができないため、わかりません。私のマシンでは以下も機能します:
where myExecutable
見つからなかった場合は、ゼロ以外の終了コードで戻ります。ただし、バッチではNUL
、出力をにリダイレクトすることもできます。
心に留めて
バッチ(.bat
)ファイルとコマンドラインでの解析は異なります(バッチファイルには%0
– %9
があるため)。そこで、ファイルを2倍にする%
必要があります。コマンドラインではこれは必要ないので、変数の場合はです%X
。
where myExecutable
。
%0
– %9
があるため)%
。そこで、2倍にする必要があります。コマンドラインではこれは必要ないので、for
変数はただ%x
です。
Windows Vista以降のバージョンにwhere.exe
は、パス内のプログラムを検索するというプログラムが付属しています。それはこのように動作します:
D:\>where notepad
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe
D:\>where where
C:\Windows\System32\where.exe
バッチファイルで使用するには、/q
スイッチを使用します。このスイッチは、設定ERRORLEVEL
を行い、出力を生成しません。
where /q myapplication
IF ERRORLEVEL 1 (
ECHO The application is missing. Ensure it is installed and placed in your PATH.
EXIT /B
) ELSE (
ECHO Application exists. Let's go!
)
または、メッセージを出力してアプリを終了する簡単な(ただし、読みにくい)省略バージョン:
where /q myapplication || ECHO Cound not find app. && EXIT /B
これは、アプリケーションの実行を試み、後でエラーを処理する簡単なソリューションです。
file.exe /? 2> NUL
IF NOT %ERRORLEVEL%==9009 ECHO file.exe exists in path
エラーコード9009は通常、ファイルが見つからないことを意味します。
唯一の欠点は、file.exe
見つかった場合に実際に実行されることです(場合によっては望ましくないことがあります)。
これは、パラメーターの置換によって実現できます。
%~$PATH:1
これは、%1の実行可能ファイル名の完全パスを返します。それ以外の場合は空の文字列を返します。
これは、ユーザー定義変数では機能しません。したがって、実行可能ファイル名がスクリプトのパラメータでない場合は、サブルーチンが必要です。例えば:
call :s_which app.exe
if not "%_path%" == "" (
"%_path%"
)
goto :eof
:s_which
setlocal
endlocal & set _path=%~$PATH:1
goto :eof
setlocal
が、for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)
と1行のソリューションであるfor
ため、回避策として使用し%%~$PATH:X
ないようにするために、call
と%~$PATH:1
。
@echo off
set found=
set prog=cmd.exe
for %%i in (%path%) do if exist %%i\%prog% set found=%%i
echo "%found%"
if "%found%"=="" ....
for
の内容を解析するほどスマートではないため、機能しませんPATH
。たとえば、スペースのあるディレクトリは見逃されます。そしてfor /f
、delims=;
それを使用しても、ディレクトリに;
とが含まれている場合は正しく動作しません。
;
と"; "
:set quotedPath="%PATH:;="; "%"
。
"C:\Folder with; semicolon, quoted"
パスに追加して試して、何が起こるかを確認してください。少なくともここでは、すべての「単語」を個別に処理しようとしますが、これはある意味で以前の動作よりも悪いことです。
時々、この単純な解決策が機能し、出力が期待と一致するかどうかを確認します。最初の行はコマンドを実行し、標準出力の最後の行を取得します。
FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.
起動フォルダで私のようなものを検索している場合は、フォルダに移動する必要があります。たとえば、スタートアップフォルダーでexeを検索し、このコードを次のように使用します
@echo off
cd C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
where /q program.exe
IF ERRORLEVEL 1 (
echo F | xcopy /Y /S /I /E "\\programsetup\programsetup.exe"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\program.exe"
) ELSE (
ECHO Application exists. Let's go!
)
program.exe
1つのフォルダだけでなく、存在する場合は完全なパスを検索します
コマンドを使用します:powershell Test-Path "あなたが探しているexe"
存在する場合はTrueを返し、それ以外の場合はFalseを返します。
Test-Path
指定されたパスのみをチェックします。つまり、が現在のディレクトリにあるTest-Path nuget.exe
場合にのみtrueを返しますnuget.exe
。nuget.exeが現在のディレクトリにない場合、PATH変数にリストされているディレクトリにある場合でも、falseを返します。PowerShellではGet-Command
うまくいくかもしれませんが(stackoverflow.com/questions/11242368/…)、PowerShellでは現在のディレクトリがパスに含まれていないことを考慮してください。
(Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $null
ローカルまたはパスで見つかった場合はtrueを返します。
PowerShellオプションをお探しの方に。Get-Command
2つの項目を渡すコマンドレットを使用できます。最初に現在のディレクトリの場所を.\
プレフィックス付きで指定し、次にexe名のみを指定します。
(Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $null
ローカルまたはシステム全体のパスで見つかった場合、trueを返します。