Синхронизировать две папки с помощью MSBUILD - PullRequest
6 голосов
/ 15 сентября 2011

Интересно, как синхронизировать две папки, включая подпапки, с помощью MSBuild.

Что мне нравится делать, так это

a) копировать все файлы из исходной папки в папку dest, которые более новые.или не существует в папке dest

и

b), чтобы удалить все файлы из папки dest, которые больше не существуют в исходной папке

а) довольно просто использовать задачу <Copy>, но как мне выполнить б)?

Пока это мой файл сборки:

<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>

Ответы [ 3 ]

4 голосов
/ 15 сентября 2011

Вы можете сделать это с помощью задачи GetDistinctItems из MSBuild Extension pack . Основная идея состоит в том, чтобы получить отдельные элементы между файлами из исходной и целевой папки.

<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>
2 голосов
/ 26 ноября 2015

Если кто-то не хочет или не может установить пакет расширения

<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>
1 голос
/ 23 января 2013

Вы можете использовать утилиту MSDeploy в MSBuild для синхронизации двух папок, например:

<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 Справка по настройке обработчика веб-развертывания: http://www.iis.net/learn/publish/using-web-deploy/configure-the-web-deployment-handler

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...