Reputation:
Here are few other similar answers that I've found, but none answers my question:
Copying entire project structure into another directory using afterbuild task
Copy all files and folders using msbuild
What I'm trying to do:
I need to copy a directory tree into several different places in the project upon compilation. Here is how it presently being done:
<ItemGroup>
<MediaFiles Include="$(ProjectDir)media\**\*.*" />
<DeployLabel Include="$(ProjectDir)deploy\x">
<Dir>x</Dir>
</DeployLabel>
<DeployLabel Include="$(ProjectDir)deploy\y">
<Dir>y</Dir>
</DeployLabel>
<DeployLabel Include="$(ProjectDir)deploy\z">
<Dir>z</Dir>
</DeployLabel>
</ItemGroup>
<Target Name="GenericDeploy"
Inputs="@(DeployLabel)"
Outputs="%(Identity).Dummy">
<Message Text="Deploying: @(DeployLabel)" />
<Copy SourceFiles="@(MediaFiles)"
DestinationFiles="@(MediaFiles->'$(ProjectDir)deploy%(Dir)media\%(RecursiveDir)%(Filename)%(Extension)')"/>
This pretends to run, but copies nothing at all. I've tried also to use %(DeployLabel.Dir)
, but that gives me an error.
I don't want to use xcopy
because this program doesn't seem to be in the default inventory of Windows installs (my PC doesn't have it). Also, I must confess, I don't entirely understand what does the %
thingy do. When I saw @ and % at first, I thought they were copied from Make, but now I' starting to doubt... Also some insight into what ->
means would help (it's extremely difficult to find the documentation on these cryptic names).
Upvotes: 1
Views: 917
Reputation: 3075
These batchings are quite confusing, because some combinations of batchings are working with different ItemGroups and some not. I create a small proj to show some differences:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Batch" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<ItemGroup>
<BatchItem Include="myFile.txt">
<Folder>c:\Temp</Folder>
</BatchItem>
<BatchItem Include="myFile2.txt">
<Folder>c:\Tmp</Folder>
</BatchItem>
<DifferentItem Include="myFile3.txt">
<Folder>c:\diff</Folder>
</DifferentItem>
</ItemGroup>
<Target Name="Batch">
<Message Text="Using (at) @(BatchItem) -- @(DifferentItem)" />
<Message Text="Using -> @(BatchItem->'%(Folder)\somethingInbetween\%(Identity)') -- @(DifferentItem->'%(Folder)\somethingInbetween\%(Identity)')" />
<Message Text="Using percent %(BatchItem.Folder)\%(BatchItem.Identity) -- %(DifferentItem.Folder)\%(DifferentItem.Identity)" />
</Target>
</Project>
The third expression is also referencing the metadata of an item, but it is also calling the target for each item in the group. Doing it that way you can't mix ItemGroups.
Using (at) myFile.txt;myFile2.txt -- myFile3.txt
Using -> c:\Temp\somethingInbetween\myFile.txt;c:\Tmp\somethingInbetween\myFi le2.txt -- c:\diff\somethingInbetween\myFile3.txt
Using percent c:\Temp\myFile.txt -- \
Using percent c:\Tmp\myFile2.txt -- \
Using percent \ -- c:\diff\myFile3.txt
Upvotes: 1
Reputation:
OK, I actually solved it somehow, but I'm still interested in answering the "bonus" questions / perhaps my solution isn't good:
I added a PropertyGroup
inside the target and concatenated the path there:
<PropertyGroup>
<Deploydir>$(ProjectDir)deploy\%(DeployLabel.Dir)\media</Deploydir>
</PropertyGroup>
and later in that target I used
DestinationFiles="@(MediaFiles->'$(Deploydir)\%(RecursiveDir)%(Filename)%(Extension)')"
instead, so this avoided the problem with percents (possibly) coming from two different places.
Upvotes: 1