在目标中创建项目之间有什么区别:
<Target Name="DoStuff">
<CreateItem Include="@(IntermediateAssembly)" >
<Output TaskParameter="Include" ItemName="FileWrites"/>
</CreateItem>
</Target>
并且像这样:
<Target Name="DoStuff">
<ItemGroup>
<FileWrites Include="@(IntermediateAssembly)" />
</ItemGroup>
</Target>
你什么时候使用其中一个?为什么?
答案 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)
我不认为接受的答案已经定义了差异。
区别在于:
ItemGroup
。CreateItem
在执行目标时进行评估这可能导致脚本中的Item的值不同。
以一个任务为例,该任务对目录中与“* .txt”匹配的所有文件执行某些操作。如果在Visual Studio中加载了MSBuild脚本,则只有在VS启动时存在的文件才会在Item中使用ItemGroup。
如果您使用CreateItem - 它将在执行目标时搜索所有* .txt文件。
答案 3 :(得分:1)
作为其他人传递的附加信息:包含用于构建MSBuild项目的API的Build-Engine不支持以新方式向Target添加ItemGroup。在这里你将不得不使用老式的方式。