Подтвердить что ты не робот

CreateItem vs ItemGroup

В чем разница между созданием элемента внутри цели следующим образом:

<Target Name="DoStuff">
    <CreateItem Include="@(IntermediateAssembly)" >
        <Output TaskParameter="Include" ItemName="FileWrites"/>
    </CreateItem>
</Target>

и вот так:

<Target Name="DoStuff">
    <ItemGroup>
        <FileWrites Include="@(IntermediateAssembly)" />
    </ItemGroup>
</Target>

Когда вы используете тот или иной и почему?

4b9b3361

Ответ 1

В версиях MSBuild до 3.5 вы не могли определить свойства или элементы внутри целей (как в вашем втором примере). Поэтому вместо этого была использована задача (CreateItem и CreateProperty)

Если вы используете ToolsVersion 3.5, вам больше не нужно использовать CreateItem (хотя вы по-прежнему можете, если хотите).

В конце они оба создают элемент тот же, с той же областью. Использование второго синтаксиса более читаемо, и настройка пользовательских метаданных намного проще (на мой взгляд).

ПРИМЕЧАНИЕ. 3.5 версия MSBuild установлена ​​с .NET 3.5. Хотя вам нужно определить ToolsVersion="3.5" в теге Project вашего файла MSBuild, чтобы использовать функции 3.5.

В случае, если вам интересно, я получил большую часть этой информации из книги Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build, которую мне очень понравилось (но я никак не связан с ней).

Ответ 2

CreateItem и CreateProperty устарели в MSBuild 3.5 (хотя они всегда будут продолжать работать, конечно). Было довольно очевидно, что нам нужен такой же знакомый синтаксис для ItemGroup и PropertyGroup для работы внутри целей.

Но ItemGroup внутри цели имеет некоторые дополнительные дополнительные полномочия. Он может изменять элементы: например, это добавит true для всех элементов в списке ресурсов, которые имеют метаданные с именем Primary со значением true; только если метаданных Copy еще нет:

<ItemGroup>
  <Resources Condition=" '%(Primary)' == 'true' ">
    <Copy Condition=" '%(Copy)' == '' ">true</Copy>
  </Resources>
</ItemGroup>

Еще одна магическая сила: теперь вы можете удалить элементы из списка. В этом примере будут удалены все элементы из списка ресурсов, у которых есть метаданные. Тип со значением Bitmap:

<ItemGroup>
  <Resources Condition=" '%(Type)'=='Bitmap' " Remove="@(Resources)"/>
</ItemGroup>

Эти магические силы работают только внутри, а не снаружи.

Для получения полной информации об этом материале я настоятельно рекомендую книгу Sayed Hashimi на MSBuild. Его легко найти на Амазонке.

Дан - команда msbuild.

Ответ 3

Я не думаю, что принятый ответ определил разницу.

Разница заключается в следующем:

  • ItemGroup оценивается при загрузке MSBuild script.
  • CreateItem оценивается при выполнении цели.

Это может привести к различным значениям Item в script.

Возьмем пример задачи, которая делает что-то со всеми файлами, которые соответствуют "*.txt" в каталоге. Если ваш MSBuild script загружен в visual studio, только файлы, которые существовали при запуске VS, будут находиться в Item, если вы используете ItemGroup.

Если вы используете CreateItem - он выполнит поиск всех *.txt файлов, когда цель будет выполнена.

Ответ 4

В качестве дополнительной информации для других, проходящих здесь: Build Engine, который содержит API для создания проектов MSBuild, не поддерживает добавление ItemGroups в новый путь к Target. Здесь вам придется использовать старомодный способ.