示例#1
0
        /// <summary>
        /// Copies the contents of a source to a destination based on an individual setting
        /// </summary>
        /// <param name="setting">Contains information on a source and destination pair</param>
        /// <param name="loggingBackgroundWorker">A <see cref="BackgroundWorker"/> instance to provide updates to</param>
        public void Copy(ISetting setting, LoggingBackgroundWorker loggingBackgroundWorker)
        {
            if (setting == null)
            {
                throw new ArgumentNullException(nameof(setting));
            }

            if (loggingBackgroundWorker == null)
            {
                throw new ArgumentNullException(nameof(loggingBackgroundWorker));
            }

            if (string.IsNullOrWhiteSpace(setting.Source))
            {
                try
                {
                    throw new Exception("Source path is null or whitespace.");
                }
                catch (Exception e)
                {
                    loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                        Exception = e
                    });
                    return;
                }
            }

            if (string.IsNullOrWhiteSpace(setting.Destination))
            {
                try
                {
                    throw new Exception("Destination path is null or whitespace.");
                }
                catch (Exception e)
                {
                    loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                        Exception = e
                    });
                    return;
                }
            }

            if (!Directory.Exists(setting.Source))
            {
                try
                {
                    throw new Exception($"Source path {setting.Source} doesn't exist on disk.");
                }
                catch (Exception e)
                {
                    loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                        Exception = e
                    });
                    return;
                }
            }

            if (!Directory.Exists(setting.Destination))
            {
                try
                {
                    Utilities.IO.Directory.CreateDirectory(setting.Destination);
                    // throw new Exception($"Destination path {setting.Destination} doesn't exist on disk.");
                }
                catch (Exception e)
                {
                    loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                        Exception = e
                    });
                    return;
                }
            }

            loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                Message = $"Counting objects in {setting.Source}"
            });

            this.totalObjectCount = Utilities.IO.Directory.CountObjects(setting.Source, true);

            loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                Message = $"Files and folders in source directory: {this.totalObjectCount}."
            });
            loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                Message = $"Attempting to copy from {setting.Source} \r\nto {setting.Destination}."
            });

            // Note: if files / subdirs are added to a directory, the lastwritetime reflects the time they were added.
            // However, if files / subdirs are added to a directory's subdir, the lastwritetime is not updated
            // Therefore, only iterate through a directorys subdirs not its files when the lastwritetime isn't more recent than the destination equivalent
            this.CopyIfNewer(setting.Source, setting.Destination, setting.BackupMode, loggingBackgroundWorker);

            loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                Message = "Done!"
            });
        }
示例#2
0
        /// <summary>
        /// Copies a directory if it's been updated more recently than the destination equivalent,
        /// including all files and sub directories.
        /// </summary>
        /// <param name="sourceDirectoryPath">The path to the source directory.</param>
        /// <param name="destinationDirectoryPath">The path to the destination directory.</param>
        /// <param name="mode">The backup mode</param>
        /// <param name="loggingBackgroundWorker">A <see cref="LoggingBackgroundWorker"/></param>
        /// <remarks>
        /// Based on the example @ https://msdn.microsoft.com/en-us/library/bb762914(v=vs.110).aspx
        /// </remarks>
        // ReSharper disable once StyleCop.SA1650
        public void CopyIfNewer(string sourceDirectoryPath, string destinationDirectoryPath, BackupMode mode, LoggingBackgroundWorker loggingBackgroundWorker)
        {
            // Get the subdirectories for the specified directory.
            var sourceDirectory = new DirectoryInfo(sourceDirectoryPath);

            if (!sourceDirectory.Exists)
            {
                loggingBackgroundWorker.OnLog(this, new LoggingEventArgs {
                    Message = $"Source directory does not exist or could not be found: {sourceDirectoryPath}"
                });
            }

            // If the destination directory doesn't exist, create it.
            if (!Directory.Exists(destinationDirectoryPath))
            {
                Utilities.IO.Directory.CreateDirectory(destinationDirectoryPath);
            }

            // Get the files in the directory and copy them to the new location.
            foreach (var file in sourceDirectory.GetFiles())
            {
                var destinationFilePath = Path.Combine(destinationDirectoryPath, file.Name);

                var sourceFileInfo = file;

                if (File.Exists(destinationFilePath))
                {
                    var destinationFileInfo = new FileInfo(destinationFilePath);
                    if (sourceFileInfo.LastWriteTime > destinationFileInfo.LastWriteTime)
                    {
                        try
                        {
                            Utilities.IO.File.CopyTo(file.FullName, destinationFilePath);
                        }
                        catch (Exception e)
                        {
                            loggingBackgroundWorker?.OnLog(this, new LoggingEventArgs {
                                Message = $"Exception when trying to copy file from {file.FullName} to {destinationFilePath}.", Exception = e
                            });
                        }
                    }
                }
                else
                {
                    try
                    {
                        Utilities.IO.File.CopyTo(file.FullName, destinationFilePath);
                    }
                    catch (Exception e)
                    {
                        loggingBackgroundWorker?.OnLog(this, new LoggingEventArgs {
                            Message = $"Exception when trying to copy file from {file.FullName} to {destinationFilePath}.", Exception = e
                        });
                    }
                }

                this.runningObjectCount++;
                var value = Convert.ToInt32((((this.qtySettingsCompleted * this.totalObjectCount) + this.runningObjectCount) / (SettingsFile.Data.Paths.Count * this.totalObjectCount)) * 100.0);

                loggingBackgroundWorker?.ReportProgress(value);
            }

            if (mode == BackupMode.Synchronise)
            {
                // Delete any files on destination directory that aren't in the source directory
                var destinationDirectory = new DirectoryInfo(destinationDirectoryPath);
                foreach (var destinationFile in destinationDirectory.GetFiles().Where(df => !sourceDirectory.GetFiles().Any(sf => string.Equals(df.Name, sf.Name))))
                {
                    try
                    {
                        // destinationFile.Delete();
                        Utilities.IO.File.Delete(destinationFile.FullName);
                    }
                    catch (Exception e)
                    {
                        loggingBackgroundWorker?.OnLog(this, new LoggingEventArgs {
                            Message = $"Exception when trying to delete file {destinationFile.FullName}.", Exception = e
                        });
                    }
                }

                // Delete any directories on destination directory that aren't in the source directory
                foreach (var destinationDir in destinationDirectory.GetDirectories().Where(dd => !sourceDirectory.GetDirectories().Any(sd => string.Equals(dd.Name, sd.Name))))
                {
                    try
                    {
                        // destinationDir.Delete();
                        Utilities.IO.Directory.Delete(destinationDir.FullName);
                    }
                    catch (Exception e)
                    {
                        loggingBackgroundWorker?.OnLog(this, new LoggingEventArgs {
                            Message = $"Exception when trying to delete directory {destinationDir.FullName}.", Exception = e
                        });
                    }
                }
            }

            // Copy the subdirectories and their contents to new location.
            foreach (var subdirPath in Directory.GetDirectories(sourceDirectoryPath))
            {
                try
                {
                    // Path.GetDirectoryName throws PathTooLongException
                    var subdirectoryInfo = new DirectoryInfo(subdirPath);
                    this.CopyIfNewer(subdirPath, Path.Combine(destinationDirectoryPath, subdirectoryInfo.Name), mode, loggingBackgroundWorker);
                }
                catch (Exception e)
                {
                    loggingBackgroundWorker?.OnLog(this, new LoggingEventArgs {
                        Message = $"Exception when trying to copy from {subdirPath} to {destinationDirectoryPath}.", Exception = e
                    });
                }

                this.runningObjectCount++;
                var value = Convert.ToInt32((((this.qtySettingsCompleted * this.totalObjectCount) + this.runningObjectCount) / (SettingsFile.Data.Paths.Count * this.totalObjectCount)) * 100.0);
                loggingBackgroundWorker?.ReportProgress(value);
            }
        }