ソースコードはこちら
https://github.com/mi3w2a1/incremental-backup
これまではすべてのファイルをバックアップしていましたが、今回は拡張子を指定してそのファイルはバックアップ対象から外す設定ができるようにします。またリストアイテムの項目にメモ欄をつけてなにをバックアップしているのかをわかりやすくしました。
まず設定できる項目が増えたのでBackupFolderInfoクラスのメンバーを増やします(string[] Extensions と string Memo)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class BackupFolderInfo { public BackupFolderInfo() { } public BackupFolderInfo(string sourceFolderPath, string targetFolderPath, string[] extensions, string memo) { SourceFolderPath = sourceFolderPath; TargetFolderPath = targetFolderPath; Extensions = extensions; Memo = memo; } public string SourceFolderPath = ""; public string TargetFolderPath = ""; public string[] Extensions = null; public string Memo = ""; } |
実際にバックアップ対象から外す設定ができるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public partial class FormFolder : Form { // 追加 public string Memo = ""; public string[] Extensions = null; protected override void OnLoad(EventArgs e) { SourceFolderPathTextBox.Text = SourceFolderPath; TargetFolderPathTextBox.Text = TargetFolderPath; // 追加 if(Extensions != null) ExtensionsTextBox.Text = String.Join(", ", Extensions); MemoTextBox.Text = Memo; base.OnLoad(e); } private void buttonOK_Click(object sender, EventArgs e) { SourceFolderPath = SourceFolderPathTextBox.Text; TargetFolderPath = TargetFolderPathTextBox.Text; // 追加 string str = ExtensionsTextBox.Text; str = str.Replace(" ", ""); str = str.Replace(" ", ""); Extensions = str.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); Memo = MemoTextBox.Text; } } |
バックアップの設定を変更したらリストビューコントロールと設定ファイルに反映されるようにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
public partial class Form1 : Form { void InitListView() { listView1.View = View.Details; listView1.Columns.Add("バックアップ元"); listView1.Columns.Add("バックアップ先"); listView1.Columns.Add("除外する拡張子"); listView1.Columns.Add("メモ"); listView1.Columns[0].Width = 200; listView1.Columns[1].Width = 200; listView1.Columns[2].Width = 100; listView1.FullRowSelect = true; listView1.MultiSelect = false; listView1.HideSelection = false; } private void RegistFolderMenuItem_Click(object sender, EventArgs e) { FormFolder form = new FormFolder(); if(form.ShowDialog() == DialogResult.OK) { if(Directory.Exists(form.SourceFolderPath) && Directory.Exists(form.TargetFolderPath)) { string[] filePaths = Directory.GetDirectories(form.SourceFolderPath, "*.*", SearchOption.AllDirectories); if(form.SourceFolderPath != form.TargetFolderPath && !filePaths.Any(x => x == form.TargetFolderPath)) { string str = String.Join(", ", form.Extensions); string[] item = { form.SourceFolderPath, form.TargetFolderPath, str, form.Memo }; listView1.Items.Add(new ListViewItem(item)); BackupFolderInfos.Add(new BackupFolderInfo(form.SourceFolderPath, form.TargetFolderPath, form.Extensions, form.Memo)); SaveConfig(); } else { MessageBox.Show("バックアップ元フォルダのなかにバックアップ先のフォルダを指定することはできません!", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else MessageBox.Show("存在するフォルダでないと登録できません!", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } form.Dispose(); } private void ChangeFolderMenuItem_Click(object sender, EventArgs e) { var selectedItems = listView1.SelectedItems; if(selectedItems.Count == 0) { MessageBox.Show("編集する項目を選択してください!", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } ListViewItem selectedItem = selectedItems[0]; FormFolder form = new FormFolder(); int index = listView1.Items.IndexOf(selectedItem); form.SourceFolderPath = BackupFolderInfos[index].SourceFolderPath; form.TargetFolderPath = BackupFolderInfos[index].TargetFolderPath; form.Extensions = BackupFolderInfos[index].Extensions; form.Memo = BackupFolderInfos[index].Memo; if(form.ShowDialog() == DialogResult.OK) { if(Directory.Exists(form.SourceFolderPath) && Directory.Exists(form.TargetFolderPath)) { string[] filePaths = Directory.GetDirectories(form.SourceFolderPath, "*.*", SearchOption.AllDirectories); if(form.SourceFolderPath != form.TargetFolderPath && !filePaths.Any(x => x == form.TargetFolderPath)) { string[] itemText = { form.SourceFolderPath, form.TargetFolderPath, String.Join(",", form.Extensions), form.Memo }; ListViewItem item = new ListViewItem(itemText); listView1.Items.RemoveAt(index); listView1.Items.Insert(index, item); BackupFolderInfos[index].SourceFolderPath = form.SourceFolderPath; BackupFolderInfos[index].TargetFolderPath = form.TargetFolderPath; BackupFolderInfos[index].Extensions = form.Extensions; BackupFolderInfos[index].Memo = form.Memo; SaveConfig(); } else { MessageBox.Show("バックアップ元フォルダのなかにバックアップ先のフォルダを指定することはできません!", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else MessageBox.Show("存在するフォルダでないと登録できません!", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } form.Dispose(); } void LoadConfig() { string path = Application.UserAppDataPath + "\\config.xml"; if(!File.Exists(path)) return; XmlSerializer xml = new XmlSerializer(typeof(Config)); StreamReader sr = new StreamReader(path); Config config = (Config)xml.Deserialize(sr); sr.Close(); BackupFolderInfos = config.BackupFolderInfos; foreach(BackupFolderInfo info in BackupFolderInfos) { string extensions; if(info.Extensions != null) extensions = String.Join(", ", info.Extensions); else extensions = ""; string[] item = { info.SourceFolderPath, info.TargetFolderPath, extensions, info.Memo }; listView1.Items.Add(new ListViewItem(item)); } } } |
実際にバックアップをするときに特定の拡張子をもつファイルはバックアップの調査対象から外します。またアクセス拒否をされた場合はスキップして処理を続けることができるようにしています。
GetSelectedItemIndex()はリストビューコントロールで上から何番目のアイテムが選択されているかを取得します(一番上は0番目)。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public partial class Form1 : Form { int GetSelectedItemIndex() { int ret = -1; Invoke((Action)(() => { var indexes = listView1.SelectedIndices; if(indexes.Count == 1) ret = indexes[0]; })); return ret; } } |
GetSourceFolderPath()メソッドはバックアップ元のフォルダパスを取得します。
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { string GetSourceFolderPath() { int index = GetSelectedItemIndex(); if(index != -1) return BackupFolderInfos[index].SourceFolderPath; else return ""; } } |
GetTargetFolderPath()メソッドはバックアップ先のフォルダパスを取得します。
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { string GetTargetFolderPath() { int index = GetSelectedItemIndex(); if(index != -1) return BackupFolderInfos[index].TargetFolderPath; else return ""; } } |
GetExtensions()メソッドはバックアップの対象外にされている拡張子(「.」は含めない)を取得します。
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { string[] GetExtensions() { int index = GetSelectedItemIndex(); if(index != -1) return BackupFolderInfos[index].Extensions; else return new string[]{""}; } } |
GetSourceFilePaths()メソッドはバックアップ元のフォルダ内にあるファイルパスを取得します。指定された拡張子は対象から外します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public partial class Form1 : Form { public void GetSourceFilePaths(string folder, string searchPattern, List<string> filePaths, List<string> AccessDeniedFolder, string[] extensions, FormBackupProgress formBackupProgress) { if(StopBackupIfCancel(formBackupProgress)) return; string[] fs = Directory.GetFiles(folder, searchPattern, SearchOption.TopDirectoryOnly); fs = fs.Where(x => { FileInfo info = new FileInfo(x); return extensions == null || !extensions.Any(x1 => "." + x1 == info.Extension && ("." + x1).Length == info.Extension.Length); }).ToArray(); filePaths.AddRange(fs); string[] subFolders = Directory.GetDirectories(folder); foreach(string path in subFolders) { try { GetSourceFilePaths(path, searchPattern, filePaths, AccessDeniedFolder, extensions, formBackupProgress); } catch(Exception ex) { // アクセスを拒否された場合 AccessDeniedFolder.Add(path); } } } } |
GetSourceFolderPaths()メソッドはバックアップ元のフォルダ内にあるフォルダのパスを取得します。指定された拡張子は対象から外します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public partial class Form1 : Form { public void GetSourceFolderPaths(string folder, string searchPattern, List<string> filePaths, List<string> AccessDeniedFolder, FormBackupProgress formBackupProgress) { if(StopBackupIfCancel(formBackupProgress)) return; string[] fs = Directory.GetDirectories(folder, searchPattern, SearchOption.TopDirectoryOnly); filePaths.AddRange(fs); foreach(string path in fs) { try { GetSourceFolderPaths(path, searchPattern, filePaths, AccessDeniedFolder, formBackupProgress); } catch(Exception ex) { // アクセスを拒否された場合 AccessDeniedFolder.Add(path); } } } } |
実際にバックアップを行なうメソッドです。バックアップ元のフォルダ内にあるフォルダとファイルを取得する処理だけが変更されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
public partial class Form1 : Form { bool Backup(string sourceFolder, string targetFolder) { if (!CheckFolderPaths(sourceFolder, targetFolder)) return false; FormBackupProgress formBackupProgress = new FormBackupProgress(); formBackupProgress.Show(); List<string> sourceFilePaths = new List<string>(); List<string> AccessDeniedFolder = new List<string>(); formBackupProgress.GetProgressBarGetSourceFiles().Maximum = 2; GetSourceFilePaths(sourceFolder, "*", sourceFilePaths, AccessDeniedFolder, GetExtensions(), formBackupProgress); if (StopBackupIfCancel(formBackupProgress)) { Invoke((Action)(() => { formBackupProgress.IsEnd = true; formBackupProgress.Dispose(); })); return false; } if (sourceFilePaths.Count == 0) { Invoke((Action)(() => { formBackupProgress.IsEnd = true; formBackupProgress.Dispose(); })); return false; } else { Invoke((Action)(() => { formBackupProgress.GetProgressBarGetSourceFiles().Value = 1; })); } List<string> sourceFolderPaths = new List<string>(); GetSourceFolderPaths(sourceFolder, "*", sourceFolderPaths, AccessDeniedFolder, formBackupProgress); if (StopBackupIfCancel(formBackupProgress)) { Invoke((Action)(() => { formBackupProgress.IsEnd = true; formBackupProgress.Dispose(); })); return false; } else { Invoke((Action)(() => { formBackupProgress.GetProgressBarGetSourceFiles().Value = 2; })); } string[] folderPaths = sourceFolderPaths.ToArray(); string[] filePaths = sourceFilePaths.ToArray(); // ここから下は前回と同じ // } } |