Sync two folders using MSBUILD

I wonder how to synchronize two folders, including subfolders, using MSBuild.

I like to do

a) to copy all files from the source folder to the dest folder that are newer or do not exist in the dest folder

and

b) delete all files from the dest folder that do not exist (anymore) in the source folder

a) pretty easy using the <Copy> task, but how can I do b)?

This is my build file so far:

 <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> 
+6
source share
3 answers

You can do this using the GetDistinctItems task from the MSBuild expansion pack . The basic idea is to get individual items between files from the source and destination folders.

 <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> 
+4
source

If someone does not want or cannot install the expansion pack

 <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> 
+2
source

You can use the MSDeploy utility in MSBuild to synchronize two folders, such as:

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

Folders can be on one or on different computers. The folder path may contain a local and network path. Etc. You can sync IIS websites as well as folders. Just use different MSDeploy providers: http://technet.microsoft.com/en-us/library/dd569040(v=ws.10).aspx Help for setting up a Web deployment handler: http://www.iis.net/learn / publish / using-web-deploy / configure-the-web-deployment-handler

+1
source

Source: https://habr.com/ru/post/897374/


All Articles