+++ /dev/null
-//-----------------------------------------------------------------------
-// <copyright file="BackupService.cs" company="Takayoshi Matsuyama">
-// Copyright (c) Takayoshi Matsuyama. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-// This file is part of Simple Backup.
-//
-// Simple Backup is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Simple Backup is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using SimpleBackup.Core.Models;
-using SimpleBackup.Core.Services;
-using SimpleBackup.Core.Utilities;
-using SimpleBackup.Models;
-
-namespace SimpleBackup.Services
-{
- using SimpleBackup.Resources;
-
- /// <summary>
- /// Backup service.
- /// </summary>
- public class BackupService : IBackupService
- {
- /// <summary>
- /// The synchronize root
- /// </summary>
- private static readonly object SyncRoot = new object();
-
- /// <summary>
- /// The instance of SettingFileService.
- /// </summary>
- private static volatile BackupService instance;
-
- /// <summary>
- /// Prevents a default instance of the <see cref="BackupService"/> class from being created.
- /// </summary>
- private BackupService()
- {
- BackupSettingService.Instance.BackupSettingCreated += OnBackupSettingCreated;
- BackupSettingService.Instance.BackupSettingOpened += this.OnBackupSettingOpened;
- BackupSettingService.Instance.BackupSettingClosed += this.OnBackupSettingClosed;
- }
-
- /// <summary>
- /// Occurs when file backup progress is updated.
- /// </summary>
- public event EventHandler<FileBackupProgressEventArgs> NofityFileBackupProgress;
-
- /// <summary>
- /// Gets the instance.
- /// </summary>
- public static IBackupService Instance
- {
- get
- {
- if (instance == null)
- {
- lock (SyncRoot)
- {
- if (instance == null)
- {
- instance = new BackupService();
- }
- }
- }
-
- return instance;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this service is ready for backup.
- /// </summary>
- public bool IsReadyForBackup { get; private set; }
-
- /// <summary>
- /// Gets a value indicating whether this service is executing backup.
- /// </summary>
- public bool IsExecutingBackup { get; private set; }
-
- /// <summary>
- /// Backups multipul files.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="resultInfos">The array of result information.</param>
- public void BackupMultipulFiles(CancellationToken cancellationToken, out ResultInfo[] resultInfos)
- {
- this.IsExecutingBackup = true;
- var resultList = new List<ResultInfo>();
- if (this.IsReadyForBackup == false)
- {
- resultList.Add(new ResultInfo(BackupState.Failed, Resources.Backup_Failed_BackupInfomationNotPrepared));
- resultInfos = resultList.ToArray();
- return;
- }
-
- try
- {
- this.NotifyBackupProgress(0, null);
-
- int processedCount = 0;
-
- foreach (IBackupInfo backupInfo in BackupSettingService.Instance.CurrentSetting.BackupInfos)
- {
- cancellationToken.ThrowIfCancellationRequested();
- backupInfo.BackupState = BackupState.InProgress;
-
- Thread.Sleep(100);
-
- ResultInfo resultInfo = null;
- double progressValue = 0;
-
- if (backupInfo.IsEnabled == false)
- {
- string description = string.Format(
- "{0}\r\n\t{1}: {2}",
- Resources.Backup_Skipped,
- Resources.Backup_From,
- backupInfo.SourcePath);
- resultInfo = new ResultInfo(BackupState.Skipped, description);
- processedCount++;
- progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count;
- this.NotifyBackupProgress(progressValue, resultInfo);
- backupInfo.BackupState = BackupState.Skipped;
- continue;
- }
-
- // Check the source.
- if (((backupInfo.BackupSourceType == BackupSourceType.File) && (File.Exists(backupInfo.SourcePath) == false)) ||
- ((backupInfo.BackupSourceType == BackupSourceType.Folder) && (Directory.Exists(backupInfo.SourcePath) == false)))
- {
- string description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}",
- Resources.Backup_Failed_SourceNotExist,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- backupInfo.DestinationFolderPath);
- resultInfo = new ResultInfo(BackupState.Failed, description);
- resultList.Add(resultInfo);
- processedCount++;
- progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count;
- this.NotifyBackupProgress(progressValue, resultInfo);
- backupInfo.BackupState = BackupState.Failed;
- continue;
- }
-
- // Check the destination.
- if ((backupInfo.DestinationFolderPath == "\\") ||
- (Directory.Exists(backupInfo.DestinationFolderPath) == false))
- {
- string description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}",
- Resources.Backup_Failed_DestinationNotExist,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- backupInfo.DestinationFolderPath);
- resultInfo = new ResultInfo(BackupState.Failed, description);
- resultList.Add(resultInfo);
- processedCount++;
- progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count;
- this.NotifyBackupProgress(progressValue, resultInfo);
- backupInfo.BackupState = BackupState.Failed;
- continue;
- }
-
- var destinationFileNames = new DestinationPathInfo[0];
- try
- {
- if (backupInfo.IsZipArchive)
- {
- if (backupInfo.BackupSourceType == BackupSourceType.File)
- {
- BackupFileToZip(backupInfo, out destinationFileNames);
- }
- else if (backupInfo.BackupSourceType == BackupSourceType.Folder)
- {
- BackupFolerToZip(backupInfo, out destinationFileNames);
- }
- }
- else
- {
- if (backupInfo.BackupSourceType == BackupSourceType.File)
- {
- BackupFile(backupInfo, out destinationFileNames);
- }
- else if (backupInfo.BackupSourceType == BackupSourceType.Folder)
- {
- BackupFolder(backupInfo, out destinationFileNames);
- }
- }
- }
- catch (Exception e)
- {
- string description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}\r\n{5}",
- Resources.Backup_Failed_FailedToCopy,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- destinationFileNames.FirstOrDefault(),
- e.Message);
- resultInfo = new ResultInfo(BackupState.Failed, description);
- resultList.Add(resultInfo);
- processedCount++;
- progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count;
- this.NotifyBackupProgress(progressValue, resultInfo);
- backupInfo.BackupState = BackupState.Failed;
- continue;
- }
-
- if (CheckExistence(destinationFileNames))
- {
- string description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}",
- Resources.Backup_Succeeded,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- destinationFileNames.First().Path);
- resultInfo = new ResultInfo(BackupState.Success, description);
- resultList.Add(resultInfo);
- backupInfo.BackupState = BackupState.Success;
- backupInfo.LatestSuccessfulBackupTargetName = destinationFileNames.First().Path;
- }
-
- processedCount++;
- progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count;
- this.NotifyBackupProgress(progressValue, resultInfo);
- }
-
- this.NotifyBackupProgress(100.0, null);
- }
- catch (OperationCanceledException)
- {
- var resultInfo = new ResultInfo(BackupState.Cancelled, Resources.BackupState_Cancelled);
- resultList.Add(resultInfo);
- this.NotifyBackupProgress(100.0, resultInfo);
- }
- finally
- {
- resultInfos = resultList.ToArray();
- this.IsExecutingBackup = false;
- }
- }
-
- /// <summary>
- /// Backups single file.
- /// </summary>
- /// <param name="backupInfoId">The backup information identifier.</param>
- /// <returns>The result information.</returns>
- public ResultInfo BackupSingleFile(Guid backupInfoId)
- {
- IBackupInfo backupInfo = BackupSettingService.Instance.CurrentSetting.FirstOrDefault(backupInfoId);
- if (backupInfo == null)
- {
- return new ResultInfo(
- BackupState.Failed,
- Resources.Backup_Failed_BackupInfomationNotPrepared);
- }
-
- backupInfo.BackupState = BackupState.InProgress;
- Helpers.UpdateWpfGui();
-
- ResultInfo resultInfo = null;
- string description = string.Empty;
-
- // Check the source.
- if (((backupInfo.BackupSourceType == BackupSourceType.File) && (File.Exists(backupInfo.SourcePath) == false)) ||
- ((backupInfo.BackupSourceType == BackupSourceType.Folder) && (Directory.Exists(backupInfo.SourcePath) == false)))
- {
- description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}",
- Resources.Backup_Failed_SourceNotExist,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- backupInfo.DestinationFolderPath);
- resultInfo = new ResultInfo(BackupState.Failed, description);
- backupInfo.BackupState = BackupState.Failed;
- return resultInfo;
- }
-
- // Check the destination.
- if (Directory.Exists(backupInfo.DestinationFolderPath) == false)
- {
- description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}",
- Resources.Backup_Failed_DestinationNotExist,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- backupInfo.DestinationFolderPath);
- resultInfo = new ResultInfo(BackupState.Failed, description);
- backupInfo.BackupState = BackupState.Failed;
- return resultInfo;
- }
-
- var destinationFileNames = new DestinationPathInfo[0];
- try
- {
- if (backupInfo.IsZipArchive)
- {
- if (backupInfo.BackupSourceType == BackupSourceType.File)
- {
- BackupFileToZip(backupInfo, out destinationFileNames);
- }
- else if (backupInfo.BackupSourceType == BackupSourceType.Folder)
- {
- BackupFolerToZip(backupInfo, out destinationFileNames);
- }
- }
- else
- {
- if (backupInfo.BackupSourceType == BackupSourceType.File)
- {
- BackupFile(backupInfo, out destinationFileNames);
- }
- else if (backupInfo.BackupSourceType == BackupSourceType.Folder)
- {
- BackupFolder(backupInfo, out destinationFileNames);
- }
- }
- }
- catch (Exception e)
- {
- description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}\r\n{5}",
- Resources.Backup_Failed_FailedToCopy,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- destinationFileNames.FirstOrDefault(),
- e.Message);
- resultInfo = new ResultInfo(BackupState.Failed, description);
- backupInfo.BackupState = BackupState.Failed;
- return resultInfo;
- }
-
- if (CheckExistence(destinationFileNames))
- {
- description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}",
- Resources.Backup_Succeeded,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- destinationFileNames.First().Path);
- resultInfo = new ResultInfo(BackupState.Success, description);
- backupInfo.BackupState = BackupState.Success;
- backupInfo.LatestSuccessfulBackupTargetName = destinationFileNames.First().Path;
- return resultInfo;
- }
-
- description = string.Format(
- "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}",
- Resources.Backup_Failed_FailedToCopy,
- Resources.Backup_From,
- backupInfo.SourcePath,
- Resources.Backup_To,
- destinationFileNames.FirstOrDefault());
- return new ResultInfo(BackupState.Failed, description);
- }
-
- private static void BackupFileToZip(IBackupInfo backupInfo, out DestinationPathInfo[] destinationPathInfoArray)
- {
- var innerDestinationPathInfoList = new List<DestinationPathInfo>();
-
- Match lastPathSegmentMatch = Constants.EndPathSegmentRegex.Match(backupInfo.SourcePath);
- Match fileNameMatch = Constants.FileNameRegex.Match(lastPathSegmentMatch.Value);
- Match extensionMatch = Constants.ExtensionRegex.Match(lastPathSegmentMatch.Value);
-
- string destinationFolderPath = backupInfo.DestinationFolderPath.AddTailPathSeparatorIfNotExist();
- string destinationTempFolderPath = destinationFolderPath + fileNameMatch.Value +
- " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss") + "-tmp";
- string destinationTempFileName = destinationTempFolderPath + "\\" + fileNameMatch.Value +
- " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss") + "." + extensionMatch.Value;
- try
- {
- try
- {
- Directory.CreateDirectory(destinationTempFolderPath);
- }
- catch (Exception e)
- {
- throw new InvalidOperationException(
- string.Format(
- "Failed to create the folder: {0}\r\n{1}",
- destinationTempFolderPath,
- e.Message),
- e);
- }
-
- try
- {
- File.Copy(backupInfo.SourcePath, destinationTempFileName);
- }
- catch (Exception e)
- {
- throw new InvalidOperationException(
- string.Format(
- "Failed to copy the file.\r\n\tFrom: {0}\r\n\tTo: {1}\r\n{2}",
- backupInfo.SourcePath,
- destinationTempFolderPath,
- e.Message),
- e);
- }
-
- var destinationFileName = destinationFolderPath + fileNameMatch.Value
- + " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".zip";
- innerDestinationPathInfoList.Add(new DestinationPathInfo(BackupSourceType.File, destinationFileName));
-
- try
- {
- ZipFile.CreateFromDirectory(
- destinationTempFolderPath,
- destinationFileName,
- CompressionLevel.Optimal,
- false,
- Encoding.GetEncoding(Properties.Settings.Default.DefaultZipEncodingKeyText));
- }
- catch (Exception e)
- {
- backupInfo.BackupState = BackupState.Failed;
- throw new InvalidOperationException(
- string.Format(
- "Failed to create the zip archive.\r\n\tFrom: {0}\r\n\tTo: {1}\r\n{2}",
- destinationTempFolderPath,
- destinationFileName,
- e.Message),
- e);
- }
- }
- finally
- {
- destinationPathInfoArray = innerDestinationPathInfoList.ToArray();
-
- if (File.Exists(destinationTempFileName))
- {
- File.Delete(destinationTempFileName);
- }
-
- if (Directory.Exists(destinationTempFolderPath))
- {
- Directory.Delete(destinationTempFolderPath);
- }
- }
- }
-
- private static void BackupFolerToZip(IBackupInfo backupInfo, out DestinationPathInfo[] destinationPathInfoArray)
- {
- var innerDestinationPathInfoList = new List<DestinationPathInfo>();
-
- Match lastPathSegmentMatch = Constants.EndPathSegmentRegex.Match(backupInfo.SourcePath);
-
- string destinationFolderPath = backupInfo.DestinationFolderPath.AddTailPathSeparatorIfNotExist();
- var destinationFileName = destinationFolderPath
- + lastPathSegmentMatch.Value + " - "
- + DateTime.Now.ToString("yyyyMMdd-HHmmss")
- + ".zip";
- innerDestinationPathInfoList.Add(new DestinationPathInfo(BackupSourceType.File, destinationFileName));
-
- try
- {
- ZipFile.CreateFromDirectory(
- backupInfo.SourcePath,
- destinationFileName,
- CompressionLevel.Optimal,
- false,
- Encoding.GetEncoding(SimpleBackup.Properties.Settings.Default.DefaultZipEncodingKeyText));
- }
- catch (Exception e)
- {
- backupInfo.BackupState = BackupState.Failed;
- throw new InvalidOperationException(
- string.Format(
- "Failed to create the zip archive.\r\n\tFrom: {0}\r\n\tTo: {1}\r\n{2}",
- backupInfo.SourcePath,
- destinationFileName,
- e.Message),
- e);
- }
- finally
- {
- destinationPathInfoArray = innerDestinationPathInfoList.ToArray();
- }
- }
-
- private static void BackupFile(IBackupInfo backupInfo, out DestinationPathInfo[] destinationPathInfoArray)
- {
- var innerDestinationPathInfoList = new List<DestinationPathInfo>();
-
- Match lastPathSegmentMatch = Constants.EndPathSegmentRegex.Match(backupInfo.SourcePath);
- Match fileNameMatch = Constants.FileNameRegex.Match(lastPathSegmentMatch.Value);
- Match extensionMatch = Constants.ExtensionRegex.Match(lastPathSegmentMatch.Value);
-
- string destinationFolderPath = backupInfo.DestinationFolderPath.AddTailPathSeparatorIfNotExist();
- var destinationFileName = destinationFolderPath + fileNameMatch.Value
- + " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss") + "." + extensionMatch.Value;
- innerDestinationPathInfoList.Add(new DestinationPathInfo(BackupSourceType.File, destinationFileName));
-
- try
- {
- File.Copy(backupInfo.SourcePath, destinationFileName);
- }
- finally
- {
- destinationPathInfoArray = innerDestinationPathInfoList.ToArray();
- }
- }
-
- private static void BackupFolder(IBackupInfo backupInfo, out DestinationPathInfo[] destinationPathInfoArray)
- {
- var innerDestinationPathInfoList = new List<DestinationPathInfo>();
-
- Match lastPathSegmentMatch = Constants.EndPathSegmentRegex.Match(backupInfo.SourcePath);
-
- //// 方法 : ディレクトリをコピーする
- //// http://msdn.microsoft.com/ja-jp/library/bb762914(v=vs.110).aspx
- string destinationFolderPath = backupInfo.DestinationFolderPath.AddTailPathSeparatorIfNotExist();
- var destinationFolderName = destinationFolderPath
- + lastPathSegmentMatch.Value + " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss");
- innerDestinationPathInfoList.Add(new DestinationPathInfo(BackupSourceType.Folder, destinationFolderName));
-
- try
- {
- FolderCopy(backupInfo.SourcePath, destinationFolderName, true);
- }
- finally
- {
- destinationPathInfoArray = innerDestinationPathInfoList.ToArray();
- }
- }
-
- private static void FolderCopy(string sourceFolderPath, string destinationFolderPath, bool copySubFolders)
- {
- var sourceDirectoryInfo = new DirectoryInfo(sourceFolderPath);
- DirectoryInfo[] subDirectoryInfos = sourceDirectoryInfo.GetDirectories();
-
- if (sourceDirectoryInfo.Exists == false)
- {
- throw new DirectoryNotFoundException(
- "Source directory does not exist or could not be found: "
- + sourceFolderPath);
- }
-
- // If the destination directory doesn't exist, create it.
- if (Directory.Exists(destinationFolderPath) == false)
- {
- Directory.CreateDirectory(destinationFolderPath);
- }
-
- // Get the files in the directory and copy them to the new location.
- FileInfo[] files = sourceDirectoryInfo.GetFiles();
- foreach (FileInfo file in files)
- {
- string temppath = Path.Combine(destinationFolderPath, file.Name);
- file.CopyTo(temppath, false);
- }
-
- // If copying subdirectories, copy them and their contents to new location.
- if (copySubFolders)
- {
- foreach (DirectoryInfo subDirectoryInfo in subDirectoryInfos)
- {
- string temppath = Path.Combine(destinationFolderPath, subDirectoryInfo.Name);
- FolderCopy(subDirectoryInfo.FullName, temppath, copySubFolders);
- }
- }
- }
-
- private static bool CheckExistence(DestinationPathInfo[] destinationPathInfoArray)
- {
- return (destinationPathInfoArray != null) &&
- (destinationPathInfoArray.Length != 0) &&
- destinationPathInfoArray.All(
- destinationPathInfo =>
- {
- if (destinationPathInfo.BackupSourceType == BackupSourceType.File)
- {
- return File.Exists(destinationPathInfo.Path);
- }
-
- return Directory.Exists(destinationPathInfo.Path);
- });
- }
-
- private void OnBackupSettingCreated(object sender, SettingFileEventArgs settingFileEventArgs)
- {
- this.IsReadyForBackup = true;
- }
-
- private void OnBackupSettingOpened(object sender, SettingFileEventArgs settingFileEventArgs)
- {
- this.IsReadyForBackup = true;
- }
-
- private void OnBackupSettingClosed(object sender, SettingFileEventArgs settingFileEventArgs)
- {
- this.IsReadyForBackup = false;
- }
-
- private void NotifyBackupProgress(double progressValue, ResultInfo latestResultInfo)
- {
- if (this.NofityFileBackupProgress != null)
- {
- this.NofityFileBackupProgress(this, new FileBackupProgressEventArgs(progressValue, latestResultInfo));
- }
- }
- }
-}