From cb9f5eb6632a791a2501e911f0132c3bb80ba2bf Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 26 Oct 2021 17:39:24 +0100 Subject: [PATCH] WIP: search directory with function callback --- IO/SmartFileSystem.cs | 166 ++++++++++++++++++++++++++++++++++++++++++ MainForm.Designer.cs | 2 + MainForm.cs | 84 +++++++++++++++++++-- Models/AppSession.cs | 20 +++++ 4 files changed, 267 insertions(+), 5 deletions(-) create mode 100644 IO/SmartFileSystem.cs diff --git a/IO/SmartFileSystem.cs b/IO/SmartFileSystem.cs new file mode 100644 index 0000000..bb37373 --- /dev/null +++ b/IO/SmartFileSystem.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.AccessControl; +using System.Text; +using System.Threading.Tasks; + +namespace RandomFileRunner.IO +{ + public class SmartFileSystem + { + + + public static List GetFiles(string path, string pattern) + { + List fileList = new List(); + List directoryList = new List(); + + directoryList.Add(path); + + while (true) + { + if (directoryList.Count <= 0) + { + break; + } + + string directory = directoryList.First(); + directoryList.RemoveAt(0); + + if (IsDirectoryAccessible(directory)) + { + IEnumerable searchDirList = new List(); + + try + { + searchDirList = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly); + } + catch (Exception) + { + continue; + } + + foreach (string item in searchDirList) + { + if (!IsDirectoryAccessible(item)) + { + continue; + } + + directoryList.Add(item); + } + + foreach (string item in Directory.EnumerateFiles(directory, pattern, SearchOption.TopDirectoryOnly)) + { + if (!IsFileAccessible(item)) + { + continue; + } + + fileList.Add(item); + } + } + } + + return fileList; + } + + public static void GetFiles(string path, string pattern, Func callback) + { + List directoryList = new List(); + ulong searchCount = 0; + + directoryList.Add(path); + searchCount++; + + while (true) + { + if (directoryList.Count <= 0) + { + break; + } + + string directory = directoryList.First(); + directoryList.RemoveAt(0); + + callback(null, searchCount, directoryList.Count); + + if (IsDirectoryAccessible(directory)) + { + IEnumerable searchDirList = new List(); + + try + { + searchDirList = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly); + } + catch (Exception) + { + continue; + } + + foreach (string item in searchDirList) + { + if (!IsDirectoryAccessible(item)) + { + continue; + } + + directoryList.Add(item); + searchCount++; + + callback(null, searchCount, directoryList.Count); + } + + foreach (string item in Directory.EnumerateFiles(directory, pattern, SearchOption.TopDirectoryOnly)) + { + if (!IsFileAccessible(item)) + { + continue; + } + + callback(item, searchCount, directoryList.Count); + } + } + } + } + + public static bool IsFileAccessible(string filename) + { + if (string.IsNullOrWhiteSpace(filename)) return false; + if (!File.Exists(filename)) return false; + + try + { + FileInfo fi = new FileInfo(filename); + fi.GetAccessControl(); + } + catch + { + return false; + } + + return true; + } + + public static bool IsDirectoryAccessible(string path) + { + if (string.IsNullOrWhiteSpace(path)) return false; + if (!Directory.Exists(path)) return false; + + try + { + DirectoryInfo di = new DirectoryInfo(path); + di.GetAccessControl(); + } + catch + { + return false; + } + + return true; + } + + } +} diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs index c67629a..4864909 100644 --- a/MainForm.Designer.cs +++ b/MainForm.Designer.cs @@ -333,6 +333,8 @@ namespace RandomFileRunner // // textBox1 // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.textBox1.BackColor = System.Drawing.Color.Transparent; this.textBox1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); this.textBox1.HighlightImage = ((System.Drawing.Image)(resources.GetObject("textBox1.HighlightImage"))); diff --git a/MainForm.cs b/MainForm.cs index 113226b..7db8dee 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -1,8 +1,11 @@ -using RyzStudio.Windows.Forms; +using RandomFileRunner.IO; +using RyzStudio.Windows.Forms; using System; +using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; +using System.Threading.Tasks; using System.Windows.Forms; namespace RandomFileRunner @@ -13,7 +16,9 @@ namespace RandomFileRunner protected OptionsForm optionsForm = null; protected bool isBusy = false; + protected bool requestCancel = false; + protected List foundFiles = null; protected Process currentProcess = null; @@ -48,13 +53,13 @@ namespace RandomFileRunner ThreadControl.SetValue(pictureBox1, (isBusy ? AppResource.loading_block : null)); ThreadControl.SetEnable(textBox1, !isBusy); - ThreadControl.SetEnable(button2, !isBusy); + //ThreadControl.SetEnable(button2, !isBusy); + button2.LabelText = (isBusy? "&Cancel" : "&Search"); ThreadControl.SetEnable(button3, !isBusy); ThreadControl.SetEnable(button4, !isBusy); ThreadControl.SetEnable(memoBox1, !isBusy); ThreadControl.SetEnable(button5, !isBusy); - - ThreadControl.SetEnable(button1, !isBusy); + //ThreadControl.SetEnable(button1, !isBusy); } } @@ -72,14 +77,77 @@ namespace RandomFileRunner memoBox1.Text += line + Environment.NewLine; } + protected bool SearchDirecory_OnFound(string file, ulong searchCount, int searchQueue) + { + if (!string.IsNullOrWhiteSpace(file)) + { + foundFiles.Add(file); + } + + //ThreadControl.SetText(label2, foundFiles.Count.ToString()); + ThreadControl.SetText(label2, foundFiles.Count.ToString("#,#", System.Globalization.CultureInfo.CurrentCulture) + Environment.NewLine + searchQueue.ToString("#,#", System.Globalization.CultureInfo.CurrentCulture)); + + return true; + } + + /// /// Search /// /// /// - private void button2_MouseClick(object sender, MouseEventArgs e) + private async void button2_MouseClick(object sender, MouseEventArgs e) { + await Task.Run(() => + { + if (this.IsBusy) + { + requestCancel = true; + button2.LabelText = "&Cancelling..."; + return; + } + + this.IsBusy = true; + requestCancel = false; + + foundFiles = new List(); + currentProcess = null; + + string[] itemList = memoBox1.Text?.Trim().Split('\n'); + for (int i=0; i< itemList.Length; i++) + { + if (string.IsNullOrWhiteSpace(itemList[i])) continue; + if (requestCancel) break; + + string item = itemList[i]?.Trim(); + + if (File.Exists(item)) + { + if (SmartFileSystem.IsFileAccessible(item)) + { + foundFiles.Add(item); + ThreadControl.SetText(label2, foundFiles.Count.ToString()); + + continue; + } + } + + if (Directory.Exists(item)) + { + SmartFileSystem.GetFiles(item, "*.txt", SearchDirecory_OnFound); + + ThreadControl.SetText(label2, foundFiles.Count.ToString()); + + continue; + } + } + + ThreadControl.SetText(label2, foundFiles.Count.ToString("#,#", System.Globalization.CultureInfo.CurrentCulture) + " File" + ((foundFiles.Count == 1) ? "" : "s") + " Found"); + + this.IsBusy = false; + requestCancel = false; + }); } /// @@ -169,10 +237,16 @@ namespace RandomFileRunner } + /// + /// Close + /// + /// + /// private void button1_MouseClick(object sender, MouseEventArgs e) { this.Close(); } + } } diff --git a/Models/AppSession.cs b/Models/AppSession.cs index d99d2f8..cf6c473 100644 --- a/Models/AppSession.cs +++ b/Models/AppSession.cs @@ -2,6 +2,26 @@ { public class AppSession { + public class HotKeyOptions + { + public bool IsCtrl { get; set; } = false; + public bool IsAlt { get; set; } = false; + public bool IsShift { get; set; } = false; + public int Key { get; set; } = (int)System.Windows.Forms.Keys.None; + + public int ModifierCode => ((this.IsAlt ? 1 : 0) + (this.IsCtrl ? 2 : 0) + (this.IsShift ? 4 : 0)); + + public System.Windows.Forms.Keys KeyCode => (System.Windows.Forms.Keys)this.Key; + } + + + public bool SearchTopDirectoryOnly { get; set; } = false; + + public bool ClosePrevOnNext { get; set; } = false; + + public HotKeyOptions NextHotKey { get; set; } = null; + + public bool AlwaysOnTop { get; set; } = false; public int NoFrames { get; set; } = 3;