如何使用MSBuild复制任务复制到多个目标文件夹? [英] How can I use MSBuild Copy Task to Copy To Multiple Destination Folders?

查看:88
本文介绍了如何使用MSBuild复制任务复制到多个目标文件夹?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用MSBuild的复制"任务将文件夹递归复制到多个目标文件夹.我已经看到了以下问题,这为我提供了一个良好的开端,但我必须缺少一些东西:

I'm trying to copy a folder recursively to multiple destination folders using MSBuild's Copy task. I've seen the following question which gave me a good start, but I must be missing something:

将Msbuild复制到基于目标参数列表?

我的构建文件中的一个片段如下:

A snippet from my build file is below:

<ItemGroup>
    <DeployPath Include="\\server1\path" />
    <DeployPath Include="\\server2\path" />
</Item Group>

<Target Name="Deploy">
    <Message Text="%(DeployPath.Identity)" />
    <Copy SourceFiles="@(ItemsToCopy)" DestinationFolder="%(DeployPath.Identity)\%(RecursiveDir)" />
</Target>

运行此命令时,正如我期望的那样,消息"任务吐出两行:

When I run this, the "Message" task, as I would expect, spits out 2 lines:

\\server1\path
\\server2\path

问题是,复制"任务似乎只运行一次,并将文件复制到当前硬盘驱动器的根目录,而不是指定的网络路径:

The problem is, the "Copy" task appears to only run once, and copies the files to the root of the current hard drive and not the specified network paths:

复制到C:\file1.txt而不是\\server1\path\file1.txt

我是MSBuild的新手,所以我觉得这里缺少一些基本的东西.

I'm fairly new to MSBuild, so I feel like I'm missing something pretty basic here.

任何帮助将不胜感激.

推荐答案

此处要处理的内容称为批处理.我在博客上写了很多关于批处理的文章.您可以在 http://sedotech.com/Resources#Batching 上找到我的博客.批处理是一种无需在MSBuild中真正执行循环即可进行循环的方法.您可以将组划分为具有通用元数据值的值.元数据可以是Identity,FullPath,Filename等值.您甚至可以创建自己的元数据.无论如何,当您对多个值进行批处理时,它们将彼此独立地进行批处理.看一下我创建的示例.执行目标的结果显示在脚本之后.

What you are dealing with here is known as batching. I have blogged quite a bit about batching. You can find my blogs listed at http://sedotech.com/Resources#Batching. Batching is a way to do a loop without really doing one in MSBuild. You can split groups into values with a common metadata value. Metadata could be values like Identity, FullPath, Filename, etc. You can even make your own metadata. In any case when you batch on more than 1 value they are batched independently of each other. Take a look at the example that I created. The result of executing the target is shown after the script.

<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.

这篇关于如何使用MSBuild复制任务复制到多个目标文件夹?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆