/// <summary> /// Creates a backup of the specified files using the specified key. /// </summary> /// <param name="backupRoot">Backup root directory.</param> /// <param name="key">Backup key.</param> /// <param name="fileNames">Files to backup.</param> /// <returns>Backup location</returns> public static string BackupFiles( string backupRoot, string key, IEnumerable <string> fileNames) { if (backupRoot == null || backupRoot.Trim().Length == 0) { throw new ArgumentException("Invalid backup location", "backupRoot"); } else if (key == null || key.Trim().Length == 0) { throw new ArgumentException("Invalid backup key", "key"); } if (!Directory.Exists(backupRoot)) { Directory.CreateDirectory(backupRoot); } DateTime backupDate = DateTime.Now; string dateDirectory = backupDate.ToFileTime().ToString(CultureInfo.InvariantCulture); string keyRoot = Path.Combine(backupRoot, key); if (!Directory.Exists(keyRoot)) { Directory.CreateDirectory(keyRoot); } string backupLocation = Path.Combine(keyRoot, dateDirectory); Directory.CreateDirectory(backupLocation); string zipFile = Path.Combine(backupLocation, ZipFileName); // Copy all files to a temporary working directory string workingDirectory = CreateTempFilePath(); Directory.CreateDirectory(workingDirectory); try { string indexFile = Path.Combine(backupLocation, IndexFileName); using (FileStream fs = new FileStream(indexFile, FileMode.Create)) { using (StreamWriter writer = new StreamWriter(fs)) { foreach (string fileName in fileNames) { string fileKey = CreateFileNameKey(fileName); string fileBackupName = fileKey + "." + ProjectManager.GetExtension(fileName); writer.WriteLine(fileBackupName + IndexSeparator + fileName); string fileBackupPath = Path.Combine(workingDirectory, fileBackupName); File.Copy(fileName, fileBackupPath); } } } // Zip up all files to backup ZipUtilities.Zip(workingDirectory, zipFile); } finally { TryDeleteDirectory(workingDirectory); } return(backupLocation); }
/// <summary> /// Restores all files associated with the specified key. /// </summary> /// <param name="backupRoot">Backup root directory.</param> /// <param name="key">Backup key.</param> /// <returns>A boolean value indicating whether or not the operation was succesful.</returns> public static bool RestoreFiles(string backupRoot, string key) { bool success = false; if (backupRoot == null || backupRoot.Trim().Length == 0) { throw new ArgumentException("Invalid backup location", "backupRoot"); } else if (key == null || key.Trim().Length == 0) { throw new ArgumentException("Invalid backup key", "key"); } string keyRoot = Path.Combine(backupRoot, key); // Find the most recent timestamped folder DirectoryInfo keyDirectory = new DirectoryInfo(keyRoot); SortedList <string, DirectoryInfo> timestampedDirectories = new SortedList <string, DirectoryInfo>(); DirectoryInfo[] childDirectories = keyDirectory.GetDirectories(); foreach (DirectoryInfo childDirectory in childDirectories) { timestampedDirectories.Add(childDirectory.Name, childDirectory); } if (timestampedDirectories.Count > 0) { string dateDirectory = timestampedDirectories.Values[timestampedDirectories.Count - 1].Name; string backupLocation = Path.Combine(keyRoot, dateDirectory); string zipFile = Path.Combine(backupLocation, ZipFileName); // Extract all files to a temporary working directory string workingDirectory = CreateTempFilePath(); Directory.CreateDirectory(workingDirectory); try { // Unzip and copy all files to restore ZipUtilities.Unzip(zipFile, workingDirectory); string indexFile = Path.Combine(backupLocation, IndexFileName); using (FileStream fs = new FileStream(indexFile, FileMode.Open)) { using (StreamReader reader = new StreamReader(fs)) { while (!reader.EndOfStream) { string line = reader.ReadLine(); int separatorIndex = line.IndexOf(IndexSeparator); string fileBackupName = line.Substring(0, separatorIndex); string fileBackupPath = Path.Combine(workingDirectory, fileBackupName); string restorePath = line.Substring(separatorIndex + 1); string backupText = File.ReadAllText(fileBackupPath); string restoreText = null; if (File.Exists(restorePath)) { restoreText = File.ReadAllText(restorePath); File.SetAttributes(restorePath, FileAttributes.Normal); } if (backupText != restoreText) { File.Copy(fileBackupPath, restorePath, true); } } } } // Remove the restored backup so that a consecutive restore // will process the next in the history Directory.Delete(backupLocation, true); success = true; } finally { TryDeleteDirectory(workingDirectory); } } return(success); }