如果没有在批处理文件的for循环中执行条件

时间:2012-10-17 06:41:14

标签: batch-file

我们在批处理文件中调用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块中的代码没有被执行。

由于没有发送通知邮件。

如果条件如何让它执行?

2 个答案:

答案 0 :(得分:3)

这是批处理文件的解析类型 块中的所有百分比,括号内的任何内容,都在解析时而不是在执行时扩展 因此,在任何命令在块中运行之前,您的%errrorlevel%将被精确扩展一次。所以通常总是为零。

为避免这种情况,存在延迟扩展,请改用它。

!errorlevel!代替%errorlevvel% 您需要先激活它才能使用它(最好在批处理脚本的第二行)。

setlocal EnableDelayedExpansion

答案 1 :(得分: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
    )
)