批处理文件'choice'命令的errorlevel返回0

时间:2011-12-22 22:50:13

标签: file batch-file command choice errorlevel

我正在尝试创建一个批处理文件,该文件根据正在执行的Windows版本执行不同的“选择”命令。选择命令的语法在Windows 7和Windows XP之间是不同的。

Choice命令为Y返回1,为N返回2.以下命令返回正确的错误级别:

Windows 7:

choice /t 5 /d Y /m "Do you want to automatically shutdown the computer afterwards "
echo %errorlevel%
if '%errorlevel%'=='1' set Shutdown=T
if '%errorlevel%'=='2' set Shutdown=F

Windows XP:

choice /t:Y,5 "Do you want to automatically shutdown the computer afterwards "
echo %ERRORLEVEL%
if '%ERRORLEVEL%'=='1' set Shutdown=T
if '%ERRORLEVEL%'=='2' set Shutdown=F

但是,当它与检测Windows操作系统版本的命令结合使用时,errorlevel在我的Windows XP和Windows 7代码块中的选择命令之后的AN之前返回0。

REM Windows XP
ver | findstr /i "5\.1\." > nul
if '%errorlevel%'=='0' (
set errorlevel=''
echo %errorlevel%
choice /t:Y,5 "Do you want to automatically shutdown the computer afterwards "
echo %ERRORLEVEL%
if '%ERRORLEVEL%'=='1' set Shutdown=T
if '%ERRORLEVEL%'=='2' set Shutdown=F
echo.
)

REM Windows 7
ver | findstr /i "6\.1\." > nul
if '%errorlevel%'=='0' (
set errorlevel=''
echo %errorlevel%
choice /t 5 /d Y /m "Do you want to automatically shutdown the computer afterwards "
echo %errorlevel%
if '%errorlevel%'=='1' set Shutdown=T
if '%errorlevel%'=='2' set Shutdown=F
echo.
)

如您所见,我甚至尝试在执行choice命令之前清除errorlevel var,但是在执行choice命令后errorlevel保持为0。

任何提示? 谢谢!

1 个答案:

答案 0 :(得分:14)

您遇到了一个经典问题 - 您正试图在带括号的代码块中展开%errorlevel%。这种扩展形式在解析时发生,但整个IF构造一次被解析,因此%errorlevel%的值不会改变。

解决方案很简单 - 延迟扩展。您需要在顶部SETLOCAL EnableDelayedExpansion,然后使用!errorlevel!代替。延迟扩展在执行时发生,因此您可以在括号内看到值的更改。

SET(SET /?)的帮助描述了FOR语句的问题和解决方案,但概念是相同的。

您还有其他选择。

您可以将代码从IF的正文移动到没有括号的标记代码段,并使用GOTOCALL来访问代码。然后你可以使用%errorlevel%。我不喜欢这个选项,因为CALLGOTO相对较慢,代码不太优雅。

另一种选择是使用IF ERRORLEVEL N代替IF !ERRORLEVEL!==N。 (请参阅IF /?)因为IF ERRORLEVEL N测试错误级别是否> = N,所以您需要按降序执行测试。

REM Windows XP
ver | findstr /i "5\.1\." > nul
if '%errorlevel%'=='0' (
  choice /t:Y,5 "Do you want to automatically shutdown the computer afterwards "
  if ERRORLEVEL 2 set Shutdown=F
  if ERRORLEVEL 1 set Shutdown=T
)