Jak sprawdzić, czy plik wykonywalny istnieje w% PATH% z pliku wsadowego systemu Windows?

90

Szukam prostego sposobu na sprawdzenie, czy plik wykonywalny istnieje w zmiennej środowiskowej PATH z pliku wsadowego systemu Windows.

Korzystanie z narzędzi zewnętrznych, które nie są dostarczane przez system operacyjny, jest niedozwolone. Minimalna wymagana wersja systemu Windows to Windows XP.

sorin
źródło
1
możliwy duplikat Jak sprawdzić, czy plik istnieje w partii DOS
karlphillip
15
@karlphilip: Zdecydowanie nie. Tutaj pytanie jest zupełnie inne.
Joey
1
Powinieneś zaznaczyć zaakceptowaną odpowiedź.
Jeb

Odpowiedzi:

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

Jeśli potrzebujesz tego dla różnych rozszerzeń, po prostu powtórz PATHEXT:

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

Możliwe, że whereistnieje już w starszych wersjach systemu Windows, ale nie mam dostępu do jednej, więc nie mogę powiedzieć. Na moim komputerze działa również:

where myExecutable

i zwraca z niezerowym kodem zakończenia, jeśli nie można go znaleźć. Jednak w przypadku wsadu prawdopodobnie chcesz również przekierować dane wyjściowe do NUL.

Pamiętać

Parsowanie w .batplikach batch ( ) iw wierszu poleceń różni się (ponieważ pliki wsadowe mają %0- %9), więc musisz podwoić to %. W linii poleceń nie jest to konieczne, więc dla zmiennych są po prostu %X.

Joey
źródło
1
Podoba mi się twoje podejście, ale byłoby jeszcze lepiej, gdybyś mógł dostarczyć pełną wersję, która również używa do tego PATHEXT.
sorin
4
W przypadku XP potrzebujesz skryptu pętli (lub pobierz where.exe z RK). Vista i 7 są dostarczane z where.exe. Wiem, że OP konkretnie powiedział XP, ale dla potomnych najlepszą odpowiedzią jest zawsze użycie where myExecutable.
Ryan Bemrose
Ryan: Hę? Nie sądzę, żebym mógł przeanalizować twoje zdanie.
Joey,
2
Jestem początkującym użytkownikiem skryptów wsadowych i nie jestem pewien, co oznacza %% x. W moim systemie Windows 7 próbowałem wpisać: dla %% X w (myExecutable.exe) wykonaj (ustaw FOUND = %% ~ $ PATH: X), a następnie naciśnij klawisz zwrócony. Otrzymałem to w odpowiedzi: C: \ Users \ James> dla %% X w (cmd.exe) do (ustaw FOUND = %% ~ $ PATH: X) %% X było w tym czasie nieoczekiwane.
simgineer
3
simengineer: Parsowanie w plikach wsadowych i w wierszu poleceń różni się (ponieważ pliki wsadowe mają %0- %9), więc musisz %tam podwoić . W linii poleceń nie jest to konieczne, więc forzmienne są po prostu %x.
Joey,
82

System Windows Vista i nowsze wersje są dostarczane z programem o nazwie, where.exektóry wyszukuje programy w ścieżce. Działa to tak:

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

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

Do użycia w pliku wsadowym możesz użyć /qprzełącznika, który po prostu ustawia ERRORLEVELi nie generuje żadnych wyników.

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

Lub prostą (ale mniej czytelną) skróconą wersję, która drukuje wiadomość i zamyka aplikację:

where /q myapplication || ECHO Cound not find app. && EXIT /B
Ryan Bemrose
źródło
Bardzo ładne i proste! Dzięki!
Paweł Cioch
18

Oto proste rozwiązanie, które próbuje uruchomić aplikację i obsługuje później każdy błąd .

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

Kod błędu 9009 zwykle oznacza, że ​​nie znaleziono pliku.

Jedynym minusem jest to, że file.exejest faktycznie wykonywany, jeśli zostanie znaleziony (co w niektórych przypadkach nie jest pożądane).

eadmaster
źródło
24
jedynym minusem jest to, że uruchamiany jest
plik
6

Można to osiągnąć poprzez podstawianie parametrów.

%~$PATH:1

Zwraca pełną ścieżkę do nazwy pliku wykonywalnego w% 1, w przeciwnym razie pusty ciąg.

Nie działa to ze zmiennymi zdefiniowanymi przez użytkownika. Więc jeśli nazwa pliku wykonywalnego nie jest parametrem twojego skryptu, potrzebujesz podprogramu. Na przykład:

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

goto :eof

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

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

Chris Noe
źródło
1
Ciekawa sztuczka z rozwiązaniem jednokierunkowym, setlocalktóra for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)jest forużywana jako obejście %%~$PATH:Xw celu uniknięcia calli %~$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
źródło
3
Nie będzie działać, ponieważ fornie jest wystarczająco inteligentny, aby przeanalizować zawartość PATH. Pominie na przykład katalogi ze spacjami. I nawet jeśli używasz for /fz delims=;nim, nie będzie działać poprawnie, jeśli katalog zawiera ;i jest cytowany.
Joey
@Joey, co powiesz na zamianę ciągu? Wymienić ;z "; ": set quotedPath="%PATH:;="; "%".
XP1
1
XP1: Nie, nadal bezużyteczne. Spróbuj, dołączając "C:\Folder with; semicolon, quoted"do ścieżki i zobacz, co się stanie. Przynajmniej tutaj próbuje traktować każde »słowo« osobno, co w pewnym sensie jest gorsze niż wcześniejsze zachowanie.
Joey,
0

Czasami działa to proste rozwiązanie, w którym sprawdzasz, czy dane wyjściowe są zgodne z oczekiwaniami. Pierwsza linia uruchamia polecenie i przechwytuje ostatni wiersz standardowego wyjścia.

FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.
bdombro
źródło
Ale co, jeśli środowisko systemowe używa innego języka?
Beachwalker
0

Jeśli szukasz czegoś takiego jak ja w folderze startowym, powinieneś przejść do folderu. Na przykład wyszukuję exe w folderze startowym i używam tego kodu jak

@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
źródło
Ale to wyszukuje w pełnej PATH, jeśli program.exeistnieje, nie tylko w jednym folderze
jeb
-1

Użyj polecenia: powershell Test-Path „exe, którego szukasz”

Zwróci True, jeśli jest obecny, w przeciwnym razie False.

akkidukes
źródło
To nie zadziała. Test-Pathsprawdza tylko określoną ścieżkę, tj. Test-Path nuget.exezwróci wartość true tylko wtedy, gdy nuget.exeznajduje się w bieżącym katalogu. Jeśli nuget.exe nie znajduje się w bieżącym katalogu, zwróci wartość false, nawet jeśli znajduje się w katalogu wymienionym w zmiennej PATH. W PowerShell Get-Commandmoże działać lepiej ( stackoverflow.com/questions/11242368/… ), ale weź pod uwagę, że dla PowerShell bieżący katalog nie znajduje się w ścieżce.
Ronald Zarīts
1
Jak zauważył @RonaldZarits, aby uzyskać pełną obsługę PowerShell, możesz użyć polecenia Get-Command z dwiema opcjami. Najpierw podaj aktualną lokalizację katalogu, a następnie podaj tylko nazwę exe.(Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $nullzwróci wartość true, jeśli zostanie znaleziony lokalnie lub w ścieżce.
John C
-1

Dla tych, którzy szukają opcji PowerShell. Możesz użyć polecenia Get-Commandcmdlet przekazującego dwa elementy. Najpierw podaj aktualną lokalizację katalogu z .\prefiksem, a następnie podaj tylko nazwę exe.

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

To zwróci prawdę, jeśli zostanie znalezione lokalnie lub w ścieżkach całego systemu.

John C.
źródło
Nie ma nic lepszego niż głosowanie przeciw i uruchamianie użytkowników. Jeśli się nie zgadzasz i zamierzasz posunąć się nawet do głosowania w dół, dodaj również komentarz, aby podać powód, dla którego nie zgadzasz się, że nie jest to dobre podejście do uzyskania pożądanych rezultatów.
John C