2011-12-22 69 views
6

我想創建一個批處理文件,該文件根據正在執行的Windows版本執行不同的'選擇'命令。 Windows 7和Windows XP的選擇命令語法不同。批處理文件'選擇'命令的錯誤級別返回0

選擇命令返回用於Y 1和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 

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操作系統版本的命令結合使用時,錯誤級別在我的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. 
) 

正如你所看到的,我甚至嘗試執行選擇命令之前清除錯誤級別變種,但在執行選擇命令後,錯誤級別仍爲0。

任何提示? 謝謝!

回答

13

您已經遇到了一個經典問題 - 您試圖在括號內的代碼塊中擴展%errorlevel%。這種擴展形式在解析時發生,但是整個IF構造被立即解析,所以%errorlevel%的值不會改變。

解決方案很簡單 - 延遲擴展。頂部需要SETLOCAL EnableDelayedExpansion,然後用!errorlevel!代替。延遲擴展在執行時發生,因此您可以看到括號內值的更改。

SET的幫助(SET /?)描述了有關FOR語句的問題和解決方案,但概念是相同的。

您有其他選擇。

您可以將IF正文中的代碼移動到不帶括號的代碼標籤部分,並使用GOTOCALL來訪問代碼。然後你可以使用%errorlevel%。我不喜歡這個選項,因爲CALLGOTO比較慢,代碼不太優雅。

另一種選擇是使用IF ERRORLEVEL N而不是IF !ERRORLEVEL!==N。 (請參閱IF /?)由於IF ERRORLEVEL N測試errorlevel是否大於等於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 
)