Соблюдение кодов выхода из пакетных файлов, вызванных msbuild

У меня есть пакетный файл, который использует команду exit для возврата кода выхода.

Этот пакетный файл в некоторых случаях может быть запущен в интерактивном режиме из командной строки, а в других случаях может быть запущен как часть проекта MSBuild с использованием задачи Exec.

  • Если я использую 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 по-прежнему не получает правильное значение ошибки.


person Daniel Fortunov    schedule 18.05.2009    source источник


Ответы (3)


Один из способов справиться с этим может заключаться в том, чтобы 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

Сайед Ибрагим Хашими

Моя книга: Внутри Microsoft Build Engine: Использование MSBuild и Team Foundation Build

person Sayed Ibrahim Hashimi    schedule 19.05.2009

Этот вопрос немного старше, но ответ все еще может представлять интерес, так что вот:

Слегка измените задачу MSBuild, чтобы

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

И держи

exit /b %errorlevel%

в вашем Batch.cmd.

person Alexander Rautenberg    schedule 14.03.2013

Я не пробовал, но что, если вы просто установите переменную среды с именем ERRORLEVEL? Скрытый после содержимого вашей команды Exec, MSBuild имеет «выход% ERRORLEVEL%». %ERRORLEVEL%, если установлен, переопределяет любой фактический уровень ошибки.

person Community    schedule 12.09.2009