tags:

views:

27

answers:

2

Let's say I have a list of sub paths such as

 <PropertyGroup>
   <subPaths>$(path1)\**\*; $(path2)\**\*; $(path3)\file3.txt; </subPaths>
</PropertyGroup>

I want to copy these files from folder A to folder B (surely we already have all the sub folders/files in A). What I try was:

<Target Name="Replace" DependsOnTargets="Replace_Init; Replace_Copy1Path">
</Target>

<Target Name="Replace_Init">
  <PropertyGroup>
    <subPaths>$(path1)\**\*; $(path2)\**\*; $(path3)\file3.txt; </subPaths>
  </PropertyGroup>
  <ItemGroup>
    <subPathItems Include="$(subPathFiles.Split(';'))" />
  </ItemGroup>
</Target>

<Target Name="Replace_Copy1Path" Outputs="%(subPathItems.Identity)">
  <PropertyGroup>
    <src>$(folderA)\%(subPathItems.Identity)</src>
    <dest>$(folderB)\%(subPathItems.Identity)</dest>
  </PropertyGroup>
  <Copy SourceFiles="$(src)" DestinationFiles="$(dest)" />
</Target>

But the Copy task didn't work. It doesn't translate the **\* to files. What did I do wrong? Please help!

+1  A: 

I don't think you can do something like that.

$(subPathFiles.Split(';')) returns a property where value are separated by semicolon, so this call is useless.

If you want to keep this mechanism you should use the task StringToItemCol from MSBuild Extension Pack :

<Target Name="Replace_Init">
  <PropertyGroup>
    <subPaths>$(path1)\**\*; $(path2)\**\*; $(path3)\file3.txt; </subPaths>
  </PropertyGroup>

  <MsBuildHelper TaskAction="StringToItemCol" 
                 ItemString="$(subPaths)" Separator=";">
    <Output TaskParameter="OutputItems" ItemName="subPathItems "/>
  </MsBuildHelper>
</Target>

Otherwise, you could directly pass items with folderA and subPaths embedded :

<ItemGroup>
  <subPathIt Include="$(folderA)\$(path1)\**\*"/>
  <subPathIt Include="$(folderA)\$(path2)\**\*"/>
  <subPathIt Include="$(folderA)\$(path3)\file3.txt" Condition="Exists('$(path3)\file3.txt')"/>
</ItemGroup>


<Target Name="Replace_Copy1Path">
  <Copy SourceFiles="@(subPathItems )" 
        DestinationFiles="$(folderB)\%(RecursiveDir)\%(Filename)%(Extension)" />
</Target>
madgnome
Dear madgnome. I'm waiting to hear from your reply to my question below.
Nam Gi VU
You could use semicolon inside an item definition to separate multiple item lists. Does that answer your question?
madgnome
A: 

Thanks madgnome! But as you said, if we do

<ItemGroup>
  <files Include="$(folderA)\**\*; $(folderB)\**\*"/>
</ItemGroup>

, we won't have @files which contains all files in folderA and folderB, right?

Nam Gi VU
You reply to Madgnome or can update your question with those details.
ydobonmai
Right. You have to write two separate <files Include="$(folderX)...">
madgnome
Dear madgnome, I don't think so. I've just double checked and see that if I declare like above, all files are recursively added into files. So strange!
Nam Gi VU
My bad, semicolon can be used inside item includes to separate multiple item lists.
madgnome