CreateItem vs ItemGroup

时间:2009-06-02 02:29:59

标签: msbuild

在目标中创建项目之间有什么区别:

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

并且像这样:

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

你什么时候使用其中一个?为什么?

4 个答案:

答案 0 :(得分:29)

在3.5之前的MSBuild版本中,您无法定义目标内的属性或项目(如第二个示例中所示)。因此,使用了一个任务(CreateItem和CreateProperty)

如果您使用的是ToolsVersion 3.5,那么您不再需要使用CreateItem(尽管如果您愿意,仍然可以使用)。

最后,他们都创建了相同的项目,具有相同的范围。使用第二种语法更具可读性,设置自定义元数据更容易(在我看来)。

注意:3.5版本的MSBuild随.NET 3.5一起安装。虽然您需要在MSBuild文件的ToolsVersion="3.5"标记中定义Project以使用3.5功能。

如果你想知道,我从书中Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build获得了大部分这些信息,我非常喜欢(但不以任何方式加入)。

答案 1 :(得分:17)

CreateItem和CreateProperty在MSBuild 3.5中已经过时(当然,它总会继续工作)。很明显,我们需要使用相同熟悉的ItemGroup和PropertyGroup语法才能在目标内部工作。

但目标中的ItemGroup具有一些特殊的额外功能。它可以修改项目:例如,这将向Resources列表中的所有项添加true,这些项具有名为Primary的元数据,其值为true;仅当尚未存在复制元数据时:

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

另一个神奇的力量:您现在可以从列表中删除项目。此示例将从“资源”列表中删除具有值为“Bitmap:

”的元数据的所有项目
<ItemGroup>
  <Resources Condition=" '%(Type)'=='Bitmap' " Remove="@(Resources)"/>
</ItemGroup>

这些神奇的力量目前只在内部工作,而不是在外面。

关于这些内容的全部细节,我强烈推荐Sayed Hashimi关于MSBuild的书。它很容易在亚马逊上找到。

Dan - msbuild团队。

答案 2 :(得分:8)

我不认为接受的答案已经定义了差异。

区别在于:

    加载MSBuild脚本时会评估
  • ItemGroup
  • CreateItem在执行目标时进行评估

这可能导致脚本中的Item的值不同。

以一个任务为例,该任务对目录中与“* .txt”匹配的所有文件执行某些操作。如果在Visual Studio中加载了MSBuild脚本,则只有在VS启动时存在的文件才会在Item中使用ItemGroup。

如果您使用CreateItem - 它将在执行目标时搜索所有* .txt文件。

答案 3 :(得分:1)

作为其他人传递的附加信息:包含用于构建MSBuild项目的API的Build-Engine不支持以新方式向Target添加ItemGroup。在这里你将不得不使用老式的方式。