Comment tester si un exécutable existe dans le% PATH% à partir d'un fichier batch Windows?

89

Je recherche un moyen simple de tester si un exécutable existe dans la variable d'environnement PATH à partir d'un fichier batch Windows.

L'utilisation d'outils externes non fournis par le système d'exploitation n'est pas autorisée. La version minimale de Windows requise est Windows XP.

Sorin
la source
1
duplication possible de Comment vérifier si un fichier existe dans un lot DOS
karlphillip
15
@karlphilip: Certainement pas. La question ici est bien différente.
Joey le
1
Vous devez marquer une réponse acceptée.
Jeb

Réponses:

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

Si vous en avez besoin pour différentes extensions, répétez simplement PATHEXT:

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

Peut-être que cela whereexiste déjà sur les versions héritées de Windows, mais je n'y ai pas accès, donc je ne peux pas le dire. Sur ma machine, ce qui suit fonctionne également:

where myExecutable

et retourne avec un code de sortie différent de zéro s'il est introuvable. Dans un lot, vous souhaitez probablement également rediriger la sortie vers NUL.

Gardez à l'esprit

L'analyse dans les .batfichiers batch ( ) et sur la ligne de commande diffère (car les fichiers batch ont %0- %9), vous devez donc doubler le %. Sur la ligne de commande, ce n'est pas nécessaire, donc les variables sont justes %X.

Joey
la source
1
J'aime votre approche mais ce serait encore mieux si vous pouviez fournir la version complète, celle qui utilise également PATHEXT pour cela.
sorin le
4
Pour XP, vous avez besoin du script de boucle (ou téléchargez where.exe à partir du RK). Vista et 7 sont livrés avec where.exe. Je sais que l'OP a spécifiquement dit XP, mais pour la postérité, la meilleure réponse est toujours d'utiliser where myExecutable.
Ryan Bemrose
Ryan: Hein? Je ne pense pas pouvoir analyser votre phrase.
Joey
2
Je suis un débutant en scripts batch et je ne suis pas sûr de ce que signifie %% x. Sur mon système Windows 7, j'ai essayé de taper: pour %% X dans (myExecutable.exe), faites (définissez FOUND = %% ~ $ PATH: X), puis appuyez sur renvoyé. J'ai eu ceci en réponse: C: \ Users \ James> pour %% X dans (cmd.exe) do (set FOUND = %% ~ $ PATH: X) %% X était inattendu à ce moment.
simgineer
3
simengineer: L'analyse dans les fichiers batch et sur la ligne de commande diffère (car les fichiers batch ont %0- %9), vous devez donc doubler le %. Sur la ligne de commande, ce n'est pas nécessaire, donc les forvariables sont justes %x.
Joey
79

Windows Vista et les versions ultérieures sont fournis avec un programme appelé where.exequi recherche les programmes dans le chemin. Cela fonctionne comme ceci:

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

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

Pour une utilisation dans un fichier de commandes, vous pouvez utiliser le /qcommutateur, qui définit simplement ERRORLEVELet ne produit aucune sortie.

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

Ou une version abrégée simple (mais moins lisible) qui imprime le message et quitte votre application:

where /q myapplication || ECHO Cound not find app. && EXIT /B
Ryan Bemrose
la source
Très joli et simple! Merci!
Pawel Cioch
18

Voici une solution simple qui tente d'exécuter l'application et gère toute erreur par la suite .

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

Le code d'erreur 9009 signifie généralement que le fichier est introuvable.

Le seul inconvénient est qu'il file.exeest effectivement exécuté s'il est trouvé (ce qui dans certains cas n'est pas souhaitable).

eadmaster
la source
24
le seul inconvénient est que "file.exe" est exécuté (ce qui dans certains cas est indésirable)
eadmaster
6

Cela peut être accompli via la substitution de paramètres.

%~$PATH:1

Cela renvoie le chemin complet du nom de fichier exécutable dans% 1, sinon une chaîne vide.

Cela ne fonctionne pas avec les variables définies par l'utilisateur. Donc, si le nom de fichier exécutable n'est pas un paramètre de votre script, vous avez besoin d'un sous-programme. Par exemple:

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

goto :eof

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

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

Chris Noe
la source
1
Astuce intéressante avec setlocalmais for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)est une solution en une ligne avec forutilisé comme solution de contournement pour %%~$PATH:Xéviter callet %~$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
la source
3
Ne fonctionnera pas car ce forn'est pas assez intelligent pour analyser le contenu de PATH. Il manquera des répertoires avec des espaces, par exemple. Et même lorsque vous utilisez for /favec, delims=;cela ne fonctionnera pas correctement si un répertoire contient un ;et est cité.
Joey
@Joey, qu'en est-il du remplacement de chaîne? Remplacer ;par "; ": set quotedPath="%PATH:;="; "%".
XP1
1
XP1: Non, toujours inutile. Essayez-le en ajoutant "C:\Folder with; semicolon, quoted"au chemin et voyez ce qui se passe. Au moins ici, il essaie de traiter chaque «mot» séparément, ce qui est en quelque sorte pire que le comportement antérieur.
Joey
0

Parfois, cette solution simple fonctionne, où vous vérifiez si la sortie correspond à ce que vous attendez. La première ligne exécute la commande et saisit la dernière ligne de sortie standard.

FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.
bdombro
la source
Mais que faire si l'environnement système utilise une autre langue?
Beachwalker
0

Si vous recherchez quelque chose comme moi dans le dossier de démarrage, vous devriez aller dans le dossier. Par exemple, je recherche exe sur le dossier de démarrage et j'utilise ce code comme

@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
la source
Mais cela recherche dans le PATH complet si le program.exeexiste, pas seulement dans un dossier
jeb
-1

Utilisez la commande: powershell Test-Path "exe que vous recherchez"

Il retournera True s'il est présent, sinon False.

akkidukes
la source
Cela ne fonctionnera pas. Test-Pathne vérifie que le chemin spécifié, c'est-à-dire Test-Path nuget.exene retournera vrai que s'il se nuget.exetrouve dans le répertoire courant. Si nuget.exe ne se trouve pas dans le répertoire en cours, il retournera false, même s'il se trouve dans un répertoire répertorié dans la variable PATH. Dans PowerShell Get-Commandpeut fonctionner mieux ( stackoverflow.com/questions/11242368/… ), mais prenez en compte que pour PowerShell, le répertoire actuel n'est pas dans le chemin.
Ronald Zarīts
1
Comme @RonaldZarits l'a souligné, pour une prise en charge complète de PowerShell, vous pouvez utiliser Get-Command avec deux options. Donnez d'abord l'emplacement actuel du répertoire, puis donnez simplement le nom de l'exe. (Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $nullretournera true s'il est trouvé local ou dans le chemin.
John C
-1

Pour ceux qui recherchent une option PowerShell. Vous pouvez utiliser l' Get-Commandapplet de commande en passant deux éléments. Donnez d'abord l'emplacement actuel du répertoire avec le .\préfixe, puis donnez simplement le nom de l'exe.

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

Cela retournera vrai si trouvé local ou dans des chemins d'accès à l'échelle du système.

Jean C
la source
Rien de mieux que de voter contre et d'exécuter des utilisateurs. Si vous n'êtes pas d'accord et que vous allez aller jusqu'au vote négatif, ajoutez également un commentaire pour expliquer pourquoi vous n'êtes pas d'accord sur le fait que ce n'est pas une bonne approche pour obtenir les résultats souhaités.
John C