2011-12-22 15 views
6

Estoy tratando de crear un archivo por lotes que realiza un comando diferente 'choice' basado en la versión de Windows que se está ejecutando. La sintaxis del comando de elección es diferente entre Windows 7 y Windows XP.Error del comando de "elección" del archivo por lotes returnlevel 0

elección comando devuelve un 1 para Y y 2 para N. El siguiente comando devuelve el nivel correcto de error:

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 

Sin embargo Cuando se combina con un comando para detectar la versión del sistema operativo Windows, errorlevel devuelve 0 antes que AN después del comando de opción en mis bloques de código de Windows XP y 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. 
) 

Como se puede ver, que incluso intentó despejar el nivel de error var antes de ejecutar el comando elección, pero se mantiene en nivel de error 0 después de ejecutar el comando elección.

¿Algún consejo? Gracias!

Respuesta

13

Se ha encontrado con un problema clásico: está intentando expandir %errorlevel% dentro de un bloque de código entre paréntesis. Esa forma de expansión se produce en el tiempo de análisis, pero toda la construcción IF se analiza al mismo tiempo, por lo que el valor de %errorlevel% no cambiará.

La solución es simple: expansión retrasada. Necesita SETLOCAL EnableDelayedExpansion en la parte superior y luego, en su lugar, use !errorlevel!. La expansión retrasada ocurre en el momento de la ejecución, entonces usted puede ver los cambios en el valor entre paréntesis.

La ayuda para SET (SET /?) describe el problema y la solución con respecto a una declaración FOR, pero el concepto es el mismo.

Tiene otras opciones.

se puede mover el código desde dentro del cuerpo de la IF a etiquetadas secciones de código sin paréntesis, y utilizar GOTOCALL o acceder al código. Entonces puede usar %errorlevel%. No me gusta esta opción porque CALL y GOTO son relativamente lentos y el código es menos elegante.

Otra opción es usar IF ERRORLEVEL N en lugar de IF !ERRORLEVEL!==N. (Consulte IF /?) Dado que IF ERRORLEVEL N prueba si errorlevel es> = N, debe realizar las pruebas en orden descendente.

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 
) 
Cuestiones relacionadas