Запоминание кодов выхода из пакетных файлов, вызванных msbuild - PullRequest
7 голосов
/ 18 мая 2009

У меня есть командный файл, который использует команду 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 все еще не получает правильное значение ошибки.

Ответы [ 3 ]

13 голосов
/ 19 мая 2009

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

2 голосов
/ 14 марта 2013

Этот вопрос немного старше, но ответ все еще может быть интересен, поэтому здесь идет речь:

Немного измените задачу MSBuild на

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

И держи

exit /b %errorlevel%

в вашем Batch.cmd.

0 голосов
/ 12 сентября 2009

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

...