您在这里处理的是批处理。我在博客上写了很多关于批处理的东西。你可以在以下网址找到我的博客
http://sedotech.com/Resources#Batching
. 批处理是一种在MSBuild中执行循环而不真正执行循环的方法。可以将组拆分为具有公共元数据值的值。元数据可以是Identity、FullPath、Filename等值。您甚至可以创建自己的元数据。在任何情况下,当你批量处理超过一个值时,它们是相互独立的批处理。看看我创建的示例。执行目标的结果显示在脚本之后。
<Project ToolsVersion="4.0" DefaultTargets="Demo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ItemsToCopy Include="src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt"/>
</ItemGroup>
<ItemGroup>
<DeployPath Include="C:\temp\path01\" />
<DeployPath Include="C:\temp\path02\" />
</ItemGroup>
<!--
Target batching is happening here because there is a
%() expression inside the Outputs attribute. So that
means that this target will be repeated once per
uinque batch of %(DeployPath.Identity). Identity is
the value that is passed in the Incude= attribute.
Since we know there are two values we know that
this target will be executed twice, and on each
pass the DeployPath item will only look to contain
a single value. If there were duplicates then the list
could contain more than 1 value.
-->
<Target Name="Demo" Outputs="%(DeployPath.Identity)">
<Message Text="DeployPath.Identity: %(DeployPath.Identity)" />
<Message Text="======================================" Importance="high"/>
<Message Text="ItemsToCopy1: @(ItemsToCopy)|| DeployPath.Identity: %(DeployPath.Identity)" />
<Message Text="======================================" Importance="high"/>
<!--
In the next emample you are batching on both the DeployPath item list as well as
the ItemsToCopy item. When two batched items are in the same expression they are
matched individually, so you ge a value for DeployPath metadata but not ItemsToCopy
metadata. That is why your copy only copied to one location.
-->
<Message Text="ItemsToCopy2: @(ItemsToCopy)|| DeployPath.Identity-RecursiveDir: %(DeployPath.Identity)\%(RecursiveDir)" />
<Message Text="======================================" Importance="high"/>
<!--
In this example I create a property and assign it the value of
%(DeployPath.Identity). We know there will only be one such
value. Because there should only be one value with Identity
when this target is executed so it is safe to
convert item to property
Because we are not batching on both items we will get the values for both vaules
to be correct becuase the target is repeated for the other
DeployPath values.
-->
<PropertyGroup>
<_DeployPathIdentity>%(DeployPath.Identity)</_DeployPathIdentity>
</PropertyGroup>
<Message Text="ItemsToCopy3: @(ItemsToCopy)|| _DeployPathIdentity-RecursiveDir: $(_DeployPathIdentity)\%(RecursiveDir)" />
<!--
I've always preferred to use DestinationFiles so my sample
below uses that. But you could change the target to use
DestinationFolder instead.
-->
<Copy SourceFiles="@(ItemsToCopy)"
DestinationFiles="@(ItemsToCopy->'$(_DeployPathIdentity)%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
</Project>
输出
Build started 9/10/2010 9:31:28 PM.
Project "I:\Development\My Code\Community\MSBuild\CopyFiles01.proj" on node 1 (default targets).
Demo:
DeployPath.Identity: C:\temp\path01\
======================================
ItemsToCopy1: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| DeployPath.I
dentity: C:\temp\path01\
======================================
ItemsToCopy2: || DeployPath.Identity-RecursiveDir: C:\temp\path01\\
ItemsToCopy2: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| DeployPath.I
dentity-RecursiveDir: \
======================================
ItemsToCopy3: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| _DeployPathI
dentity-RecursiveDir: C:\temp\path01\\
Creating directory "C:\temp\path01".
Copying file from "src\0001.txt" to "C:\temp\path01\0001.txt".
Copying file from "src\0002.txt" to "C:\temp\path01\0002.txt".
Copying file from "src\sub\sub-0001.txt" to "C:\temp\path01\sub-0001.txt".
Copying file from "src\sub\sub-0002.txt" to "C:\temp\path01\sub-0002.txt".
Demo:
DeployPath.Identity: C:\temp\path02\
======================================
ItemsToCopy1: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| DeployPath.I
dentity: C:\temp\path02\
======================================
ItemsToCopy2: || DeployPath.Identity-RecursiveDir: C:\temp\path02\\
ItemsToCopy2: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| DeployPath.I
dentity-RecursiveDir: \
======================================
ItemsToCopy3: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| _DeployPathI
dentity-RecursiveDir: C:\temp\path02\\
Creating directory "C:\temp\path02".
Copying file from "src\0001.txt" to "C:\temp\path02\0001.txt".
Copying file from "src\0002.txt" to "C:\temp\path02\0002.txt".
Copying file from "src\sub\sub-0001.txt" to "C:\temp\path02\sub-0001.txt".
Copying file from "src\sub\sub-0002.txt" to "C:\temp\path02\sub-0002.txt".
Done Building Project "I:\Development\My Code\Community\MSBuild\CopyFiles01.proj" (default targets
).
Build succeeded.