/// <summary> /// Performa backup using the supplied configuration. /// </summary> /// <returns>BackupResult object describing the outcome.</returns> public BackupResult DoBackup() { this.OnError += this.OnEvent_Error; this.OnInformation += this.OnEvent_Information; var result = new BackupResult(); result.StartTime = DateTime.Now; try { Directory.CreateDirectory(config.BackupTarget.Path); } catch (Exception ex) { OnError?.Invoke(this, new BackupEventArgs("Failed to create backup directory at {0}", config.BackupTarget.Path)); result.Success = false; result.Exception = ex; result.EndTime = DateTime.Now; return(result); } if ((config.Options != null) && config.Options.CreateLogFile) { // Create log file. result.LogFilePath = Path.Combine(config.BackupTarget.Path, "backup.log"); logFileWtr = new StreamWriter(result.LogFilePath, false); OnInformation?.Invoke(this, new BackupEventArgs("Starting at {0}", result.StartTime)); } try { foreach (var source in config.BackupSource) { var excludeFileTypes = Combine(source.GetExcludeFileTypes(), config.Options.GetExcludeFileTypes()); var excludeDirs = Combine(source.GetExcludeDirs(), config.Options.GetExcludeDirs()); // Create a top-level directory for each backup root in the configuration. // We need to make sure these are unique. var targetPath = BuildTargetPath(new DirectoryInfo(source.Path).Name, config.BackupTarget.Path); DoBackup(source.Path, targetPath, config.Options.Verify, excludeFileTypes, excludeDirs, result); } result.Success = true; } catch (Exception ex) { result.Success = false; result.Exception = ex; if (logFileWtr != null) { logFileWtr.WriteLine("{0} : Error: {1}", DateTime.Now, ex.Message); } } finally { result.EndTime = DateTime.Now; if (logFileWtr != null) { logFileWtr.WriteLine("Finished at {0}", result.EndTime); logFileWtr.Close(); logFileWtr = null; } this.OnError -= this.OnEvent_Error; this.OnInformation -= this.OnEvent_Information; } return(result); }
/// <summary> /// backup a directory. /// </summary> /// <param name="sourceDirPath">Source directory.</param> /// <param name="targetDirPath">Target directory.</param> /// <param name="verify">Verify each file copy?</param> /// <param name="excludeFileTypes">File types to exclude</param> /// <param name="excludeDirs">Directory names to exclude</param> /// <param name="progress">Backup result to be updated.</param> private void DoBackup( string sourceDirPath, string targetDirPath, bool verify, string[] excludeFileTypes, string[] excludeDirs, BackupResult progress) { Directory.CreateDirectory(targetDirPath); // Backup files. IEnumerable <string> filesEnum = null; try { filesEnum = EnumerateFiles(sourceDirPath, excludeFileTypes); } catch (System.UnauthorizedAccessException ex) { progress.DirectoriesSkipped += 1; OnError?.Invoke(this, new BackupEventArgs("{0} Directory skipped.", ex.Message)); return; } foreach (var sourceFilePath in filesEnum) { var targetFilePath = Path.Combine(targetDirPath, sourceFilePath.Substring(sourceFilePath.LastIndexOf('\\') + 1)); var sourceFileLen = new FileInfo(sourceFilePath).Length; OnInformation?.Invoke(this, new BackupEventArgs("{0} => {1}", sourceFilePath, targetFilePath)); string sourceHash, targetHash; try { CopyFile(sourceFilePath, targetFilePath, copyBuff, verify, out sourceHash, out targetHash); } catch (Exception ex) { if (ex is UnauthorizedAccessException || ex is IOException) { progress.FilesSkipped += 1; OnError?.Invoke(this, new BackupEventArgs("{0} File skipped.", ex.Message)); continue; } else { throw; } } if (sourceHash != targetHash) { throw new IOException(string.Format("Backup verify failed for {0}", sourceFilePath)); } progress.FilesCopied += 1; progress.BytesCopied += sourceFileLen; OnInformation?.Invoke(this, new BackupEventArgs("{0}, {1} => {2}, {3} bytes {4}", DateTime.Now, sourceFilePath, targetFilePath, sourceFileLen, verify ? sourceHash : "")); } // Recurse subdirectories. foreach (var sourceSubdirPath in EnumerateDirectories(sourceDirPath, excludeDirs)) { var targetSubdirPath = Path.Combine(targetDirPath, sourceSubdirPath.Substring(sourceSubdirPath.LastIndexOf('\\') + 1)); DoBackup(sourceSubdirPath, targetSubdirPath, verify, excludeFileTypes, excludeDirs, progress); progress.DirectoriesCopied += 1; } }