How to invoke the same msbuild target twice with different parameters from within msbuild project file itself

前端 未结 3 1653
时光取名叫无心
时光取名叫无心 2020-12-28 08:04

I have the following piece of msbuild code:

  
    C:\\DirA\\
    C:\\DirB\\
  

        
相关标签:
3条回答
  • 2020-12-28 08:38

    Yes, what you want is called batching in MSBuild. The

    ;%(Dirs.Identity)
    

    Defined in the Outputs will cause this task to be executed for each item in the Dirs ItemGroup.

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="CopyFiles"
       xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
       ToolsVersion="3.5">
    
    <ItemGroup>
        <Dirs Include="C:\DirA" />
        <Dirs Include="C:\DirB" />
    </ItemGroup>
    
    <Target Name="CopyFiles"
        Inputs="@(FilesToCopy);@(Dirs)"
        Outputs="@(FilesToCopy -> '%(Dirs.Identity)%(Filename)%(Extension)');%(Dirs.Identity)" >
        <Message Text="%(Dirs.Identity)" />
    </Target>
    
    </Project>
    

    Outputs:

    Build started 8/19/2009 10:11:57 PM.
    Project "D:\temp\test.proj" on node 0 (default targets).
      C:\DirA
    CopyFiles:
      C:\DirB
    Done Building Project "D:\temp\test.proj" (default targets).
    

    Change the Message task to Copy task with the following condition and you are done:

    Condition="Exists('%(Dirs.Identity)') AND '@(FilesToCopy)' != ''"
    
    0 讨论(0)
  • 2020-12-28 08:54

    You should be able to generate an ItemGroup containing the Dirs and then % on that.

    <ItemGroup>
        <Dirs Include="C:\DirA\;C:\DirB\">
    </ItemGroup>
    <Target Name="CopyFiles"
        Condition="Exists('%(Dirs)') AND '@(FilesToCopy)' != ''"
        Inputs="@(FilesToCopy)"
        Outputs="@(FilesToCopy -> '%(Dirs)%(Filename)%(Extension)')">
        <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="%(Dirs)" />
    </Target>
    

    Or you can do 2 explicit calls:

    <Target Name="CopyFiles">
        <MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="FilesToCopy=@(FilesToCopy);DestDir=$(DirA)" />
        <MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="FilesToCopy=@(FilesToCopy);DestDir=$(DirB)" />
    </Target>
    
    <Target Name="CopyASetOfFiles"
        Condition="Exists('$(DestDir)') AND '@(FilesToCopy)' != ''"
        Inputs="@(FilesToCopy)"
        Outputs="@(FilesToCopy -> '$(DestDir)%(Filename)%(Extension)')">
        <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DestDir)" />
    </Target>
    

    I haven't tested either syntax, but am relatively more confident of the second.

    (The answer, if there is one, is in my Sayed Hashimi book on my desk - you'll have to wait until the first of:

    1. Get the book
    2. I get bored
    3. Sayed finds this post and comes up with a brilliant tested answer)
    0 讨论(0)
  • 2020-12-28 08:57

    As someone already mentiond the answer is batching.

    Here are some links:

    • MSBuild Batching Part 1
    • MSBuild Batching Part 2
    • MSBuild Batching Part 3
    • MSBuild RE: Enforcing the Build Agent in a Team Build
    0 讨论(0)
提交回复
热议问题