msbuild复制到项元数据中定义的多个位置

时间:2013-04-18 05:14:02

标签: msbuild metadata

我有一个项目包含我要复制的元数据以执行某些操作,结果会在多个位置发生, 例如,我想将文件复制到多个位置:

<ItemGroup>
  <MyItem Include="myFile.txt">
   <Out>c:\blah;c:\test</Out>
  </MyItem>
</ItemGroup>

我如何设置目标来创建c:\ blah和c:\ test如果它们不存在,则将myFile.txt复制到c:\ blah \ myFile.txt和c:\ test \ myFile.txt

如果我想在清理期间清理它们,我还想获得完整输出路径列表(c:\ blah \ myFile.txt和c:\ test \ myFile.txt)。

3 个答案:

答案 0 :(得分:1)

如果你不想改变ItemGroup的结构,你需要处理你有一个嵌套的ItemGroup(MetaDataElement Out)。因此,您需要将ItemGroup MyItem批处理到目标,然后您可以批量输出。我做了一个小例子项目:

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="CopyFiles" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
 <ItemGroup>
  <MyItem Include="myFile.txt">
   <Out>c:\blah;c:\test</Out>
  </MyItem>
  <MyItem Include="myFile2.txt">
   <Out>c:\blah2;c:\test2</Out>
  </MyItem>
 </ItemGroup>

 <Target Name="CopyFiles"
      Inputs="%(MyItem.Identity)"
      Outputs="%(MyItem.Identity)\ignore_this.msg">

  <PropertyGroup>
   <File>%(MyItem.Identity)</File>
  </PropertyGroup>

  <ItemGroup>
   <Folders Include="%(MyItem.Out)" />
  </ItemGroup>

  <Message Text="%(Folders.Identity)\$(File)" />    
 </Target>
</Project> 

输出将是:

Project "D:\TEMP\test.proj" on node 1 (default targets).
CopyFiles:
c:\blah\myFile.txt
c:\test\myFile.txt
CopyFiles:
c:\blah2\myFile2.txt
c:\test2\myFile2.txt
Done Building Project "D:\TEMP\test.proj" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)

答案 1 :(得分:0)

您想要做的是一个名为MSBuild Batching的概念。 它允许您将项目列表分成不同的批次,并将每个批次分别传递给任务。

<Target Name="CopyFiles">
    <ItemGroup Label="MyFolders">
    <Folder Include="c:\blah" />
    <Folder Include="C:\test" />
</ItemGroup>
    <Copy SourceFiles="myFile.txt" DestinationFolder="%(Folder.Identity)\">
        <Output TaskParameter="CopiedFiles" ItemName="FilesCopy" />
    </Copy>
</Target>

答案 2 :(得分:0)

这个怎么样:

<Target Name="CopyFiles">

    <!--The item(s)--> 
    <ItemGroup>
      <MyItem Include="myFile.txt"/>
    </ItemGroup>

    <!--The destinations--> 
    <ItemGroup>
      <MyDestination Include="c:\blah"/>
      <MyDestination Include="c:\test"/>
    </ItemGroup>

    <!--The copy--> 
    <Copy SourceFiles="@(MyItem)" DestinationFolder="%(MyDestination.FullPath)" />
    <ItemGroup>
      <FileWrites Include="%(MyDestination.FullPath)\*" />
    </ItemGroup>

    <!--The output -->
    <Message Text="FileWrites: @(FileWrites)" Importance="high"/>

</Target>