CreateItem vs ItemGroup - PullRequest
       18

CreateItem vs ItemGroup

30 голосов
/ 02 июня 2009

В чем разница между созданием предмета внутри цели, например:

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

и вот так:

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

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

Ответы [ 4 ]

30 голосов
/ 02 июня 2009

В версиях 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, которая мне действительно понравилась (но никак не связана).

17 голосов
/ 27 июня 2009

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

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

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

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

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

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

Для получения полной информации об этом материале я настоятельно рекомендую книгу Сайеда Хашими о MSBuild. Его легко найти на Amazon.

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

8 голосов
/ 05 июня 2009

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

Разница:

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

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

Возьмите пример Задачи, которая делает что-то со всеми файлами, которые соответствуют «* .txt» в каталоге. Если ваш скрипт MSBuild загружен в Visual Studio, в Item, если вы используете ItemGroup, будут только файлы, которые существовали при запуске VS.

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

1 голос
/ 06 марта 2010

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

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