Нивото на грешка на командата 'choice' на партиден файл връща 0

Опитвам се да създам партиден файл, който изпълнява различна команда „избор“ въз основа на версията на Windows, на която се изпълнява. Синтаксисът на командата за избор е различен между Windows 7 и Windows XP.

Командата за избор връща 1 за Y и 2 за N. Следната команда връща правилното ниво на грешка:

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

Уиндоус експи:

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 OS, errorlevel връща 0 преди AN след командата за избор и в моите блокове код на Windows XP и Windows 7.

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.
)

Както можете да видите, дори се опитах да изчистя променливата на нивото на грешка, преди да изпълня командата за избор, но нивото на грешка остава 0 след изпълнението на командата за избор.

Някакви съвети? Благодаря!


person lbrtdy    schedule 22.12.2011    source източник


Отговори (1)


Срещнахте класически проблем - Опитвате се да разширите %errorlevel% в рамките на блок код в скоби. Тази форма на разширение се появява по време на анализ, но цялата конструкция IF се анализира наведнъж, така че стойността на %errorlevel% няма да се промени.

Решението е просто - забавено разширяване. Трябва ви SETLOCAL EnableDelayedExpansion в горната част и след това използвайте !errorlevel! вместо това. Забавеното разширяване възниква по време на изпълнение, така че тогава можете да видите промените в стойността в скобите.

Помощта за SET (SET /?) описва проблема и решението по отношение на оператор FOR, но концепцията е същата.

Имате и други възможности.

Можете да преместите кода от тялото на IF към обозначени секции от код без скоби и да използвате GOTO или CALL за достъп до кода. След това можете да използвате %errorlevel%. Не харесвам тази опция, защото CALL и GOTO са относително бавни и кодът не е толкова елегантен.

Друг вариант е да използвате 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
)
person dbenham    schedule 23.12.2011