构建脚本以将文件从各种源文件夹复制到各种目标文件夹

时间:2018-11-29 17:28:18

标签: msbuild build-process robocopy xcopy build-script

基本要求是将不同解决方案/项目目录中的各种文件和文件夹复制到单个build_output文件夹(/子文件夹)中。

当前,我正在使用Robocopy命令来执行此操作。唯一的问题是我的脚本太长,仅使用多个Robocopy命令。

<Copy SourceFiles="$(Docs)\Manual.pdf" DestinationFolder="$(BuildPath)\Help"/>
<RoboCopy Source="$(Web1)" Destination="$(BuildPath)" Files="*.aspx" Options="/E"/>
<RoboCopy Source="$(Web1)\Images" Destination="$(BuildPath)\Images" Files="*.jpg;*.png" Options="/E"/>
<RoboCopy Source="$(Web2)\Images" Destination="$(BuildPath)\Images" Files="*.jpg;*.png" Options="/E"/>
<!--- 100s of such RoboCopy & Copy commands (note that in last two commands i need to copy from different sources to same destination -->
  1. 如何在实际的企业应用程序中实施此工作,以便 构建脚本简洁明了。
  2. 我下面的想法是解决问题的方法。如果是,任何人都可以使用MSBuild或CommandScript为我提供示例步骤。 (免费使用任何MSBuild扩展)
    • 定义所有源文件夹,文件类型(可以是xyz.png / .png / 。*)和目标路径的映射。
    • 使用单个目标或任务使用上述映射复制文件(自动复制)
  3. 还有其他更好的方法来解决此问题吗?

见解/解决方案

2 个答案:

答案 0 :(得分:1)

我确实做了这种事情,以便分阶段输出构建,以供安装程序构建收集。我有一个用于一致处理的自定义目标文件,还有一些msbuild属性文件,其中包含需要完成的项目组。

  <ItemGroup Label="AcmeComponent1Payload">
    <FileToHarvest Include="$(SourceRoot)AcmeProjects\ServerManager\$(Configuration)\**\*;
                            $(SourceRoot)Library\SQLServerCompact\**\*;
                            $(SourceRoot)Utility Projects\PropertyDataValidator\PropertyDataValidator\bin\$(Configuration)\PropertyDataValidator.*"
                   Exclude="$(SourceRoot)Server Manager Projects\AcmeServerManager\$(Configuration)\IntegrationTests.*;
                            $(SourceRoot)Server Manager Projects\AcmeServerManager\$(Configuration)\**\Microsoft.Practices.*.xml;
                            $(SourceRoot)Server Manager Projects\AcmeServerManager\$(Configuration)\obj\**\*;
                            $(SourceRoot)Server Manager Projects\AcmeServerManager\$(Configuration)\**\Microsoft.VisualStudio.*;
                            $(SourceRoot)Server Manager Projects\AcmeServerManager\$(Configuration)\**\Microsoft.Web.*;
                            $(SourceRoot)Utility Projects\PropertyDataValidator\PropertyDataValidator\bin\$(Configuration)\PropertyDataValidator.xml">
      <Group>AcmeServerManager</Group>
      <SubDir>Utilities\</SubDir>
    </FileToHarvest>
  </ItemGroup>

自定义目标文件具有处理该文件的功能。

  <Target Name="CopyFiles">
    <Copy Condition="@(FileToHarvest)!=''"
          SourceFiles="@(FileToHarvest)"
          DestinationFiles="@(FileToHarvest->'$(OutputPath)\%(Group)\%(SubDir)%(RecursiveDir)%(Filename)%(Extension)')"
          OverwriteReadOnlyFiles="true"
          SkipUnchangedFiles="true" />
  </Target>

您可以根据需要使属性文件简单或复杂。我使用多个,然后使用通配符将它们导入到项目文件中。

答案 1 :(得分:0)

感谢@daughey,我的第一部分工作了,我需要从不同的源复制到相同的目的地。

<!--Declare an ItemGroup that points to source Locations-->
  <ItemGroup>
    <ItemToCopy Include="$(Web1)\Audit"/>
    <ItemToCopy Include="$(Utilities)\Service"/>
    <ItemToCopy Include="$(Web1)\NET"/>
  </ItemGroup>

  <!--Declare an ItemGroup that points to destination Locations-->
  <ItemGroup>
    <DestLocations Include="$(BuildPath)" />
  </ItemGroup>

  <Target Name="CopyFiles">
    <!-- Run the copy command to copy the item to your dest locations-->
    <!-- The % sign says to use Batching. So Copy will be run for each unique source ItemToCopy(s) in the DestLocation.-->
    <RemoveDir Directories="$(BuildPath)"/>
    <Message Importance="high" Text="Deploy folder is $(BuildPath)"/>
    <RoboCopy Source="%(ItemToCopy.FullPath)" Destination="$(BuildPath)" Files="*.dll"/>
  </Target>

在为任务批处理处理项目元数据后,第二部分也很好用。 方案:将文件从源目录列表复制到各自子文件夹中的输出目录

  • $(Web1)\ Audit * .dll => $(BuildPath)\ Audit * .dll

  • $(实用程序)\ Service * .jpg => $(BuildPath)\ Utilities \ Service * .jpg

解决方案

<!--Modify an ItemGroup with metadata-->
<ItemGroup>
    <ItemToCopy Include="$(Web1)\Audit">
        <ToPath>$(BuildPath)\Audit</ToPath>
        <FileType>*.dll</FileType>
    </ItemToCopy>
    <ItemToCopy Include="$(Utilities)\Service">
        <ToPath>$(BuildPath)\Utilities\Service</ToPath>
        <FileType>*.jpg;*.bmp</FileType>
    </ItemToCopy>
</ItemGroup>

<Target Name="CopyBatch">
    <RoboCopy Source="%(ItemToCopy.Identity)" Destination="%(ItemToCopy.ToPath)" Files="%(ItemToCopy.Filetype)"/>
</Target>