【问题标题】:Msbuild copy to several locations based on list of destination parameter?Msbuild 根据目标参数列表复制到多个位置?
【发布时间】:2023-03-26 17:56:01
【问题描述】:

我有一个想要复制到多个位置的目录。

说我有

  • home.aspx

我想复制到

  • abc/home.aspx
  • def/home.aspx
  • ghi/home.aspx

我有两个问题:

  • 如何定义列表 abc、def、ghi?
  • 如何使用此列表的每个元素执行复制任务?

【问题讨论】:

    标签: msbuild copy msbuild-task msbuild-propertygroup


    【解决方案1】:

    这是我整理的一个实际示例,它显示了您正在寻找的内容:

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Test" ToolsVersion="3.5">
    
      <!--Declare an ItemGroup that points to your file you want to copy.-->
      <ItemGroup>
        <ItemToCopy Include=".\Home.aspx" />
      </ItemGroup>
    
      <!--Declare an ItemGroup that points to your destination Locations-->
      <ItemGroup>
        <DestLocations Include=".\abc\home.aspx" />
        <DestLocations Include=".\def\home.aspx" />
        <DestLocations Include=".\ghi\home.aspx" />
      </ItemGroup>
    
      <Target Name="CopyFiles">
        <!--Run the copy command to copy the item to your dest locations-->
        <!--This is where the magic happens.  The % sign before the DestLocations reference says to use
        Batching.  So Copy will be run for each unique FullPath MetaData in the DestLocations ItemGroup.-->
        <Copy SourceFiles="@(ItemToCopy)" DestinationFolder="%(DestLocations.FullPath)" />
      </Target>
    </Project>
    

    【讨论】:

    • 太棒了。谢谢,cmets说得很清楚。我知道如果我说我不想成为 MSBuild 大师,而只是在这里解决我的问题,我可能听起来有点肤浅。我注意到,通过逐案使用技术,在学习曲线的这一点上,你有足够的分散知识,从头开始全面学习要容易得多,而且一切都到位。我发现这通常是更可取的学习方式。
    • 如果您现在不需要全部了解,那也可以。我修复了示例中的一个错误(对此感到抱歉)。您需要调用目标中的任何任务(如复制)。我把它放在一个目标上。您使用该目标名称 (CopyFiles) 调用 MSBuild,它将运行目标。
    【解决方案2】:

    您应该感兴趣的概念称为Batching

    我已经在我的博客 http://www.sedodream.com/PermaLink,guid,5f1e0445-ce3d-4052-ba80-42fd19512d42.aspx 上介绍了这个确切的场景

    这是该博客条目的文本,您可以在上面的链接中下载提到的文件。


    今天有人告诉我,一位同事遇到了 MSBuild 问题。他告诉我他正试图将一组文件复制到一组不同的服务器上。但问题是他不知道如何在不执行多次复制任务调用的情况下实现这一点。我告诉他,他可以使用 MSBuild Batching 实现这一目标。批处理是一次对一组项目(批次)执行任务(或目标)的过程。一个批次还可以包括单个项目。所以在这种情况下,我们需要为他想要部署到的每台服务器执行一次复制。我创建了一个简单的 msbuild 文件,它以两种不同的方式演示了这一点。第一种方式使用任务批处理,可以在 Test 目标中看到。另一个使用目标批处理,可以在 DoItCore 目标中看到。我还创建了一个干净的目标,它与批处理无关。

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Test">
    
          <ItemGroup>
                <SourceFiles Include="*.txt"/>
                <Dest Include="One;Two;Three;Four;Five"/>
          </ItemGroup>
    
          <Target Name="Test">
                <Copy SourceFiles ="@(SourceFiles)" DestinationFolder="%(Dest.FullPath)"/>
                <Message Text="Fullpath: %(Dest.FullPath)"/>
          </Target>
    
    
          <!-- These targets demonstrate target batching -->
          <Target Name="DoIt" DependsOnTargets="DoItCore"/>
          <Target Name="DoItCore" Inputs="@(SourceFiles)" Outputs="%(Dest.FullPath)">
                <Copy SourceFiles="@(SourceFiles)" DestinationFolder="%(Dest.FullPath)"/>
          </Target>
    
    
          <!-- This will clean up the files -->
          <Target Name="Clean">
                <CreateItem Include="%(Dest.FullPath)\**\*">
                      <Output ItemName="FilesToDelete" TaskParameter="Include"/>
                </CreateItem>
                <Delete Files="@(FilesToDelete)"/>
          </Target>
    </Project>
    

    批处理是 MSBuild 的一个高级主题,肯定会被忽略。我不得不承认我自己没有写足够的东西而感到内疚。有一些很好的批处理资源,它们在下面列出。


    这是我发布的其他一些与批处理相关的博客条目。

    谢谢, 赛义德·易卜拉欣·哈希米

    我的书:Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build

    【讨论】:

    • 如果我理解用';'分隔它们的约定使参数成为列表而不是单个项目。我会在下班后检查一下。谢谢
    【解决方案3】:

    您最好自己将其作为一种学习练习,而不是将 MSBUILD 视为一个魔术盒。 This article from Patrick Smacchia 为您提供了大部分相关技术。

    【讨论】:

    • 我实际上是在尝试通过自动执行直到今天我一直手动执行的几项任务来熟悉 MSBuild。我已经阅读了几篇与您所指的教程相似的教程(似乎是大量的复制粘贴)。通过这样做,我试图让自己熟悉语法和内置的可能性。您能否详细说明一下我是如何将其视为魔术盒的,以及您所引用的文章如何启发我?
    • 嗨,鲍里斯,我不是说“把它当作黑匣子对待”,因为你很懒惰。我主要是在回想我学习 msbuild 的时间 - 我曾经尝试一次了解一项任务,但不是整体情况。我真的发现 Smacchia 的文章是我希望在我得到它之前有一周的东西 - 作为 NDepend 的作者,他不是剪切和粘贴商人。在定义列表方面,我想 [xml list] 属性将适用于列表,然后您将使用带有列表循环/通配符工具的 Copy 任务来遍历列表。我自己没有做过 - 否则会粘贴样本。
    • 感谢您的回复。我会再仔细看看这篇文章。
    【解决方案4】:

    有一个项目组,您可以在其中构建此目的地列表(“abc...等)。然后使用此列表(@Destination)调用复制任务。

    如果您搜索它,我相信您会找到很多示例。 http://keithhill.spaces.live.com/?_c11_BlogPart_BlogPart=blogview&_c=BlogPart&partqs=cat%3dMSBuild

    【讨论】:

      猜你喜欢
      • 2016-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      相关资源
      最近更新 更多