例如,在 Windows 7mklink
上可用,cmd.exe /C mklink
但在 Windows XP 上不可用。
除了执行cmd.exe /C mklink
和尝试读取之外,errorlevel
是否有更简单的方法来测试 cmd.exe 是否支持命令?
谢谢!
例如,在 Windows 7mklink
上可用,cmd.exe /C mklink
但在 Windows XP 上不可用。
除了执行cmd.exe /C mklink
和尝试读取之外,errorlevel
是否有更简单的方法来测试 cmd.exe 是否支持命令?
谢谢!
ERRORLEVEL
of不是命令存在的cmd
良好指标,因为如果命令不存在或失败,它会设置为非零值,这可能会导致您的测试失败。
或者,您可以执行以下操作之一:
就像 Adriano 在评论中建议的那样,可以像这样检查 Windows 的版本:
set mklink_supported=true
ver | find "XP" >nul 2>&1 && set mklink_supported=false
或者像这样:
set mklink_supported=false
echo %vers% | find "Windows 7" >nul 2>&1 && set mklink_supported=true
进而:
if %mklink_supported%==false (
echo 'mklink' is not supported on this operating system.
)
或类似的东西。不过,您需要确保处理所有必要的操作系统版本。
ERRORLEVEL
或者,您可以尝试mklink
直接运行。如果未找到,ERRORLEVEL
则设置为9009
:
@echo off
mklink >nul 2>&1
if errorlevel 9009 if not errorlevel 9010 (
echo 'mklink' is not supported on this operating system.
)
请注意,有两个if
- 语句。if errorlevel 9009
如果ERRORLEVEL
>=9009 则有效,因此需要第二个if
语句来排除ERRORLEVEL
>9009 时的情况)。
我更喜欢第二种解决方案,因为它预计适用于所有版本的 Windows。
要找到可执行文件,您可以在for
循环中使用变量扩展:
setlocal EnableDelayedExpansion
set found=no
for %%f in (mklink.exe) do if exist "%%~$PATH:f" set found=yes
echo %found%
endlocal
@echo off
(for /f %%F in ('help') do echo '%%F ')|findstr /i /c:"%1 " 2>&1 >nul && echo Supported || echo Not supported
这取决于一个事实,该事实help
似乎包括相当完整的内部命令列表(以及相当多的外部命令)。它需要命令名称作为它的参数 ( isSupported.bat command_name
)
它实际上并没有测试给定的命令是否执行,只有当它应该存在时......
这只是一个想法,请尝试使其无效,如果你这样做,我会很乐意删除。
不久前,我在 SS64 Windows CMD Shell 论坛上发布了这个批处理脚本。它将 wmz 和 Ansgar Wiechers 答案中的想法结合到一个方便的包中。
它尝试在 PATH 中的某处定位给定的可执行文件,如果找不到,则搜索 HELP。如果 HELP 涵盖的标准实用程序丢失,它可能会给出错误的结果和一些丑陋的错误消息。
::WHICH.BAT CommandName [ReturnVar]
::
:: Determines the full path of the file that would execute if
:: CommandName were executed.
::
:: The result is stored in variable ReturnVar, or else it is
:: echoed to stdout if ReturnVar is not specified.
::
:: If no file is found, then an error message is echoed to stderr.
::
:: The ERRORLEVEL is set to one of the following values
:: 0 - Success: A matching file was found
:: 1 - No file was found and CommandName is an internal command
:: 2 - No file was found and CommandName is not an internal command
:: 3 - Improper syntax - no CommandName specified
::
@echo off
setlocal disableDelayedExpansion
set "file=%~1"
if not defined file (
>&2 echo Syntax error: No CommandName specified
exit /b 3
)
set "noExt="
setlocal enableDelayedExpansion
if "%~x1" neq "" if "!PATHEXT:%~x1=!" neq "!PATHEXT!" set noExt="";
set "modpath=.\;!PATH!"
@for %%E in (%noExt%%PATHEXT%) do @for %%F in ("!file!%%~E") do (
setlocal disableDelayedExpansion
if not "%%~$modpath:F"=="" if not exist "%%~$modpath:F\" (
endlocal & endlocal & endlocal
if "%~2"=="" (echo %%~$modpath:F) else set "%~2=%%~$modpath:F"
exit /b 0
)
endlocal
)
endlocal
>nul help %~1 && (
>&2 echo "%~1" is not a valid command
exit /b 2
)
>&2 echo "%~1" is an internal command