Bagaimana cara menguji apakah ada executable di% PATH% dari file batch windows?

90

Saya mencari cara sederhana untuk menguji apakah ada yang dapat dieksekusi di variabel lingkungan PATH dari file batch Windows.

Penggunaan alat eksternal yang tidak disediakan oleh OS tidak diperbolehkan. Versi Windows minimal yang dibutuhkan adalah Windows XP.

sorin
sumber
1
kemungkinan duplikat Bagaimana memeriksa apakah file ada di batch DOS
karlphillip
15
@ Karlphilip: Jelas tidak. Pertanyaannya di sini sangat berbeda.
Joey
1
Anda harus menandai jawaban yang diterima.
Jeb

Jawaban:

70
for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)
if defined FOUND ...

Jika Anda memerlukan ini untuk ekstensi yang berbeda, cukup ulangi PATHEXT:

set FOUND=
for %%e in (%PATHEXT%) do (
  for %%X in (myExecutable%%e) do (
    if not defined FOUND (
      set FOUND=%%~$PATH:X
    )
  )
)

Mungkin itu wherejuga sudah ada di versi Windows lama, tetapi saya tidak memiliki akses ke salah satunya, jadi saya tidak tahu. Di mesin saya hal berikut juga berfungsi:

where myExecutable

dan kembali dengan kode keluar bukan nol jika tidak dapat ditemukan. Namun, dalam batch, Anda mungkin juga ingin mengalihkan output ke NUL.

Mengingat

Parsing dalam .batfile batch ( ) dan pada baris perintah berbeda (karena file batch memiliki %0- %9), jadi Anda harus menggandakannya %. Pada baris perintah ini tidak perlu, jadi untuk variabel hanya %X.

Joey
sumber
1
Saya suka pendekatan Anda tetapi akan lebih baik jika Anda dapat memberikan versi lengkap, yang juga menggunakan PATHEXT untuk ini.
sorin
4
Untuk XP Anda memerlukan skrip loop (atau unduh where.exe dari RK). Vista dan 7 dikirimkan dengan where.exe. Saya tahu OP secara khusus mengatakan XP, tetapi untuk anak cucu, jawaban terbaik selalu digunakan where myExecutable.
Ryan Bemrose
Ryan: Hah? Saya tidak berpikir saya bisa mengurai kalimat Anda.
Joey
2
Saya seorang pemula skrip batch dan saya tidak yakin apa artinya %% x. Pada sistem Windows 7 saya, saya mencoba mengetik: untuk %% X di (myExecutable.exe) lakukan (setel DITEMUKAN = %% ~ $ PATH: X) dan kemudian tekan kembali. saya mendapat ini sebagai tanggapan: C: \ Users \ James> untuk %% X di (cmd.exe) lakukan (set FOUND = %% ~ $ PATH: X) %% X tidak terduga saat ini.
simgineer
3
simengineer: Parsing dalam file batch dan pada baris perintah berbeda (karena file batch memiliki %0- %9), jadi Anda harus menggandakannya %. Pada baris perintah ini tidak perlu, jadi forvariabelnya adil %x.
Joey
82

Windows Vista dan versi yang lebih baru dikirimkan dengan program yang disebut where.exeyang mencari program di jalur. Ini bekerja seperti ini:

D:\>where notepad
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe

D:\>where where
C:\Windows\System32\where.exe

Untuk digunakan dalam file batch Anda dapat menggunakan /qsakelar, yang hanya mengatur ERRORLEVELdan tidak menghasilkan output apa pun.

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

Atau versi singkat sederhana (tapi kurang terbaca) yang mencetak pesan dan keluar dari aplikasi Anda:

where /q myapplication || ECHO Cound not find app. && EXIT /B
Ryan Bemrose
sumber
Sangat bagus dan sederhana! Terima kasih!
Pawel Cioch
18

Berikut adalah solusi sederhana yang mencoba menjalankan aplikasi dan menangani kesalahan apa pun sesudahnya .

file.exe /?  2> NUL
IF NOT %ERRORLEVEL%==9009 ECHO file.exe exists in path

Kode kesalahan 9009 biasanya berarti file tidak ditemukan.

Satu-satunya downside adalah yang file.exebenar-benar dieksekusi jika ditemukan (yang dalam beberapa kasus tidak dapat diterima).

eadmaster
sumber
24
satu-satunya downside adalah bahwa "file.exe" dijalankan (yang dalam beberapa kasus tidak diinginkan)
eadmaster
6

Ini dapat dilakukan melalui substitusi parameter.

%~$PATH:1

Ini mengembalikan jalur lengkap dari nama file yang dapat dieksekusi di% 1, jika tidak string kosong.

Ini tidak berfungsi dengan variabel buatan pengguna. Jadi jika nama file yang dapat dieksekusi bukan merupakan parameter untuk skrip Anda, maka Anda memerlukan subrutin. Sebagai contoh:

call :s_which app.exe
if not "%_path%" == "" (
  "%_path%"
)

goto :eof

:s_which
  setlocal
  endlocal & set _path=%~$PATH:1
  goto :eof

Lihat http://ss64.com/nt/syntax-args.html

Chris Noe
sumber
1
Trik yang menarik dengan setlocaltetapi for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)merupakan salah satu solusi sejalan dengan fordigunakan sebagai solusi untuk %%~$PATH:Xuntuk menghindari calldan %~$PATH:1.
gavenkoa
0
@echo off
set found=
set prog=cmd.exe
for %%i in (%path%) do if exist %%i\%prog% set found=%%i
echo "%found%"
if "%found%"=="" ....
PabloG
sumber
3
Tidak akan berfungsi karena fortidak cukup pintar untuk mengurai konten PATH. Ini akan kehilangan direktori dengan spasi, misalnya. Dan bahkan ketika Anda menggunakan for /fdengan delims=;itu tidak akan bekerja dengan benar jika direktori berisi ;dan dikutip.
Joey
@ Joey, bagaimana dengan penggantian string? Ganti ;dengan "; ": set quotedPath="%PATH:;="; "%".
XP1
1
XP1: Tidak, masih tidak berguna. Cobalah dengan menambahkan "C:\Folder with; semicolon, quoted"ke jalur dan lihat apa yang terjadi. Setidaknya di sini ia mencoba memperlakukan setiap »kata« secara terpisah yang, di satu sisi, lebih buruk daripada perilaku sebelumnya.
Joey
0

Terkadang solusi sederhana ini berfungsi, di mana Anda memeriksa untuk melihat apakah hasilnya cocok dengan yang Anda harapkan. Baris pertama menjalankan perintah dan mengambil baris terakhir dari keluaran standar.

FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.
bdombro
sumber
Tetapi bagaimana jika lingkungan sistem menggunakan bahasa lain?
Beachwalker
0

Jika Anda mencari sesuatu seperti saya di folder startup, harus pergi folder. Misalnya saya mencari exe di folder startup dan saya menggunakan kode ini seperti

@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!
)
Zafer ATLI
sumber
Tapi ini mencari di PATH lengkap jika program.exeada, tidak hanya dalam satu folder
jeb
-1

Gunakan perintah: PowerShell Test-Path "exe yang Anda cari"

Ini akan mengembalikan True jika ada, jika tidak Salah.

akkidukes
sumber
Ini tidak akan berhasil. Test-Pathhanya memeriksa jalur yang ditentukan, yaitu Test-Path nuget.exeakan mengembalikan nilai true hanya jika nuget.exeada di direktori saat ini. Jika nuget.exe tidak ada di direktori saat ini, ia akan mengembalikan false, meskipun ada di direktori yang terdaftar di variabel PATH. Di PowerShell Get-Commandmungkin bekerja lebih baik ( stackoverflow.com/questions/11242368/… ), tetapi pertimbangkan bahwa untuk PowerShell direktori saat ini tidak berada di jalur.
Ronald Zarīts
1
Seperti yang ditunjukkan @RonaldZarits, untuk dukungan PowerShell penuh, Anda dapat menggunakan Get-Command dengan dua opsi. Pertama berikan lokasi dir saat ini, lalu berikan nama exe saja. (Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $nullakan mengembalikan nilai true jika ditemukan lokal atau di jalur.
John C
-1

Bagi mereka yang mencari opsi PowerShell. Anda dapat menggunakan Get-Commandcmdlet dengan melewatkan dua item. Pertama berikan lokasi dir saat ini dengan .\awalan, lalu berikan nama exe saja.

(Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $null

Itu akan mengembalikan nilai true jika ditemukan lokal atau di jalur lebar sistem.

John C
sumber
Tidak ada yang lebih baik dari downvote dan jalankan pengguna. Jika Anda tidak setuju dan akan melakukan downvoting, tambahkan juga komentar untuk memberikan alasan mengapa Anda tidak setuju bahwa ini bukan pendekatan yang baik untuk mendapatkan hasil yang diinginkan.
John C