使用通配符的程序化MSBuild递归复制

时间:2011-11-29 10:35:20

标签: c# msbuild

我正在创建一个MSBuild v4任务,恰好需要调用Copy任务来递归复制一些文件(不会在目的地展平目录结构)。

我想出了:

var copy = new Microsoft.Build.Tasks.Copy
{
    BuildEngine = this.BuildEngine,
    SourceFiles = new ITaskItem[] { new TaskItem(@"C:\source\**\*.foo") },
    DestinationFolder = new TaskItem(@"c:\dest\\")
};
copy.Execute();

但是收到错误'无法将C:\ source \ ** \ * .foo复制到c:\ dest \ * - 路径中的非法字符'

对于实用调用似乎没有太多的在线帮助,并且已经画了一个空白。有什么想法吗?

由于

乔恩

3 个答案:

答案 0 :(得分:11)

看起来复制任务对递归没有内在的理解;以下代码将导致每个文件级别调用一次Copy任务,这由MSBuild运行程序处理。

<ItemGroup>
  <x Include="c:\source\**\*.foo" />
</ItemGroup>
<Copy SourceFiles="@(x)" DestinationFolder="c:\dest\%(RecursiveDir)" />

但是,由于Copy任务似乎将SourceFiles和DestinationFiles视为一个关联数组(每个类型ITaskItem []),我们只是执行递归下降并在执行之前手动构建这两个数组

答案 1 :(得分:2)

问题是,在XML中编写相同内容时,您不会将带有通配符的路径直接传递给SourceFiles属性。您将创建一个ItemGroup然后,然后将其传递给您的任务。

据我所知,ItemGroup是通配符魔术,所以在C#中你需要手动创建ITaskItem数组,其中包含你想要的完整项目列表副本。

如果可以,请创建一个传递给您的任务的ItemGroup,然后将其传递给Copy

答案 2 :(得分:1)

您只需使用MSBuild Copy任务即可。您不必为它编写新任务。

<Copy SourceFiles="@(SourceFiles)"
      DestinationFiles="$(DestinationFolder)\%(RecursiveDir)%(Filename)%(Extension)"
      ContinueOnError="false"/>

选中所有可用的MSBuild metadata