我正在寻找一种简单的方法来测试Windows批处理文件中PATH环境变量中是否存在可执行文件。
不允许使用操作系统未提供的外部工具。所需的最低Windows版本是Windows XP。
Answers:
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
。
where myExecutable
。
%0
– %9
),因此您必须将其加倍%
。在命令行上这不是必需的,因此for
变量只是%x
。
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
这是一个尝试运行应用程序并随后处理任何错误的简单解决方案。
file.exe /? 2> NUL
IF NOT %ERRORLEVEL%==9009 ECHO file.exe exists in path
错误代码9009通常表示找不到文件。
唯一的缺点是,file.exe
如果找到,则会实际执行(在某些情况下这是不可取的)。
这可以通过参数替换来实现。
%~$PATH:1
这将返回%1中可执行文件名的完整路径,否则返回一个空字符串。
这不适用于用户定义的变量。因此,如果可执行文件名不是脚本的参数,则需要一个子例程。例如:
call :s_which app.exe
if not "%_path%" == "" (
"%_path%"
)
goto :eof
:s_which
setlocal
endlocal & set _path=%~$PATH:1
goto :eof
setlocal
但for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)
是与一个线路溶液for
作为替代方法用于%%~$PATH:X
以避免call
和%~$PATH:1
。
@echo off
set found=
set prog=cmd.exe
for %%i in (%path%) do if exist %%i\%prog% set found=%%i
echo "%found%"
if "%found%"=="" ....
for
无法解析的内容,因此无法正常工作PATH
。例如,它将丢失带有空格的目录。并且即使在for /f
与之一起使用时delims=;
,如果目录包含;
和引号,它将无法正常工作。
;
为"; "
:set quotedPath="%PATH:;="; "%"
。
"C:\Folder with; semicolon, quoted"
到路径来尝试一下,看看会发生什么。至少在这里,它尝试将每个“单词”分开对待,这在某种程度上比以前的行为更糟。
有时,这种简单的解决方案会起作用,您可以在其中检查输出是否符合期望。第一行运行命令并获取标准输出的最后一行。
FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.
如果您正在启动文件夹中搜索类似我的东西,则应该进入文件夹。例如,我在启动文件夹中搜索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!
)
program.exe
存在)中进行搜索,而不只是在一个文件夹中进行搜索
使用命令:powershell测试路径“您要查找的exe”
如果存在,它将返回True,否则返回False。
Test-Path
仅检查指定的路径,即Test-Path nuget.exe
仅nuget.exe
在当前目录中时才返回true 。如果nuget.exe不在当前目录中,则即使它在PATH变量中列出的目录中,它也会返回false。在PowerShell中Get-Command
可能会更好地工作(stackoverflow.com/questions/11242368/…),但要考虑到对于PowerShell,当前目录不在路径中。
(Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $null
如果在本地或路径中找到,将返回true。
对于那些寻找PowerShell选项的人。您可以使用Get-Command
cmdlet传递两个项目。首先给当前目录加上.\
前缀,然后仅给出exe名称。
(Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $null
如果找到本地路径或系统范围路径,则返回true。