Msbuild CreateItem与ItemGroup

Msbuild CreateItem与ItemGroup,msbuild,Msbuild,在这样的目标内创建项目有什么区别: <Target Name="DoStuff"> <CreateItem Include="@(IntermediateAssembly)" > <Output TaskParameter="Include" ItemName="FileWrites"/> </CreateItem> </Target> <Target Name="DoStuff">

在这样的目标内创建项目有什么区别:

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

就像这样:

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


何时使用一个或另一个以及原因?

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

如果您使用的是ToolsVersion3.5,那么您就不需要再使用CreateItem了(尽管如果愿意,您仍然可以)

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

注意:MSBuild的3.5版本与.NET 3.5一起安装。尽管您需要在MSBuild文件的
项目
标记中定义
ToolsVersion=“3.5”
,以使用3.5功能


如果你想知道的话,我从微软®构建引擎里面的书[Cord]中得到了大部分信息:使用MSBug和Team Foundation Bug ,我非常喜欢(但是我并没有以任何方式加入)。 区别在于:

  • ItemGroup
    在加载MSBuild脚本时进行计算
  • CreateItem
    在执行目标时进行计算
这可能导致脚本中项目的不同值

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


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

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

但是目标体内的物品组有一些特殊的额外能力。它可以修改项:例如,这会将true添加到资源列表中元数据名为Primary且值为true的所有项中;仅当尚未复制元数据时:

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

真的
另一种魔力:你现在可以从列表中删除项目。此示例将从资源列表中删除元数据类型为值位图的所有项目:

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

这些魔法力量目前只能在内部发挥作用,不能在外部发挥作用

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


Dan--msbuild团队。

作为其他在此传递的信息:包含用于构造msbuild项目的API的生成引擎不支持以新方式向目标添加项组。在这里,您必须使用老式的方法。

询问者表示这两种方法都是从目标内部调用的。从您的回答来看,您似乎在用MSBuild 3.5之前的术语思考。(无法将ItemGroup放置在目标中时)。如果ItemGroup位于目标内部,则其动态性与通过CreateItem声明的一样。(当目标运行时进行评估)(参见微软构建引擎内部的第51页:使用MSBug和Team Foundation Bug)作为参考(或只是尝试一下)。@“CreateItem将通过转换操作在Include中扩展给定给它的通配符" ... 虽然ItemGroup声明不会。是的,那本书很棒,我喜欢:):):)谢谢你的推荐。不过我发现了一个很大的区别:CreateItem将通过转换操作扩展Include中给定的通配符,就像ItemGroup声明不会扩展它一样。