using System.Collections.Generic; using System.IO; using System.Linq; namespace BetaVersionLauncher { /// /// Replicates a directory to a target directory. /// public class RoboCopy { public static void ReplicateDirectory(string source, string destination) { var sourceFiles = GetRelativeFilesRecursive(source); var destinationFiles = GetRelativeFilesRecursive(destination); // Copy new files. foreach (var file in sourceFiles) { ReplicateFile(Path.Combine(source, file), Path.Combine(destination, file)); } // Remove old files. foreach (var destinationFile in destinationFiles) { if (!sourceFiles.Contains(destinationFile)) { string file = Path.Combine(destination, destinationFile); File.SetAttributes(file, FileAttributes.Normal); File.Delete(file); } } } private static HashSet GetRelativeFilesRecursive(string folder) { if (!Directory.Exists(folder)) { return new HashSet(); } return new HashSet(Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories).Select(file => ToRelative(folder, file))); } private static void ReplicateFile(string source, string destination) { CreateDirectory(Path.GetDirectoryName(destination)); var sourceFileInfo = new FileInfo(source); var destinationFileInfo = new FileInfo(destination); if (!destinationFileInfo.Exists || sourceFileInfo.Length != destinationFileInfo.Length || sourceFileInfo.LastWriteTimeUtc != destinationFileInfo.LastWriteTimeUtc) { if (destinationFileInfo.Exists && destinationFileInfo.IsReadOnly) { File.SetAttributes(destination, FileAttributes.Normal); } File.Copy(source, destination, true); } } private static void CreateDirectory(string directory) { if (!Directory.Exists(directory)) { CreateDirectory(Path.GetDirectoryName(directory)); Directory.CreateDirectory(directory); } } private static string ToRelative(string folder, string file) { return file.Substring(folder.Length).Replace('/', '\\').TrimStart('\\'); } } }