【问题标题】:Synchronize two folders using MSBUILD使用 MSBUILD 同步两个文件夹
【发布时间】:2011-09-15 08:10:55
【问题描述】:

我想知道如何使用 MSBuild 同步两个文件夹,包括子文件夹。

我喜欢做的是

a) 将所有较新的文件从源文件夹复制到目标文件夹 或者在dest文件夹中不存在

和

b) 删除 dest 文件夹中不存在(不再存在)的所有文件 源文件夹

a) 使用 <Copy> 任务非常容易,但我怎样才能完成 b)?

这是我目前的构建文件:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
    ToolsVersion="4.0" 
    DefaultTargets="Backup">
    <PropertyGroup>
        <SourceFolder>C:\source</SourceFolder>
        <DestFolder>C:\dest</DestFolder>
    </PropertyGroup>
    <ItemGroup>
        <FilesToCopy Include="$(SourceFolder)\**" />
    </ItemGroup>
    <Target Name="Backup">
        <!-- copy all files from the source folder to the dest folder 
            that are newer or don't exist in the dest folder -->
        <Copy 
            SourceFiles="@(FilesToCopy)" 
            DestinationFiles="@(FilesToCopy->'$(DestFolder)\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="True" />
        <!-- TODO: remove all files from the dest folder 
            that don't exist in the source folder -->
    </Target>
</Project>

【问题讨论】:

    标签: msbuild


    【解决方案1】:

    您可以使用来自MSBuild Extension pack 的GetDistinctItems 任务来完成。 基本思想是从源文件夹和目标文件夹中获取文件之间的不同项目。

    <Project ToolsVersion="3.5" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks" />
    
      <PropertyGroup>
        <SourceFolder>C:\source</SourceFolder>
        <DestFolder>C:\dest</DestFolder>
      </PropertyGroup>
    
      <ItemGroup>
        <FilesToCopy Include="$(SourceFolder)\**" />
      </ItemGroup>
    
      <Target Name="Backup">
        <!-- copy all files from the source folder to the dest folder 
                      that are newer or don't exist in the dest folder -->
        <Copy SourceFiles="@(FilesToCopy)" 
              DestinationFiles="@(FilesToCopy->'$(DestFolder)\%(RecursiveDir)%(Filename)%(Extension)')" 
              SkipUnchangedFiles="True" />
    
        <!-- Remove all files from the dest folder 
                that don't exist in the source folder -->
        <ItemGroup>
          <DestFiles Include="$(DestFolder)\**"/>
        </ItemGroup>
    
        <!-- Cannot compare FilesToCopy with DestFiles directly, 
             root folders are different-->
        <ItemGroup>
          <SrcFilesLeave Include="%(FilesToCopy.RecursiveDir)%(FilesToCopy.Filename)%(FilesToCopy.Extension)"/>
          <DestFilesLeave Include="%(DestFiles.RecursiveDir)%(DestFiles.Filename)%(DestFiles.Extension)"/>
        </ItemGroup>
    
        <MSBuild.ExtensionPack.Framework.MsBuildHelper TaskAction="GetDistinctItems" 
                                                       InputItems1="@(SrcFilesLeave)" 
                                                       InputItems2="@(DestFilesLeave)">
          <Output TaskParameter="OutputItems" ItemName="Distinct"/>
        </MSBuild.ExtensionPack.Framework.MsBuildHelper>
    
        <Message Text="Distinct %(Distinct.Identity)"/>
        <Delete Files="$(DestFolder)\%(Distinct.Identity)" />
      </Target>
    
    </Project>
    

    【讨论】:

    • 效果很好!我安装了 MSBuild-Extensions 并将&lt;Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks" /&gt; 添加到构建文件中
    【解决方案2】:

    万一有人不想或无法安装扩展包

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
        ToolsVersion="4.0" 
        DefaultTargets="Backup">
        <PropertyGroup>
            <SourceFolder>C:\source</SourceFolder>
            <DestFolder>C:\dest</DestFolder>
        </PropertyGroup>
        <ItemGroup>
            <FilesToCopy Include="$(SourceFolder)\**" />
        </ItemGroup>
        <Target Name="Backup">
            <!-- copy all files from the source folder to the dest folder 
                that are newer or don't exist in the dest folder -->
            <Copy 
                SourceFiles="@(FilesToCopy)" 
                DestinationFiles="@(FilesToCopy->'$(DestFolder)\%(RecursiveDir)%Filename)%(Extension)')" 
                SkipUnchangedFiles="True">
                <Output TaskParameter="CopiedFiles" ItemName="Copied"/>
             </Copy>
             <ItemGroup>
                <OutdatedFiles Include="$(DestFolder)\**" Exclude="@(Copied)"/>
             </ItemGroup>
             <Delete Files="@(OutdatedFiles)"/>
        </Target>
    </Project>
    

    【讨论】:

    • 我知道这是一个非常古老的线程,但只是为人们找到这个解决方案的一些额外信息(我确信我在其他地方找到了这个或非常相似的)。请注意,这种方法会在目标文件夹中留下空目录,因为“删除”任务只会删除文件。
    【解决方案3】:

    您可以使用 MSBuild 中的 MSDeploy 实用程序来同步两个文件夹,如下所示:

    <Target Name="SynchronyzeFolders">
      <PropertyGroup>
        <_MSDeploySrc>contentPath=C:\inetpub\Dir1\</_MSDeploySrc>
        <_MSDeployDest>contentPath=C:\inetpub\Dir2\,computerName='https://$(RemoteComputerName):8172/MSDeploy.axd',userName='$(MSDeployUsername)',password='$(MSDeployPassword)',authtype='$(MSDeployAuth)'</_MSDeployDest>
        <_MSDeployParameters>-verb:$(MSDeployVerb) -source:$(_MSDeploySrc) -dest:$(_MSDeployDest) $(MSDeployAdditionalParams)</_MSDeployParameters>
      </PropertyGroup>
    
      <Exec Command="msdeploy $(_MSDeployParameters)"
            CustomErrorRegularExpression="ERROR"/>
    

    文件夹可以在同一台计算机上,也可以在不同的计算机上。文件夹的路径可以包含本地和网络路径。等等。您可以同步 IIS 网站和文件夹。只需使用不同的 MSDeploy 提供程序:http://technet.microsoft.com/en-us/library/dd569040(v=ws.10).aspx 配置 Web 部署处理程序的帮助:http://www.iis.net/learn/publish/using-web-deploy/configure-the-web-deployment-handler

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-17
      • 1970-01-01
      • 2019-07-08
      • 2020-02-11
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多