如何从Windows批处理文件测试%PATH%中是否存在可执行文件?


89

我正在寻找一种简单的方法来测试Windows批处理文件中PATH环境变量中是否存在可执行文件。

不允许使用操作系统未提供的外部工具。所需的最低Windows版本是Windows XP。



15
@karlphilip:绝对不会。这里的问题是完全不同的。
乔伊(Joey)

1
您应该标记一个可接受的答案。
杰布

Answers:


69
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)文件和命令行上的解析有所不同(因为批处理文件具有%0%9),因此您必须将其加倍%。在命令行上,这不是必需的,因此对于变量而言%X


1
我喜欢您的方法,但是如果您可以提供完整版本,那就更好了,因为它也使用PATHEXT。
sorin 2011年

4
对于XP,您需要循环脚本(或从RK下载where.exe)。Vista和7随where.exe一起提供。我知道OP专门说XP,但是对于后代来说,最好的答案总是使用where myExecutable
瑞安·贝罗斯

瑞安:嗯?我认为我无法解析您的句子。
乔伊(Joey)

2
我是批处理脚本的初学者,不确定%% x是什么意思。在我的Windows 7系统上,我尝试键入:在(myExecutable.exe)中为%% X做(设置FOUND = %%〜$ PATH:X),然后按回车键。我得到了响应:C:\ Users \ James>在(cmd.exe)中执行%% X(设置FOUND = %%〜$ PATH:X)%% X此时是意外的。
simgineer

3
simengineer:批处理文件中和命令行上的解析有所不同(因为批处理文件中有%0%9),因此您必须将其加倍%。在命令行上这不是必需的,因此for变量只是%x
乔伊

79

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 2013年

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
有趣的特技setlocalfor %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)是与一个线路溶液for作为替代方法用于%%~$PATH:X以避免call%~$PATH:1
gotnkoa

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 2012年

1
XP1:不,仍然没有用。通过追加"C:\Folder with; semicolon, quoted"到路径来尝试一下,看看会发生什么。至少在这里,它尝试将每个“单词”分开对待,这在某种程度上比以前的行为更糟​​。
2012年

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测试路径“您要查找的exe”

如果存在,它将返回True,否则返回False。


这行不通。Test-Path仅检查指定的路径,即Test-Path nuget.exenuget.exe在当前目录中时才返回true 。如果nuget.exe不在当前目录中,则即使它在PATH变量中列出的目录中,它也会返回false。在PowerShell中Get-Command可能会更好地工作(stackoverflow.com/questions/11242368/…),但要考虑到对于PowerShell,当前目录不在路径中。
罗纳德·扎里茨(RonaldZarīts)2015年

1
正如@RonaldZarits所指出的,要获得完全的PowerShell支持,可以将Get-Command与两个选项一起使用。首先提供当前目录位置,然后仅提供exe名称。(Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $null如果在本地或路径中找到,将返回true。
约翰C,

-1

对于那些寻找PowerShell选项的人。您可以使用Get-Commandcmdlet传递两个项目。首先给当前目录加上.\前缀,然后仅给出exe名称。

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

如果找到本地路径或系统范围路径,则返回true。


没有什么比拒绝投票和运行用户更好。如果您不同意并打算大范围投票,则还请添加一条评论,以说明不同意这不是获得所需结果的好方法的原因。
John C
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.