2012-10-17 65 views
1

我們在批處理文件中調用msbuild命令。如果批處理文件的for循環中沒有執行條件

我們已經通過了批處理文件循環的參數。

FOR %%C in (
    CommonInfrastructure 
    CommonUtilities 
    ) do ( 
     msbuild /t:%BuildCmdType% %BuildFile% /p:Group=%%C %msbuildLogger% /p:Configuration=Release 
     if %ERRORLEVEL% NEQ 0 (
     msbuild /t:SendFailureMail /p:ErrorLogFileName=%ErrorLog% %BuildFile% 
     set ErrorBuild=1 
     ) 
    ) 

當我分析日誌文件時,我看到If塊中的代碼沒有被執行。

由於通知郵件沒有被髮送。

如何讓它執行條件?

+0

系統變量ERRORLEVEL的值是什麼? –

+0

@Vincenzo Maggio:如果msbuild失敗,它將不是0。它工作正常,如果我走出for循環並逐個運行 – Samselvaprabu

+0

您是否嘗試在整個程序執行前將該變量設置爲0? –

回答

3

jeb正確診斷您的問題並提供了一個很好的解決方案。你有其他選擇。

IF ERRORLEVEL 1 ...(不含百分數)檢查ERRORLEVEL是否大於或等於1.只要msbuild永遠不返回負ERRORLEVEL,就應該工作。

FOR %%C in (
    CommonInfrastructure 
    CommonUtilities 
) do ( 
    msbuild /t:%BuildCmdType% %BuildFile% /p:Group=%%C %msbuildLogger% /p:Configuration=Release 
    if ERRORLEVEL 1 (
     msbuild /t:SendFailureMail /p:ErrorLogFileName=%ErrorLog% %BuildFile% 
     set ErrorBuild=1 
    ) 
) 


可以測試任何非零值,而無需使用擴展通過使用可變的和IF(NOT)DEFINED

set "success=" 
FOR %%C in (
    CommonInfrastructure 
    CommonUtilities 
) do ( 
    msbuild /t:%BuildCmdType% %BuildFile% /p:Group=%%C %msbuildLogger% /p:Configuration=Release 
    if errorlevel 0 if not errorlevel 1 set success=1 
    if not defined success (
     msbuild /t:SendFailureMail /p:ErrorLogFileName=%ErrorLog% %BuildFile% 
     set ErrorBuild=1 
    ) 
) 


我的優選解決方案是使用||操作者有條件只有在先前的命令失敗時才執行命令。 (注意 - &&運營商在成功時有條件執行)

FOR %%C in (
    CommonInfrastructure 
    CommonUtilities 
) do ( 
    msbuild /t:%BuildCmdType% %BuildFile% /p:Group=%%C %msbuildLogger% /p:Configuration=Release || (
     msbuild /t:SendFailureMail /p:ErrorLogFileName=%ErrorLog% %BuildFile% 
     set ErrorBuild=1 
    ) 
) 
3

這是批處理文件的解析類型。
塊中的所有百分比,括號內的任何內容都在解析時擴展,而不是在執行時擴展。
所以你的%errrorlevel%將會在任何命令在你的塊中運行之前被一次性地擴大。所以它會通常總是爲零。

爲了避免這種情況,存在延遲膨脹,請使用此代替。

!errorlevel!代替%errorlevvel% 而你需要激活才能使用它(最好在你的批處理腳本的第二行)。

setlocal EnableDelayedExpansion