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>
Когда вы используете тот или иной и почему?
Ответы
Ответ 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. Здесь вам придется использовать старомодный способ.