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

发布于 2024-07-19 11:01:56 字数 806 浏览 9 评论 0原文

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

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

  • 如果我在批处理文件中使用 exit %errorlevel% ,则效果很好,并且 MSBuild 会看到错误代码,但是从命令窗口运行批处理文件的交互式用户将在这种情况下,粗鲁地退出 cmd.exe。
  • 如果我使用 exit /b %errorlevel% 交互式场景不会粗鲁退出,但这也意味着我的 Exec 启动的 cmd > 任务也不会退出,因此 MSBuild 看不到返回值。

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

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

这个想法是我明确地从 exit /b 返回“非终端” code>exit /b 并手动调用 exit 将此值传播到 cmd.exe 之外,其中 Exec 构建任务可以看到它。

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

I have a batch file that is using the exit command to return an exit code.

This batch file may, in some cases, be invoked interactively from a commandline, or in other cases, may be run as part of an MSBuild project, using the Exec task.

  • If I use exit %errorlevel% within my batch file this works well and MSBuild sees the error code, however an interactive user who is running the batch file from a command window will get a rude exit of cmd.exe in this case.
  • If I use exit /b %errorlevel% the interactive scenario does not get a rude exit, but this also means that the cmd launched by my Exec task also does not exit, and therefore MSBuild does not see the return value.

As a solution to both problems, I am trying to use exit /b but launch the batch file from my build script like this:

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

The idea being that I explicitly take the 'non-terminal' return from exit /b and manually call exit to propogate this value outside of cmd.exe where the Exec Build Task can see it.

This seems like the perfect solution, however it isn't working. Exec still doesn't get the correct error value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情未る 2024-07-26 11:01:56

处理此问题的一种方法可能是让 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

One way to handle this could be to have MSBuild pass a parameter to the batch file so that it knows that MSBuild is calling it instead of from a command prompt.
For example I have created the sample file test.bat shown below

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%

And I've created the MSBuild file wrapper.proj which is:

<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>

If you execute the file test.bat from the command prompt the result is

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

And from MSBuild the result is:

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
爱冒险 2024-07-26 11:01:56

这个问题有点老了,但响应可能仍然令人感兴趣,所以这里是:

稍微修改您的 MSBuild 任务

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

并将其保留

exit /b %errorlevel%

在您的 Batch.cmd 中。

This question is a bit older, but the response may still be of interest, so here goes:

Slightly modify your MSBuild task to

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

And keep the

exit /b %errorlevel%

in your Batch.cmd.

笑饮青盏花 2024-07-26 11:01:56

我还没有尝试过这个,但是如果您只是设置一个名为 ERRORLEVEL 的环境变量怎么办? MSBuild 隐藏在 Exec 命令内容之后,有“exit %ERRORLEVEL%”。 %ERRORLEVEL%(如果设置)将覆盖任何实际错误级别。

I haven't tried this, but what if you just set an environment variable named ERRORLEVEL? Hidden after the content of your Exec command, MSBuild has "exit %ERRORLEVEL%". %ERRORLEVEL% if set overrides any actual error level.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文