/// <summary> /// Process all comparison entries to determine if the files need to be synchronized. /// </summary> /// <remarks> /// The normal synchronize has allowDelete set to true. /// If allowDelete is set to false, then the process will create directories plus insert and update files /// but it will not remove directories or delete files so it acts like a copy over, so that if you also /// select "replace only with newer" then it will keep the latest versions of everything. /// </remarks> public void Process(Comparisons <Comparison> comparisons, DateTime startAllDateTime, bool allowDelete) { sameCount = 0; deleteCount = 0; removeCount = 0; createCount = 0; insertCount = 0; updateCount = 0; copyCount = 0; string prevSourceDirectory = string.Empty; string prevSourceFileName = string.Empty; string prevTargetDirectory = string.Empty; string prevTargetFileName = string.Empty; bool identical = true; try { char separator = Path.DirectorySeparatorChar; Administrator.Tracer.WriteLine(); Administrator.Tracer.WriteMsg("I", "Synchronize Source Dir " + Administrator.ProfileManager.UserSettings.SelectedItem.NewBaseDir + separator); Administrator.Tracer.WriteMsg("I", "Synchronize Target Dir " + Administrator.ProfileManager.UserSettings.SelectedItem.OldBaseDir + separator); Administrator.Tracer.StartAllDateTime = startAllDateTime; if (comparisons.Count == 0) { Administrator.Tracer.WriteLine(); Administrator.Tracer.WriteMsg("I", "Nothing to compare"); } long totalChangedBytes = CalculateTotalChangedBytes(comparisons); SignalBeginSynchronize(totalChangedBytes); for (int count = 0; count < comparisons.Count; count++) { Comparison comparison = comparisons[count]; string sourceDirectory = string.Empty; string sourceFileName = string.Empty; string targetDirectory = string.Empty; string targetFileName = string.Empty; if (comparison.SourceType == "dir") { sourceDirectory = comparison.SourceEntry; sourceFileName = FileHelper.FileFullName(comparison.SourceEntry); targetDirectory = comparison.TargetEntry; targetFileName = FileHelper.FileFullName(comparison.TargetEntry); } else { sourceDirectory = FileHelper.FileStem(comparison.SourceEntry); sourceFileName = FileHelper.FileFullName(comparison.SourceEntry); targetDirectory = FileHelper.FileStem(comparison.TargetEntry); targetFileName = FileHelper.FileFullName(comparison.TargetEntry); } if (sourceDirectory != prevSourceDirectory) { this.changeOfDirectory = true; prevSourceDirectory = sourceDirectory; } if (targetDirectory != prevTargetDirectory) { this.changeOfDirectory = true; prevTargetDirectory = targetDirectory; } switch (comparison.Command) { case "Same": // Same directory entries only, no need to do anything. sameCount++; break; case "Delete": if (allowDelete) { deleteCount++; identical = false; printDirectoryChange(changeOfDirectory, comparison.Command, sourceDirectory, targetDirectory); DeleteFile(comparison); SignalUpdateSynchronize(comparison.TargetSize, comparison.DisplayCommand); } break; case "Remove": if (allowDelete) { removeCount++; identical = false; printDirectoryChange(changeOfDirectory, comparison.Command, sourceDirectory, targetDirectory); RemoveDirectory(comparison); SignalUpdateSynchronize(comparison.TargetSize, comparison.DisplayCommand); } break; case "Create": createCount++; identical = false; printDirectoryChange(changeOfDirectory, comparison.Command, sourceDirectory, targetDirectory); CreateDirectory(comparison); SignalUpdateSynchronize(comparison.SourceSize, comparison.DisplayCommand); break; case "Insert": insertCount++; copyCount++; identical = false; printDirectoryChange(changeOfDirectory, comparison.Command, sourceDirectory, targetDirectory); CopyFileUnconditional(comparison); SignalUpdateSynchronize(comparison.SourceSize, comparison.DisplayCommand); break; case "Update": bool doCopy = false; if (copyRule == UserSetting.CopyRuleEnum.SkipMatches) { doCopy = false; if (Administrator.ProfileManager.SystemProfile.Verbose) { printDirectoryChange(changeOfDirectory, comparison.Command, sourceDirectory, targetDirectory); Administrator.Tracer.WriteTimedMsg("I", String.Format(@"{0} - Skipped", sourceFileName)); } } else if (copyRule == UserSetting.CopyRuleEnum.ReplaceMatches) { doCopy = true; } else if (copyRule == UserSetting.CopyRuleEnum.ReplaceOnlyWithNewer) { if (CompareDateTimeStamps(comparison.SourceDate, comparison.TargetDate) > 0) { doCopy = true; } else { doCopy = false; if (Administrator.ProfileManager.SystemProfile.Verbose) { printDirectoryChange(changeOfDirectory, comparison.Command, sourceDirectory, targetDirectory); Administrator.Tracer.WriteTimedMsg("I", String.Format(@"{0} - Skipped - Source file is not newer", sourceFileName)); } } } else if (copyRule == UserSetting.CopyRuleEnum.ReplacePreservingNewest) { if (CompareDateTimeStamps(comparison.SourceDate, comparison.TargetDate) >= 0) { doCopy = true; } else { doCopy = false; if (Administrator.ProfileManager.SystemProfile.Verbose) { printDirectoryChange(changeOfDirectory, comparison.Command, sourceDirectory, targetDirectory); Administrator.Tracer.WriteTimedMsg("I", String.Format(@"{0} - Skipped - Source file is older", sourceFileName)); } } } if (doCopy) { updateCount++; copyCount++; identical = false; printDirectoryChange(changeOfDirectory, comparison.Command, sourceDirectory, targetDirectory); CopyFileUnconditional(comparison); SignalUpdateSynchronize(comparison.SourceSize, comparison.DisplayCommand); } else { sameCount++; } break; } if (Interrupt.Reason == "Cancel") { break; } } string message = string.Empty; string suffix = string.Empty; if (Interrupt.Reason == "Cancel") { Administrator.Tracer.WriteLine(); Administrator.Tracer.WriteMsg("W", "Synchronization process cancelled"); } else { if (identical) { Administrator.Tracer.WriteLine(); Administrator.Tracer.WriteMsg("I", "No Changes Detected"); } else { Administrator.Tracer.WriteLine(); Administrator.Tracer.WriteMsg("I", "Changes Detected"); Administrator.Tracer.WriteLine(); Administrator.Tracer.WriteMsg("I", String.Format(@"Same Count = {0}", sameCount)); Administrator.Tracer.WriteMsg("I", String.Format(@"Delete Count = {0}", deleteCount)); Administrator.Tracer.WriteMsg("I", String.Format(@"Remove Count = {0}", removeCount)); Administrator.Tracer.WriteMsg("I", String.Format(@"Create Count = {0}", createCount)); Administrator.Tracer.WriteMsg("I", String.Format(@"Insert Count = {0}", insertCount)); Administrator.Tracer.WriteMsg("I", String.Format(@"Update Count = {0}", updateCount)); Administrator.Tracer.WriteMsg("I", String.Format(@"Copy Count = {0}", copyCount)); } } SignalEndOfSynchronize(message); } catch (Exception oException) { System.Diagnostics.Debug.WriteLine(oException.Message); } finally { } }
/// <summary> /// Generate a collection of comparisons for use by external classes. /// </summary> protected void GenerateComparisons(List <DirectoryEntry> changedEntries, ref long estimate) { char separator = Path.DirectorySeparatorChar; List <Comparison> sameDirectories = new List <Comparison>(); List <Comparison> deletes = new List <Comparison>(); List <Comparison> removes = new List <Comparison>(); List <Comparison> creates = new List <Comparison>(); List <Comparison> copies = new List <Comparison>(); SignalBeginProgress("Comparisons"); estimate = 0; try { List <DirectoryEntry> changes = (List <DirectoryEntry>)(from c in changedEntries orderby c.StdDir, c.StdFile, c.StdType select c).ToList(); foreach (DirectoryEntry change in changes) { Comparison comparison = new Comparison(); comparison.Action = string.Empty; comparison.Command = string.Empty; comparison.DisplayCommand = string.Empty; comparison.Outcome = change.CtlComparison; string fileType = change.StdType; string sourceFileSpec = string.Empty; string targetFileSpec = string.Empty; if (fileType == "dir") { switch (comparison.Outcome) { case "DELETED": comparison.SortOrder = "B"; comparison.Command = "Remove"; comparison.DisplayCommand = "Removing"; break; case "INSERTED": comparison.SortOrder = "C"; comparison.Command = "Create"; comparison.DisplayCommand = "Creating"; break; case "BOTH": comparison.SortOrder = "C"; comparison.Command = "Same"; comparison.DisplayCommand = "Nothing"; break; } sourceFileSpec = change.SourceHlq + change.StdDir + separator.ToString() + change.SourceFile; targetFileSpec = change.TargetHlq + change.StdDir + separator.ToString() + change.TargetFile; } else { switch (comparison.Outcome) { case "DELETED": comparison.SortOrder = "A"; comparison.Command = "Delete"; comparison.DisplayCommand = "Deleting"; break; case "INSERTED": comparison.SortOrder = "D"; comparison.Command = "Insert"; comparison.DisplayCommand = "Copying"; break; case "BOTH": comparison.SortOrder = "E"; comparison.Command = "Update"; comparison.DisplayCommand = "Copying"; break; } sourceFileSpec = change.SourceHlq + change.StdDir + separator.ToString() + change.SourceFile; targetFileSpec = change.TargetHlq + change.StdDir + separator.ToString() + change.TargetFile; } comparison.SourceDate = change.SourceDate; comparison.TargetDate = change.TargetDate; comparison.SourceType = fileType; comparison.SourceEntry = sourceFileSpec; comparison.SourceSize = change.StdSize; comparison.TargetType = fileType; comparison.TargetEntry = targetFileSpec; comparison.TargetSize = change.StdSize; switch (comparison.Command) { case "Same": sameDirectories.Add(comparison); break; case "Delete": deletes.Add(comparison); break; case "Remove": removes.Add(comparison); break; case "Create": creates.Add(comparison); break; case "Insert": copies.Add(comparison); break; case "Update": copies.Add(comparison); break; } estimate += change.StdSize; SignalUpdateProgress("Comparisons", 1); } } catch (Exception oException) { System.Diagnostics.Debug.WriteLine(oException.Message); } finally { List <Comparison> sortedSameDirectories = (List <Comparison>)(from c in sameDirectories orderby c.SortOrder, c.Command, c.SourceEntry, c.TargetEntry select c).ToList(); List <Comparison> sortedDeletes = (List <Comparison>)(from c in deletes orderby c.SortOrder, c.Action, c.SourceEntry, c.TargetEntry select c).ToList(); //Have to be sorted descending so that deepest directories are removed before higher up directories. List <Comparison> sortedRemoves = (List <Comparison>)(from c in removes orderby c.SortOrder, c.Action, c.SourceEntry descending, c.TargetEntry descending select c).ToList(); List <Comparison> sortedCreates = (List <Comparison>)(from c in creates orderby c.SortOrder, c.Action, c.SourceEntry, c.TargetEntry select c).ToList(); List <Comparison> sortedCopies = (List <Comparison>)(from c in copies orderby c.SortOrder, c.Action, c.SourceEntry, c.TargetEntry select c).ToList(); //Transfer all groups of commands into one list. comparisons = new Comparisons <Comparison>(); foreach (var comparison in sortedSameDirectories) { comparisons.Add(comparison); } foreach (var comparison in sortedDeletes) { comparisons.Add(comparison); } foreach (var comparison in sortedRemoves) { comparisons.Add(comparison); } foreach (var comparison in sortedCreates) { comparisons.Add(comparison); } foreach (var comparison in sortedCopies) { comparisons.Add(comparison); } } SignalEndOfProgress("Comparisons"); }
/// <summary> /// Process all comparison entries to determine if the files need to be synchronized. /// </summary> /// <remarks> /// Normal synchronize which aims to make the target identical to the source /// so it will delete files and remove directories. /// </remarks> public void Process(Comparisons <Comparison> comparisons, DateTime startAllDateTime) { Process(comparisons, startAllDateTime, true); }