Reputation: 2521
Is there a way to get the CopyTask to copy the same file to multiple locations?
eg. I've generated an AssemblyInfo.cs file and want to copy it across to all my projects before building.
Upvotes: 1
Views: 2746
Reputation: 704
I had a need to copy the contents of a directory to multiple locations, this is what I came up with that works. So I am posting it here ins case anyone else is in similar need and comes across this question like I did.
<!-- Create a list of the objects in PublishURL so it will copy to multiple directories -->
<ItemGroup>
<PublishUrls Include="$(PublishUrl)"/>
</ItemGroup>
<PropertyGroup>
<Files>$(OutputPath)\**\*</Files>
</PropertyGroup>
<!-- CopyNewFiles will copy all the files in $(OutputPath) to all the directories in the
in $(PublishUrl). $(PublishUrl) can be a single directory, or a list of directories
separated by a semicolon -->
<Target Name ="CopyNewFiles">
<!-- Get list of all files in the output directory; Cross product this with all
the output directories. -->
<CreateItem Include ="$(Files)"
AdditionalMetadata="RootDirectory=%(PublishUrls.FullPath)">
<Output ItemName ="OutputFiles" TaskParameter ="Include"/>
</CreateItem>
<Message Text="'@(OutputFiles)' -> '%(RootDirectory)\%(RecursiveDir)'"/>
<Copy SourceFiles="@(OutputFiles)"
DestinationFolder ="%(RootDirectory)\%(RecursiveDir)"/>
</Target>
If you want to copy AssemblyInfo.cs
to Folders A
and B
you would set the property Files="AssemblyInfo.cs"
and PublishUrls="A;B"
What makes this work is the extra metadata in the CreateItem task AdditionalMetadata="RootDirectory=%(PublishUrls.FullPath)"
so for each files found in File
it creates 1 entry for each item found in PublishUrls
. In your case of a single file the equivelent in writing out the xml would be:
<ItemGroup>
<OutputFiles Include="AssemblyInfo.cs">
<RootDirectory>A</RootDirectory>
</OutputFiles>
<OutputFiles Include="AssemblyInfo.cs">
<RootDirectory>B</RootDirectory>
</OutputFiles>
</ItemGroup>
Now if you copied the contents of a folder that had files 1.txt
and 2.txt
copied to A
and B
the equivalent xml would be:
<ItemGroup>
<OutputFiles Include="1.txt">
<RootDirectory>A</RootDirectory>
</OutputFiles>
<OutputFiles Include="2.txt">
<RootDirectory>A</RootDirectory>
</OutputFiles>
<OutputFiles Include="1.txt">
<RootDirectory>B</RootDirectory>
</OutputFiles>
<OutputFiles Include="2.txt">
<RootDirectory>B</RootDirectory>
</OutputFiles>
</ItemGroup>
Upvotes: 1
Reputation: 22368
Check out the RoboCopy build task which is part of the Community Build Tasks library which you can find here. RoboCopy can copy one source file to multiple destinations.
On a side note: why don't you use one AssemblyInfo file on solution level and link to that in your projects if you need the same information in every project? Check out my accepted answer on this question: Automatic assembly version number management in VS2008
Upvotes: 2
Reputation: 2521
Right, well maybe I should attempt to do the things I want to do before asking for help :)
<ItemGroup>
<AssemblyInfoSource
Include="AssemblyInfo.cs;AssemblyInfo.cs" />
<AssemblyInfoDestination
Include="$(Destination1)\AssemblyInfo.cs;$(Destination2)\AssemblyInfo.cs" />
</ItemGroup>
<Copy SourceFiles="@(AssemblyInfoSource)" DestinationFiles="@(AssemblyInfoDestination)" />
Upvotes: 2