Як перевірити, чи існує виконуваний файл у% PATH% з командного файлу Windows?


90

Я шукаю простий спосіб перевірити, чи існує виконуваний файл у змінній середовища PATH з командного файлу Windows.

Використання зовнішніх інструментів, не передбачених ОС, не дозволяється. Мінімальною необхідною версією Windows є Windows XP.



15
@karlphilip: Безумовно, ні. Питання тут зовсім інше.
Joey

1
Ви повинні позначити прийняту відповідь.
Єб

Відповіді:


70
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файлах batch ( ) та в командному рядку відрізняється (оскільки в командних файлах є %0- %9), тому вам доведеться подвоїти значення %. У командному рядку це не потрібно, тому для змінних це просто %X.


1
Мені подобається ваш підхід, але було б ще краще, якби ви могли надати повну версію, ту, яка також використовує для цього PATHEXT.
сорін

4
Для XP вам потрібен сценарій циклу (або завантажте where.exe з RK). Vista і 7 постачається з where.exe. Я знаю, що ОП конкретно сказав ХР, але для нащадків найкраща відповідь - це завжди where myExecutable.
Райан Бемроуз

Райан: Так? Я не думаю, що зможу проаналізувати ваше речення.
Joey

2
Я початківець пакетного сценарію і не впевнений, що означає %% x. У моїй системі Windows 7 я спробував набрати: для %% X у (myExecutable.exe) do (встановити FOUND = %% ~ $ PATH: X), а потім натиснути повернутий. я отримав це у відповідь: C: \ Users \ James> для %% X у (cmd.exe) do (встановлено FOUND = %% ~ $ PATH: X) %% X було несподіваним у цей час.
simgineer

3
simengineer: Синтаксичний аналіз в командних файлах і в командному рядку відрізняється (оскільки в командних файлах є %0- %9), тому вам доведеться подвоїти його %там. У командному рядку це не потрібно, тому forзмінні просто %x.
Джої

82

Версії 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

Дуже приємно і просто! Дякую!
Pawel Cioch

18

Ось просте рішення, яке намагається запустити програму та обробляє будь-які помилки в подальшому .

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

Код помилки 9009 зазвичай означає, що файл не знайдено.

Єдиним недоліком є ​​те, що file.exeнасправді виконується, якщо його знаходять (що в деяких випадках не бажано).


24
єдиним недоліком є ​​те, що виконується "file.exe" (що в деяких випадках є небажаним)
eadmaster

6

Цього можна досягти за допомогою заміни параметрів.

%~$PATH:1

Це повертає повний шлях до імені виконуваного файлу в% 1, інакше - порожній рядок.

Це не працює з визначеними користувачем змінними. Отже, якщо ім'я виконуваного файлу не є параметром вашого сценарію, то вам потрібна підпрограма. Наприклад:

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

goto :eof

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

Див. Http://ss64.com/nt/syntax-args.html


1
Цікавий прийом з, setlocalале for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)це одне рядкове рішення, яке forвикористовується як обхідний шлях для %%~$PATH:Xтого, щоб уникнути callі %~$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%"=="" ....

3
Не буде працювати, оскільки forнедостатньо розумний для аналізу вмісту PATH. Наприклад, він буде пропускати каталоги з пробілами. І навіть якщо ви використовуєте for /fз delims=;ним, це не буде працювати належним чином, якщо каталог містить а ;і в лапках.
Joey

@Joey, а як щодо заміни рядків? Замінити ;з "; ": set quotedPath="%PATH:;="; "%".
XP1,

1
XP1: Ні, все ще марно. Спробуйте, додавши "C:\Folder with; semicolon, quoted"до шляху, і подивіться, що станеться. Принаймні тут він намагається розглядати кожне «слово» окремо, що, певним чином, гірше, ніж поведінка раніше.
Джої

0

Іноді працює це просте рішення, де ви перевіряєте, чи відповідає результат, що ви очікуєте. Перший рядок запускає команду і захоплює останній рядок стандартного виводу.

FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.

Але що, якщо системне середовище використовує іншу мову?
Beachwalker

0

Якщо ви шукаєте щось на зразок мене в папці автозавантаження, слід перейти до папки. Наприклад, я шукаю 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!
)

Але це здійснює пошук у повній PATH, якщо program.exeіснує, не тільки в одній папці
jeb

-1

Використовуйте команду: PowerShell Test-Path "exe, який ви шукаєте"

Це поверне True, якщо його теперішнє, інакше False.


Це не спрацює. Test-Pathперевіряє лише вказаний шлях, тобто Test-Path nuget.exeповерне true, лише якщо nuget.exeзнаходиться в поточному каталозі. Якщо nuget.exe відсутній у поточному каталозі, він поверне значення false, навіть якщо він знаходиться в каталозі, зазначеному у змінній PATH. У PowerShell Get-Commandможе працювати краще ( stackoverflow.com/questions/11242368/… ), але враховуйте , що для PowerShell поточний каталог не в шляху.
Рональд Зарітс

1
Як зазначив @RonaldZarits, для повної підтримки PowerShell ви можете використовувати Get-Command із двома варіантами. Спочатку вкажіть поточне місце розташування каталогу, а потім просто ім’я exe. (Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $nullповерне true, якщо знайдено локально або в шляху.
Джон Сі

-1

Для тих, хто шукає варіант PowerShell. Ви можете використовувати Get-Commandкомандлет, передаючи два елементи. Спочатку вкажіть поточне місце розташування каталогу із .\префіксом, а потім просто ім’я exe.

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

Це поверне істину, якщо знайдено локально або в загальносистемних шляхах.


Немає нічого кращого, ніж голоси проти та запуск користувачів. Якщо ви не згодні і збираєтесь піти настільки далеко, як проголосування, тоді також додайте коментар, щоб пояснити, чому ви не згодні з тим, що це не є хорошим підходом для отримання бажаних результатів.
Джон С
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.