------ #### SuperDesign V3.0.2412.2001 - *.[新增]新增程序更新日志设置和自动发布功能。 - *.[修复]修复Post数据格式不正确时双击文本框会导致软件闪退的BUG。
418 lines
17 KiB
C#
418 lines
17 KiB
C#
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;
|
|
/// <summary>
|
|
/// 搜索配置
|
|
/// </summary>
|
|
public SearchDirConfig SearchConfig=new SearchDirConfig();
|
|
/// <summary>
|
|
/// 获取待搜索的文件数量
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
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<CharacterRange> SearchText(string Text)
|
|
{
|
|
var list = new List<CharacterRange>();
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// 获取待搜索的文件数量
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private void SearchFiles()
|
|
{
|
|
IsRunning = true;
|
|
var count = 0;
|
|
ShowText("正在统计总文件数...");
|
|
var total_count= GetFileCount();
|
|
this.Invoke(new Action(() =>
|
|
{
|
|
progressBar1.Maximum = total_count;
|
|
}));
|
|
ShowText("统计结束,正在查找...");
|
|
Dictionary<string,List<CharacterRange>> dict_list = new Dictionary<string, List<CharacterRange>>();
|
|
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
|
|
{
|
|
/// <summary>
|
|
/// 搜索文件夹
|
|
/// </summary>
|
|
public string SearchDir { get; set; } = "";
|
|
/// <summary>
|
|
/// 是否搜索子目录
|
|
/// </summary>
|
|
public bool SearchSubDir { get; set; } = false;
|
|
/// <summary>
|
|
/// 忽略常见二进制格式
|
|
/// </summary>
|
|
public bool IgnoreBinExt { get; set; } = true;
|
|
/// <summary>
|
|
/// 是否搜索隐藏目录
|
|
/// </summary>
|
|
public bool SearchHiddenDir { get; set; } = false;
|
|
/// <summary>
|
|
/// 要查找的文本
|
|
/// </summary>
|
|
public string FindText { get; set; } = "";
|
|
/// <summary>
|
|
/// 要替换的文本
|
|
/// </summary>
|
|
public string ReplaceText { get; set; } = "";
|
|
/// <summary>
|
|
/// 要搜索的扩展名列表
|
|
/// </summary>
|
|
public string Exts { get; set; } = "";
|
|
/// <summary>
|
|
/// 跳过的目录名
|
|
/// </summary>
|
|
public string SkipDirName { get; set; } = "";
|
|
/// <summary>
|
|
/// 超过该大小的文件将不再查找
|
|
/// </summary>
|
|
public long LimitFileSize { get; set; } = 0;
|
|
/// <summary>
|
|
/// 是否开启替换模式,默认是查找模式
|
|
/// </summary>
|
|
public bool ReplaceModeOn { get; set; } = false;
|
|
/// <summary>
|
|
/// 正则表达式选项
|
|
/// </summary>
|
|
public RegexOptions RegexOptions { get; set; } = RegexOptions.None;
|
|
public ScintillaNET.SearchFlags SearchFlags { get; set; }
|
|
/// <summary>
|
|
/// 查找模式,0为普通查找,1表示扩展查找,2表示正则查找
|
|
/// </summary>
|
|
public int SearchMode { get; set; } = 0;
|
|
}
|
|
}
|