How to test if an executable exists in the %PATH% from a windows batch file?
Asked Answered
A

8

113

I'm looking for a simple way to test if an executable exists in the PATH environment variable from a Windows batch file.

Usage of external tools not provided by the OS is not allowed. The minimal Windows version required is Windows XP.

Abductor answered 24/1, 2011 at 12:8 Comment(2)
possible duplicate of How to check if a file exists in DOS batchNevertheless
@karlphilip: Definitely no. The question here is quite different.Engender
E
74
for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)
if defined FOUND ...

If you need this for different extensions, just iterate over PATHEXT:

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

Could be that where also exists already on legacy Windows versions, but I don't have access to one, so I cannot tell. On my machine the following also works:

where myExecutable

and returns with a non-zero exit code if it couldn't be found. In a batch you probably also want to redirect output to NUL, though.

Keep in mind

Parsing in batch (.bat) files and on the command line differs (because batch files have %0%9), so you have to double the % there. On the command line this isn't necessary, so for variables are just %X.

Engender answered 24/1, 2011 at 12:10 Comment(8)
I like your approach but it would be even better if you could provide the full version, the one that does also use PATHEXT for this.Abductor
For XP you need the loop script (or download where.exe from the RK). Vista and 7 ships with where.exe. I know the OP specifically said XP, but for posterity the best answer is always to use where myExecutable.Stormie
Ryan: Huh? I don't think I can parse your sentence.Engender
where.exe (shipped only with Vista and up) has a /q switch which suppresses the need of redirecting output in a script. where /q cmd OR where /q cmd.exe does do the trick.Esquivel
i'm a batch scripting beginner and am not sure what the %%x means. On my Windows 7 system i tried typing: for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X) and then hit returned. i got this in response: C:\Users\James>for %%X in (cmd.exe) do (set FOUND=%%~$PATH:X) %%X was unexpected at this time.Philippians
simengineer: Parsing in batch files and on the command line differs (because batch files have %0%9), so you have to double the % there. On the command line this isn't necessary, so for variables are just %x.Engender
great! this works after hours of investigations on this issuePlug
@RyanBemrose: I think you should post it as a separate answer, even if the OP asked for XP. :) (I think many of us will still find this thread who don't use XP anymore - and it's good that we don't use it anymore.) It's a really good idea (I firstly forgot where opportunity), and you would get upvotes - at least from me. :)Krona
S
105

Windows Vista and later versions ship with a program called where.exe that searches for programs in the path. It works like this:

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

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

For use in a batch file you can use the /q switch, which just sets ERRORLEVEL and doesn't produce any 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!
)

Or a simple (but less readable) shorthand version that prints the message and exits your app:

where /q myapplication || ECHO Cound not find app. && EXIT /B
Stormie answered 6/9, 2014 at 3:8 Comment(1)
Very nice and simple! Thanks!Eunuchoidism
E
74
for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)
if defined FOUND ...

If you need this for different extensions, just iterate over PATHEXT:

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

Could be that where also exists already on legacy Windows versions, but I don't have access to one, so I cannot tell. On my machine the following also works:

where myExecutable

and returns with a non-zero exit code if it couldn't be found. In a batch you probably also want to redirect output to NUL, though.

Keep in mind

Parsing in batch (.bat) files and on the command line differs (because batch files have %0%9), so you have to double the % there. On the command line this isn't necessary, so for variables are just %X.

Engender answered 24/1, 2011 at 12:10 Comment(8)
I like your approach but it would be even better if you could provide the full version, the one that does also use PATHEXT for this.Abductor
For XP you need the loop script (or download where.exe from the RK). Vista and 7 ships with where.exe. I know the OP specifically said XP, but for posterity the best answer is always to use where myExecutable.Stormie
Ryan: Huh? I don't think I can parse your sentence.Engender
where.exe (shipped only with Vista and up) has a /q switch which suppresses the need of redirecting output in a script. where /q cmd OR where /q cmd.exe does do the trick.Esquivel
i'm a batch scripting beginner and am not sure what the %%x means. On my Windows 7 system i tried typing: for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X) and then hit returned. i got this in response: C:\Users\James>for %%X in (cmd.exe) do (set FOUND=%%~$PATH:X) %%X was unexpected at this time.Philippians
simengineer: Parsing in batch files and on the command line differs (because batch files have %0%9), so you have to double the % there. On the command line this isn't necessary, so for variables are just %x.Engender
great! this works after hours of investigations on this issuePlug
@RyanBemrose: I think you should post it as a separate answer, even if the OP asked for XP. :) (I think many of us will still find this thread who don't use XP anymore - and it's good that we don't use it anymore.) It's a really good idea (I firstly forgot where opportunity), and you would get upvotes - at least from me. :)Krona
W
19

Here is a simple solution that attempts to run the application and handles any error afterwards.

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

Error code 9009 usually means file not found.

The only downside is that file.exe is actually executed if found (which in some cases is not desiderable).

Whiteside answered 4/11, 2013 at 21:36 Comment(1)
the only downside is that "file.exe" is executed (which in some cases is unwanted)Whiteside
C
6

This can be accomplished via parameter substitution.

%~$PATH:1

This returns the full path of the executable filename in %1, else an empty string.

This does not work with user-defined variables. So if the executable filename is not a parameter to your script, then you need a subroutine. For example:

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

goto :eof

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

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

Cannell answered 24/9, 2013 at 13:3 Comment(1)
Interesting trick with setlocal but for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X) is one line solution with for used as workaround for %%~$PATH:X in order to avoid call and %~$PATH:1.Kinder
D
3

For those looking for a PowerShell option. You can use the Get-Command cmdlet passing two items. First give the current dir location with .\ prefixed, then give just the exe name.

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

That will return true if found local or in system wide paths.

Destructor answered 31/1, 2019 at 18:18 Comment(1)
Nothing better than downvote and run users. If you disagree and are going to go as far as downvoting, then also add a comment to give your reason why you disagree that this is not a good approach at getting the desired results.Destructor
N
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%"=="" ....
Nerveless answered 25/1, 2011 at 16:50 Comment(3)
Won't work as for is not smart enough to parse the contents of PATH. It will miss directories with spaces, for example. And even when you use for /f with delims=; it will not work correctly if a directory contains a ; and is quoted.Engender
@Joey, how about string replacement? Replace ; with "; ": set quotedPath="%PATH:;="; "%".Excaudate
XP1: Nope, still useless. Try it by appending "C:\Folder with; semicolon, quoted" to the path and see what happens. At least here it tries treating every »word« separately which, in a way, is worse than the behaviour before.Engender
S
-1

Sometimes this simple solution works, where you check to see if the output matches what you expect. The first line runs the command and grabs the last line of standard output.

FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.
Smoot answered 12/6, 2013 at 16:3 Comment(1)
But what if the system environment uses an other language?Perrone
A
-1

Use command : powershell Test-Path "exe which you looking for"

It will return True if its present, otherwise False.

Appetence answered 26/6, 2015 at 12:4 Comment(2)
This won't work. Test-Path only checks the specified path, i.e. Test-Path nuget.exe will return true only if nuget.exe is in the current directory. If nuget.exe is not in the current directory, it will return false, even if it is in a directory listed in the PATH variable. In PowerShell Get-Command might work better(#11242868), but take into account that for PowerShell the current directory is not in the path.Assume
As @RonaldZarits pointed out, for full PowerShell support, you can use the Get-Command with two options. First give the current dir location, then give just the exe name. (Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $null will return true if found local or in path.Destructor

© 2022 - 2024 — McMap. All rights reserved.