using ryCommon; using ryControls; using ScintillaNET; using SuperDesign.Tools.SmartEditor; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using 开发辅助工具.Tools.SmartEditor; using static ScintillaNET.Style; using static System.Net.Mime.MediaTypeNames; namespace ScintillaNET_FindReplaceDialog { public partial class FrmFinding : Form { public FrmFinding() { InitializeComponent(); } bool IsExit = false; bool IsRunning = false; /// /// 搜索配置 /// public SearchDirConfig SearchConfig=new SearchDirConfig(); /// /// 获取待搜索的文件数量 /// /// private int GetFileCount() { var count = 0; GetCount(SearchConfig.SearchDir); return count; void GetCount(string folder) { if(!SearchConfig.SearchHiddenDir) { DirectoryInfo directory = new DirectoryInfo(folder); if((directory.Attributes & FileAttributes.Hidden)== FileAttributes.Hidden) { return; } } var split_ext = SearchConfig.Exts.Split(';'); for (int i = 0; i < split_ext.Length; i++) { if (IsExit) { break; } var files = System.IO.Directory.GetFiles(folder, split_ext[i]); if (files != null) count += files.Length; } if (SearchConfig.SearchSubDir) { if (IsExit) { return ; } var folder_list = System.IO.Directory.GetDirectories(folder); if (folder_list != null) { for (int i = 0; i < folder_list.Length; i++) { if (IsExit) { break; } GetCount(folder_list[i]); } } } } } private void ShowText(string text) { this.Invoke(new Action(() => { label1.Text = "状态:" + text; })); } private List SearchText(string Text) { var list = new List(); var start_i = 0; var all_text = Text; while (start_i>=0) { CharacterRange foundRange = new CharacterRange(start_i, Text.Length); try { if (SearchConfig.SearchMode == 2)//正则 { Regex r = new Regex(SearchConfig.FindText, SearchConfig.RegexOptions); Match m = r.Match(all_text); if (!m.Success) return list; int start = foundRange.CpMin + all_text.Substring(0, m.Index).Length; int end = all_text.Substring(m.Index, m.Length).Length; var LineNum = GetLineNum(start, out var LinePos,out var LineText); list.Add(new CharacterRange(start, start + end) {LineText= LineText, LineNum=LineNum, LinePos=LinePos,RangeText=Text.Substring(start,end) }); start_i = start+end + 1; } else { string textToFind = SearchConfig.SearchMode == 1 ? FindReplace.Transform(SearchConfig.FindText) : SearchConfig.FindText; int start = 0; if ((SearchConfig.SearchFlags & SearchFlags.MatchCase) == SearchFlags.MatchCase) //忽略大小写 { start=Text.IndexOfEx(textToFind,start_i); } else { start = Text.IndexOf(textToFind, start_i, StringComparison.Ordinal); } int end = textToFind.Length; if (start >= 0) { if ((SearchConfig.SearchFlags & SearchFlags.WholeWord) == SearchFlags.WholeWord) //全词匹配 { if (start >= 0) { bool Word_Start = false; bool Word_End = false; if (start == 0) { Word_Start = true; } else { var char_i = Text[start - 1]; if ((char_i >= '0' && char_i <= '9') || (char_i >= 'a' && char_i <= 'z') || (char_i >= 'A' && char_i <= 'Z')) { Word_Start = false; } else { Word_Start = true; } } if ((start + end)>=(Text.Length-1)) { Word_End = true; } else { var char_i = Text[start + end]; if ((char_i >= '0' && char_i <= '9') || (char_i >= 'a' && char_i <= 'z') || (char_i >= 'A' && char_i <= 'Z')) { Word_End = false; } else { Word_End = true; } } if (Word_Start && Word_End) { var LineNum = GetLineNum(start, out var LinePos, out var LineText); list.Add(new CharacterRange(start, start + end) { LineText = LineText, LineNum = LineNum, LinePos = LinePos, RangeText = Text.Substring(start, end) }); } start_i = start+ end + 1; } else { break; } } else if ((SearchConfig.SearchFlags & SearchFlags.WordStart) == SearchFlags.WordStart) //开头匹配 { if (start >= 0) { bool Word_Start = false; if (start == 0) { Word_Start = true; } else { var char_i = Text[start - 1]; if ((char_i >= '0' && char_i <= '9') || (char_i >= 'a' && char_i <= 'z') || (char_i >= 'A' && char_i <= 'Z')) { Word_Start = false; } else { Word_Start = true; } } if (Word_Start) { var LineNum = GetLineNum(start, out var LinePos, out var LineText); list.Add(new CharacterRange(start, start + end) { LineText = LineText, LineNum = LineNum, LinePos = LinePos, RangeText = Text.Substring(start, end) }); } start_i = start+ end + 1; } else { break; } } else { var LineNum = GetLineNum(start, out var LinePos, out var LineText); list.Add(new CharacterRange(start, start + end) { LineText = LineText, LineNum = LineNum, LinePos = LinePos, RangeText = Text.Substring(start, end) }); start_i = start+end + 1; } } else { break; } } } catch (ArgumentException ex) { } if (foundRange.CpMin == foundRange.CpMax) { break; } if (start_i < Text.Length) { all_text = Text.Substring(start_i); } } //根据位置来获取该位置所在行 int GetLineNum(int pos,out int LinePos,out string LineText) { LinePos = -1; var split_txt = Text.Split('\n'); var count = 0; for (int i = 0; i < split_txt.Length; i++) { if (count+split_txt[i].Length+1>=pos) { LinePos = count; LineText = split_txt[i]; return i; } else { count += split_txt[i].Length+1; } } LineText = ""; return -1; } return list; } /// /// 获取待搜索的文件数量 /// /// private void SearchFiles() { IsRunning = true; var count = 0; ShowText("正在统计总文件数..."); var total_count= GetFileCount(); this.Invoke(new Action(() => { progressBar1.Maximum = total_count; })); ShowText("统计结束,正在查找..."); Dictionary> dict_list = new Dictionary>(); new Thread(Start).Start(); void Start() { Search(SearchConfig.SearchDir); this.Invoke(new Action(() => { var opens = System.Windows.Forms.Application.OpenForms; for (int i = 0; i < opens.Count; i++) { if (opens[i] is FrmResultText frm2) { frm2.findAllResultsPanel1.UpdateFindAllResults(dict_list); frm2.Show(FrmMainEditor.MainEditor.DockPanel, WeifenLuo.WinFormsUI.Docking.DockState.DockBottom); IsRunning = false; this.Close(); return; } } FrmResultText frm = new FrmResultText(); frm.findAllResultsPanel1.UpdateFindAllResults(dict_list); frm.Show(FrmMainEditor.MainEditor.DockPanel, WeifenLuo.WinFormsUI.Docking.DockState.DockBottom); IsRunning = false; this.Close(); })); } void Search(string folder) { if (!SearchConfig.SearchHiddenDir) { DirectoryInfo directory = new DirectoryInfo(folder); if ((directory.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { return; } } var split_ext = SearchConfig.Exts.Split(';'); for (int i = 0; i < split_ext.Length; i++) { if (IsExit) { break; } var files = System.IO.Directory.GetFiles(folder, split_ext[i]); if (files != null) { for (int f = 0; f < files.Length; f++) { ShowText("正在查找=>" + files[f]); if(SearchConfig.IgnoreBinExt) { var ext= Path.GetExtension(files[f]); if (";.exe;.apk;.bin;.dll;.msi;.sys;.zip;.rar;.7z;.iso;.cab;.tar;.tgz;.crx;.psd;.jpg;.bmp;.gif;.webp;.png;.jpeg;.ico;.mp3;.wav;.ape;.aac;.flac;.ogg;.mp4;.rmvb;.flv;.wmv;.mov;.3gp;.mpeg;".IndexOfEx(";" + ext + ";") >= 0) { continue; } } if(SearchConfig.LimitFileSize>0) { if(RyFiles.GetFileSize(files[f])> SearchConfig.LimitFileSize) { continue; } } var text = RyFiles.ReadAllText(files[f]); var find_list= SearchText(text); if(find_list.Count>0) { dict_list.Add(files[f],find_list); } count++; if (count <= total_count) { this.Invoke(new Action(() => { progressBar1.Value = count; })); } } } } if (SearchConfig.SearchSubDir) { if (IsExit) { return; } var folder_list = System.IO.Directory.GetDirectories(folder); if (folder_list != null) { for (int i = 0; i < folder_list.Length; i++) { if (IsExit) { break; } if(SearchConfig.SkipDirName.Length>0) { var name = Path.GetFileName(folder_list[i]); if((";"+SearchConfig.SkipDirName+";").IndexOfEx(";"+name+";")>=0) { continue; } } Search(folder_list[i]); } } } } } private void FrmFinding_Load(object sender, EventArgs e) { } private void BtnClose_Click(object sender, EventArgs e) { IsExit = true; } private void FrmFinding_FormClosing(object sender, FormClosingEventArgs e) { if (IsRunning) { e.Cancel = true; } } private void FrmFinding_Shown(object sender, EventArgs e) { SearchFiles(); } } public class FindResult { public string Path { get; set; } = ""; public CharacterRange Result { get; set; } } public class SearchDirConfig { /// /// 搜索文件夹 /// public string SearchDir { get; set; } = ""; /// /// 是否搜索子目录 /// public bool SearchSubDir { get; set; } = false; /// /// 忽略常见二进制格式 /// public bool IgnoreBinExt { get; set; } = true; /// /// 是否搜索隐藏目录 /// public bool SearchHiddenDir { get; set; } = false; /// /// 要查找的文本 /// public string FindText { get; set; } = ""; /// /// 要替换的文本 /// public string ReplaceText { get; set; } = ""; /// /// 要搜索的扩展名列表 /// public string Exts { get; set; } = ""; /// /// 跳过的目录名 /// public string SkipDirName { get; set; } = ""; /// /// 超过该大小的文件将不再查找 /// public long LimitFileSize { get; set; } = 0; /// /// 是否开启替换模式,默认是查找模式 /// public bool ReplaceModeOn { get; set; } = false; /// /// 正则表达式选项 /// public RegexOptions RegexOptions { get; set; } = RegexOptions.None; public ScintillaNET.SearchFlags SearchFlags { get; set; } /// /// 查找模式,0为普通查找,1表示扩展查找,2表示正则查找 /// public int SearchMode { get; set; } = 0; } }