2011-12-22 22 views
6

Sto cercando di creare un file batch che esegua un comando 'choice' diverso in base alla versione di Windows in esecuzione. La sintassi del comando choice è diversa tra Windows 7 e Windows XP.Il file di errore del file batch 'choice' restituisce 0

Scelta comando restituisce un 1 per Y e 2 per N. Il comando seguente restituisce il corretto livello di errore:

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 

Tuttavia , quando è combinato con un comando per rilevare la versione del sistema operativo Windows, errorlevel restituisce 0 prima di AN dopo il comando choice in entrambi i miei blocchi di codice Windows XP e 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. 
) 

Come potete vedere, ho anche provato aprendo l'errorlevel var prima di eseguire il comando di scelta, ma errorlevel rimane a 0 dopo l'esecuzione del comando di scelta.

Qualche consiglio? Grazie!

risposta

13

Si è verificato un problema classico: si sta tentando di espandere %errorlevel% all'interno di un blocco di codice in parentesi. Quella forma di espansione si verifica in fase di analisi, ma l'intero costrutto IF viene analizzato in una sola volta, quindi il valore di %errorlevel% non cambierà.

La soluzione è semplice: espansione ritardata. È necessario SETLOCAL EnableDelayedExpansion nella parte superiore, quindi utilizzare !errorlevel!. L'espansione ritardata si verifica al momento dell'esecuzione, quindi è possibile visualizzare le modifiche al valore tra parentesi.

L'aiuto per SET (SET /?) descrive il problema e la soluzione rispetto all'istruzione FOR, ma il concetto è lo stesso.

Hai altre opzioni.

È possibile spostare il codice all'interno del corpo di IF in sezioni del codice etichettate senza parentesi e utilizzare GOTO o CALL per accedere al codice. Quindi è possibile utilizzare %errorlevel%. Non mi piace questa opzione perché CALL e GOTO sono relativamente lenti e il codice è meno elegante.

Un'altra opzione è utilizzare IF ERRORLEVEL N anziché IF !ERRORLEVEL!==N. (Vedere IF /?) Perché il test IF ERRORLEVEL N se errorlevel è> = N, è necessario eseguire i test in ordine decrescente.

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 
)