Jon Bates
Jon Bates

Reputation: 3183

Programmatic MSBuild Recursive Copy with wildcards

I am creating an MSBuild v4 task that happens to need to call the Copy task to recursively copy some files (without flattening the directory structure at the destination).

I have come up with:

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();

but am getting an error 'Could not copy C:\source\**\*.foo to c:\dest\* - Illegal characters in path'

There doesn't seem to be much online help for pragmatic invocation, and have drawn a blank. Any ideas?

Thanks

Jon

Upvotes: 6

Views: 4454

Answers (3)

Jon Bates
Jon Bates

Reputation: 3183

It looks like the Copy task doesn't have an intrinsic understanding of recursion; the following code would cause the Copy task to be invoked once per file level, and this is handled by the MSBuild runner.

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

However, since the Copy task seems to treat SourceFiles and DestinationFiles as an associative array (each of type ITaskItem[]), we just performed a recursive descent and built up these two arrays manually, before execing it

Upvotes: 15

madd0
madd0

Reputation: 9323

The problem is that, when writing the same thing in XML, you wouldn't have passed the path with wildcards directly to the SourceFiles property. You would've created an ItemGroup and then you pass that to your task.

As far as I know, it's the ItemGroup does the wildcard magic, so in C# it's up to you to manually create the array of ITaskItem that contains the complete list of items that you want to copy.

If you can, create an ItemGroup that you pass to your task, which in turn passes it to Copy.

Upvotes: 2

Ludwo
Ludwo

Reputation: 6193

You can do it simply using MSBuild Copy task. You don't have to write new task for it.

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

Check all available MSBuild metadata.

Upvotes: 1

Related Questions