Come verificare se esiste un eseguibile in% PATH% da un file batch di Windows?


89

Sto cercando un modo semplice per verificare se esiste un eseguibile nella variabile di ambiente PATH da un file batch di Windows.

L'utilizzo di strumenti esterni non forniti dal sistema operativo non è consentito. La versione minima di Windows richiesta è Windows XP.



15
@karlphilip: decisamente no. La domanda qui è molto diversa.
Joey

1
Dovresti contrassegnare una risposta accettata.
Jeb

Risposte:


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

Se ne hai bisogno per estensioni diverse, ripeti semplicemente PATHEXT:

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

Potrebbe essere che whereesista già sulle versioni precedenti di Windows, ma non ho accesso a uno, quindi non posso dirlo. Sulla mia macchina funziona anche quanto segue:

where myExecutable

e restituisce un codice di uscita diverso da zero se non è stato trovato. In un batch probabilmente vuoi anche reindirizzare l'output NUL, però.

Tieni a mente

L'analisi nei .batfile batch ( ) e sulla riga di comando è diversa (perché i file batch hanno %0- %9), quindi devi raddoppiare il valore %there. Sulla riga di comando questo non è necessario, quindi per le variabili lo sono solo %X.


1
Mi piace il tuo approccio ma sarebbe ancora meglio se tu potessi fornire la versione completa, quella che usa anche PATHEXT per questo.
sorin

4
Per XP è necessario lo script loop (o scaricare where.exe da RK). Vista e 7 vengono forniti con where.exe. So che l'OP diceva specificamente XP, ma per i posteri la risposta migliore è sempre quella di usare where myExecutable.
Ryan Bemrose

Ryan: eh? Non credo di poter analizzare la tua frase.
Joey

2
Sono un principiante nello scripting batch e non sono sicuro di cosa significhi %% x. Sul mio sistema Windows 7 ho provato a digitare: for %% X in (myExecutable.exe) do (set FOUND = %% ~ $ PATH: X) e poi premi restituito. Ho ottenuto questo in risposta: C: \ Users \ James> per %% X in (cmd.exe) do (set FOUND = %% ~ $ PATH: X) %% X era inaspettato in questo momento.
Simgineer

3
simengineer: L'analisi nei file batch e sulla riga di comando è diversa (perché i file batch hanno %0- %9), quindi devi raddoppiare il valore %there. Sulla riga di comando questo non è necessario, quindi le forvariabili sono solo %x.
Joey

79

Windows Vista e le versioni successive vengono fornite con un programma chiamato where.exeche cerca i programmi nel percorso. Funziona così:

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

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

Per l'utilizzo in un file batch è possibile utilizzare l' /qopzione, che si limita a impostare ERRORLEVELe non produce alcun output.

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

O una versione abbreviata semplice (ma meno leggibile) che stampa il messaggio ed esce dalla tua app:

where /q myapplication || ECHO Cound not find app. && EXIT /B

Molto carino e semplice! Grazie!
Pawel Cioch

18

Ecco una semplice soluzione che tenta di eseguire l'applicazione e gestisce eventuali errori in seguito .

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

Il codice di errore 9009 di solito indica che il file non è stato trovato.

L'unico svantaggio è che file.exeviene effettivamente eseguito se trovato (cosa che in alcuni casi non è desiderabile).


24
l'unico svantaggio è che "file.exe" viene eseguito (che in alcuni casi è indesiderato)
eadmaster

6

Ciò può essere ottenuto tramite la sostituzione dei parametri.

%~$PATH:1

Questo restituisce il percorso completo del nome del file eseguibile in% 1, altrimenti una stringa vuota.

Questo non funziona con le variabili definite dall'utente. Quindi, se il nome del file eseguibile non è un parametro del tuo script, allora hai bisogno di una subroutine. Per esempio:

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

goto :eof

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

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


1
Trucco interessante con setlocalma for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)è una soluzione di linea con forusato come soluzione alternativa per %%~$PATH:Xevitare calle %~$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
Non funzionerà perché fornon è abbastanza intelligente per analizzare i contenuti di PATH. Mancheranno directory con spazi, ad esempio. E anche quando si usa for /fcon delims=;esso non funzionerà correttamente se una directory contiene un ;e è quotata.
Joey

@ Joey, che ne dici della sostituzione delle stringhe? Sostituire ;con "; ": set quotedPath="%PATH:;="; "%".
XP1

1
XP1: No, ancora inutile. Provalo aggiungendo "C:\Folder with; semicolon, quoted"al percorso e guarda cosa succede. Almeno qui cerca di trattare ogni »parola« separatamente che, in un certo senso, è peggiore del comportamento precedente.
Joey

0

A volte questa semplice soluzione funziona, in cui controlli per vedere se l'output corrisponde a ciò che ti aspetti. La prima riga esegue il comando e acquisisce l'ultima riga dello standard output.

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

Ma cosa succede se l'ambiente di sistema utilizza un'altra lingua?
Beachwalker

0

Se stai cercando qualcosa come me nella cartella di avvio, dovrebbe andare nella cartella. Ad esempio cerco exe nella cartella di avvio e utilizzo questo codice come

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

Ma questo cerca nel PERCORSO completo se program.exeesiste, non solo in una cartella
jeb

-1

Usa il comando: powershell Test-Path "exe che stai cercando"

Restituirà True se è presente, altrimenti False.


Questo non funzionerà. Test-Pathcontrolla solo il percorso specificato, ovvero Test-Path nuget.exerestituirà true solo se si nuget.exetrova nella directory corrente. Se nuget.exe non si trova nella directory corrente, restituirà false, anche se si trova in una directory elencata nella variabile PATH. In PowerShell Get-Commandpotrebbe funzionare meglio ( stackoverflow.com/questions/11242368/… ), ma tieni presente che per PowerShell la directory corrente non è nel percorso.
Ronald Zarīts,

1
Come ha sottolineato @RonaldZarits, per il supporto completo di PowerShell, puoi utilizzare Get-Command con due opzioni. Per prima cosa dare la posizione della directory corrente, quindi dare solo il nome dell'exe. (Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $nullrestituirà true se trovato locale o nel percorso.
John C

-1

Per chi cerca un'opzione PowerShell. È possibile utilizzare il Get-Commandcmdlet passando due elementi. Per prima cosa dare la posizione della .\directory corrente con il prefisso, quindi dare solo il nome exe.

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

Ciò restituirà vero se trovato locale o in percorsi a livello di sistema.


Niente di meglio che downvote ed eseguire utenti. Se non sei d'accordo e ti spingi fino al voto negativo, aggiungi anche un commento per spiegare il motivo per cui non sei d'accordo sul fatto che questo non è un buon approccio per ottenere i risultati desiderati.
John C
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.