我们在批处理文件中调用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 :(得分: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
)
)