Как обрабатывать ошибки при использовании целевого пакетирования в msbuild? - PullRequest
4 голосов
/ 29 декабря 2011

Я использую пакетную обработку для цели и хочу выполнить очистку OnError, которая специфична для итерации, в которой произошла ошибка.Вот полностью обобщенный пример:

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

<ItemGroup>
    <Example Include="Item1">
        <Color>Blue</Color>
    </Example>
    <Example Include="Item2">
        <Color>Red</Color>
    </Example>
</ItemGroup>

<Target Name="Build"
    Inputs="@(Example)"
    Outputs="%(Example.Color).txt">
    <Error Text="An error occurred during %(Example.Color)" />
    <OnError ExecuteTargets="HandleErrors" />
</Target>

<Target Name="HandleErrors">
    <Message Text="Do some cleanup about %(Example.Color)" Importance="high" />
</Target>

</Project>

Цель сборки не работает, когда цвет синий.Но цель HandleErrors запускается дважды, по одному разу для каждого цвета.Есть ли способ заставить его работать только для цвета, который был активен во время сбоя?

Ответы [ 2 ]

9 голосов
/ 29 декабря 2011

Я думаю, что не ясно, что именно точно происходит здесь.Прежде чем мы перейдем к вашему вопросу, давайте посмотрим, что происходит, изменив ваш proj-файл.

Ниже приведен измененный файл sample-no-error.proj, в котором я удалил части ошибок и просто добавилЗадача сообщения там.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
  <ItemGroup>
      <Example Include="Item1">
          <Color>Blue</Color>
      </Example>
      <Example Include="Item2">
          <Color>Red</Color>
      </Example>
  </ItemGroup>

  <Target Name="Build"
      Inputs="@(Example)"
      Outputs="%(Example.Color).txt">

    <Message Text="Inside of Build, color: %(Example.Color)" />
  </Target>  
</Project>

Когда я собираю это из командной строки, результат будет.enter image description here Отсюда видно, что сама цель была выполнена два раза.Это потому, что на цели вы украсили ее Outputs =% (Example.Color) .txt .Когда вы используете % (...) , вы запускаете пакетирование MSBuild.Есть два вида дозирования;целевое пакетирование, пакетное задание.Целевое пакетирование - это то, где целая цель выполняется за пакет (это то, что у вас происходит здесь).Пакетирование задач - это то, где задача выполняется для каждого пакета.

У меня есть другой пример, который в точности соответствует вашему, за исключением того, что я добавил дополнительный оператор Message внутри цели Build.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
  <ItemGroup>
      <Example Include="Item1">
          <Color>Blue</Color>
      </Example>
      <Example Include="Item2">
          <Color>Red</Color>
      </Example>
  </ItemGroup>

  <Target Name="Build"
      Inputs="@(Example)"
      Outputs="%(Example.Color).txt">

    <Message Text="Inside of Build, color: %(Example.Color)" />

    <Error Text="An error occurred during %(Example.Color)" />
    <OnError ExecuteTargets="HandleErrors" />
  </Target>

  <Target Name="HandleErrors">
    <Message Text="Inside of the HandleErrors target" />
    <Message Text="Do some cleanup about %(Example.Color)" Importance="high" />
  </Target>
</Project>

Когда я создаю это, результат будет.enter image description here Исходя из этого, мы видим, что цель Build была выполнена один раз, и произошла ошибка, поэтому она не была выполнена во второй раз, как это было в предыдущем примере, где не было ошибки.После этого сработала цель HandleErrors. Внутри нее она столкнулась с элементом.

<Message Text="Inside of the HandleErrors target" />

И сообщение было отправлено регистраторам (обратите внимание, что оно вызывалось только один раз).После этого он пришел к.

<Message Text="Do some cleanup about %(Example.Color)" Importance="high" />

Теперь это привело к двум операторам сообщения.Это потому, что здесь начали действовать пакетные задачи.Задача вызывается один раз для каждой уникальной партии% (Example.Color), которая имеет красный и синий цвета.Итак, мы знаем, что цель была вызвана только один раз (где произошла первоначальная ошибка), но вы передаете ей весь набор элементов Example.

Если вы хотите узнать, какое значение вызвало ошибку, вы 'Я должен следить за этим в вашей цели сборки.Вы можете просто разместить текущий цвет в свойстве и затем ссылаться на него в своей цели HandleErrors.Например, посмотрите на sample-id-errors.proj ниже.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
  <ItemGroup>
      <Example Include="Item1">
          <Color>Blue</Color>
      </Example>
      <Example Include="Item2">
          <Color>Red</Color>
      </Example>
  </ItemGroup>

  <Target Name="Build"
      Inputs="@(Example)"
      Outputs="%(Example.Color).txt">
    <PropertyGroup>
      <_LastUsedColor>%(Example.Color)</_LastUsedColor>
    </PropertyGroup>

    <Message Text="Inside of Build, color: %(Example.Color)" />

    <Error Text="An error occurred during %(Example.Color)" />
    <OnError ExecuteTargets="HandleErrors" />
  </Target>

  <Target Name="HandleErrors">
    <Message Text="Inside of the HandleErrors target" />
    <Message Text="The color which caused the error was: $(_LastUsedColor)"/>
  </Target>
</Project>

Здесь вы можете видеть, что внутри Build я просто устанавливаю значение для свойства _LastUsedColor, а затем, если происходит ошибка, я просто используюэто же свойство внутри этой цели.Когда я создаю этот файл, я получаю следующие результаты:

enter image description here

Я думаю, это то, что вы пытаетесь достичь.Пакетирование довольно запутанно, если вы не знаете, как оно работает.У меня есть куча ресурсов онлайн о дозировании на http://sedotech.com/resources#Batching.

0 голосов
/ 29 декабря 2011

IIUC, ваши HandleErrors будут отдельно упакованы.

Вы будете использовать задачу Error как условно, так и безоговорочно.В любом случае вы должны иметь возможность использовать задачу MSBuild для вызова HandleErrors и передачи% (Example.Color) в качестве свойства.Что-то вроде:

<MSBuild Targets="HandleErrors" Properties="ErrorColor=%(Example.Color)" />

Другим способом может быть создание свойства в случае ошибки и его использование в целевом объекте HandleErrors.Хотя вышеупомянутый подход будет чище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...