尊重msbuild调用的批处理文件中的退出代码

时间:2009-05-18 18:02:45

标签: msbuild batch-file msbuild-task

我有一个使用exit命令返回退出代码的批处理文件。

在某些情况下,可以从命令行以交互方式调用此批处理文件,或者在其他情况下,可以使用Exec任务作为MSBuild项目的一部分运行此批处理文件。

  • 如果我在我的批处理文件中使用exit %errorlevel%,那么效果很好,MSBuild会看到错误代码,然而从命令窗口运行批处理文件的交互式用户将会变得粗鲁无礼在这种情况下退出cmd.exe。
  • 如果我使用exit /b %errorlevel%,交互式方案不会出现粗暴退出,但这也意味着我的cmd任务启动的Exec也不会退出,因此MSBuild会没有看到返回值。

作为这两个问题的解决方案,我尝试使用exit /b但是从我的构建脚本中启动批处理文件,如下所示:

<Exec Command="Batch.cmd params &amp; exit %errorlevel%" />

我的想法是明确地从exit /b获取'非终端'回报并手动调用exit以在cmd.exe之外传播此值Exec任务可以看到它。

这似乎是完美的解决方案,但它不起作用。 Exec仍然无法获得正确的错误值。

3 个答案:

答案 0 :(得分:13)

处理此问题的一种方法是让MSBuild将参数传递给批处理文件,以便它知道MSBuild正在调用它而不是从命令提示符调用它。 例如,我创建了下面显示的示例文件test.bat

ECHO OFF

IF (%1)==() goto Start
SET fromMSBuild=1

:Start

ECHO fromMSBuild:%fromMSBuild%


REM ***** Perform your actions here *****

set theExitCode=101
GOTO End



:End
IF %fromMSBuild%==1 exit %theExitCode%


REM **** Not from MSBuild ****

ECHO Exiting with exit code %theExitCode%
exit /b %theExitCode%

我已经创建了MSBuild文件wrapper.proj,它是:

<Project DefaultTargets="Demo" ToolsVersion="3.5"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <BatchFile>test.bat</BatchFile>
    <FromMSBuild>FromMSBuild</FromMSBuild>
  </PropertyGroup>

  <Target Name="Demo">

    <Message Text="Executing batch file $(BatchFile)" Importance="high"/>

    <PropertyGroup>
      <_Command>$(BatchFile) $(FromMSBuild)</_Command>
    </PropertyGroup>

    <Exec Command="$(_Command)">
      <Output PropertyName="CommandExitCode" TaskParameter="ExitCode"/>
    </Exec>

    <Message Text="CommandExitCode: $(CommandExitCode)"/>

  </Target>
</Project>

如果从命令提示符执行文件test.bat,结果为

C:\Data\Development\My Code\Community\MSBuild\BatchFile>test.bat

C:\Data\Development\My Code\Community\MSBuild\BatchFile>ECHO OFF
fromMSBuild:0
Exiting with exit code 101

从MSBuild得到的结果是:

C:\Data\Development\My Code\Community\MSBuild\BatchFile>msbuild Wrapper.proj /t:Demo /fl /nologo
Build started 5/18/2009 10:54:52 PM.
Project "C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj" on node 0 (Demo target(s)).
  Executing batch file test.bat
  fromMSBuild:1
C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj(17,5): error MSB3073: The command "test.bat FromMSBuild" exi
ted with code 101.
Done Building Project "C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj" (Demo target(s)) -- FAILED.


Build FAILED.

"C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj" (Demo target) (1) ->
(Demo target) ->
  C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj(17,5): error MSB3073: The command "test.bat FromMSBuild" e
xited with code 101.

    0 Warning(s)
    1 Error(s)

Time Elapsed 00:00:00.06

Sayed Ibrahim Hashimi

我的书:Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build

答案 1 :(得分:2)

这个问题有点老了,但回复可能仍然有意义,所以这里有:

稍微修改您的MSBuild任务

<Exec Command='cmd.exe /C "call Batch.cmd params &amp;&amp; exit %errorlevel%"' />

并保持

exit /b %errorlevel%

在Batch.cmd中。

答案 2 :(得分:0)

我没试过这个,但是如果你只设置一个名为ERRORLEVEL的环境变量呢?在Exec命令的内容后隐藏,MSBuild具有“exit%ERRORLEVEL%”。 %ERRORLEVEL%如果设置覆盖任何实际错误级别。