C调用everything工具进行文件搜索功能
C#调用everything工具进行文件搜索功能
前言:
根据需求,现在需要任意输入输入批次号,然后软件到共享文件夹里面搜索这个CSV文件拷贝到我们的分拣表格里面,以及搜索这个批次号下面的文件夹里面的 可以运行 的加工文件拷贝到Z盘里面(Z盘存在网络映射文件夹)
难点:
1.电脑自带的搜索工具遍历搜索比较困难,文件多会卡住程序;
2.选取指定路径时,可能存在找不到路径(访问权限不足,导致无法访问共享文件夹;防火墙或安全软件阻止了网络连接等等);如果您的程序以管理员身份运行,则可能会受到UAC(用户帐户控制)的影响,导致无法访问网络映射驱动器
3.需求需要根据批次号,再去路径下,找到该批次号名称所在的文件夹,然后找到所有的加工文件,一键复制到指定目录
准备工作:
配置 | 要求 |
系统 | windows10以上 |
软件 | Visual Studio 2022、everything |
接口 | ES |
开始
新建一个winform窗体项目,找到该项目的文件目录地址,将Everything” 搜索引擎、ES下载放在debug文件夹的bin目录下
(找最新版的就好,先下载好,自己试试能不能搜索自己想要的文件);
:ES 是让用户在命令提示符中使用 Everything 搜索的命令行接口。
需求
- Everything 必须已安装并运行中。
窗体设计
大概设计成这种窗体,样式自定义就好
我的程序名称为:
控件 | 控件名称 | 控件 | 控件名称 |
label6 | 打孔文件后缀 | label4 | 分拣文件后缀 |
label5 | 批次号: | btnCopy | 复制 |
txtChType | .mpr | txtType | .csv |
LBlChild | label1 | ||
btnSz | 地址设置 | lBl | |
txtbox | prog |
附上一个小程序:搜索所有窗体,将窗体的名称输出:
foreach (Control control in this.Controls)
{
string name = control.Name;
string text = control.Text;
Console.WriteLine($"Name: {name}, Text: {text}");
}
设计主要代码:
代码保存与读取的路径存放在App.config,方便下次读取与保存
配置文件准备:App.config:
添加一个 “CmdHelper” 工具类用于通过启动ES执行相关命令以便执行Everything搜索
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace everythingTest
{
internal class CmdHelper
{
private static string CmdPath = @"C:\Windows\System32\cmd.exe";
public static void RunCmd(string cmd, out string output)
{
cmd = cmd.Trim().TrimEnd('&') + "&exit";
using (Process p = new Process())
{
p.StartInfo.FileName = CmdPath;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
//向cmd窗口写入命令
p.StandardInput.WriteLine(cmd);
p.StandardInput.AutoFlush = true;
//获取cmd窗口的输出信息
output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
}
}
}
}
1.模糊搜索功能
//模糊搜索
private void search_Changed(object sender, EventArgs e)
{
//要求:读取csv
// 读取配置文件中的路径
string folderpath = ConfigurationManager.AppSettings["FolderPath"];
//设置关键字
string name = this.txtbox.Text.Trim();
//设置搜索文件扩展名
string type = txtType.Text.Trim();
string cmd = $@"es.exe *{name}*{type} -path {folderpath}";
CmdHelper.RunCmd(cmd, out string str);
lBl.DataSource = GetFileList(str);
lBl.Refresh();
}
2.文件选中操作事件
//文件选中 操作
private void thevalueChanged(object sender, EventArgs e)
{
LBlChild.DataSource = null;
LBlChild.Items.Clear();
label3.Text = "";
if (lBl.SelectedItem == null || string.IsNullOrEmpty(lBl.SelectedItem.ToString()))
{
return;
}
// 读取文件名 比如B230223030
string fileName = Path.GetFileNameWithoutExtension(lBl.SelectedItem.ToString());
// 读取配置文件中要搜索的路径 比如C:\\Users\\DELL\\Desktop
string folderpath2 = ConfigurationManager.AppSettings["FolderPath2"];
//直接获取文件夹名称的路径 例如搜索demo C:\\Users\\DELL\\Desktop\\demo
string cmd = $"es.exe -s folder:ww:{fileName} {folderpath2}";
CmdHelper.RunCmd(cmd, out string str);
var list = GetFileList(str);
//获取文件夹全路径
string tempath = list[0];
string path = $"{tempath}\\MPR56";
//需要搜索的类型
string type = txtChType.Text.Trim();
string cmd2 = $@"es.exe *{type} -path {path}";
CmdHelper.RunCmd(cmd2, out string str2);
var list2 = GetFileList(str2);
LBlChild.DataSource = list2;
LBlChild.Refresh();
label3.Visible = true;
label3.Text = $"在MPR56文件夹共搜索出{list2.Count - 1}个文件";
// 控件全选
for (int i = 0; i < LBlChild.Items.Count; i++)
{
LBlChild.SetSelected(i, true);
}
}
3.一键复制操作
//复制
private void SelectedItems(object sender, EventArgs e)
{
List<string> selectedFiles = new List<string>();
foreach (string file in lBl.SelectedItems)
{
selectedFiles.Add(file);
}
//复制文件到指定文件夹
string targetFolder = ConfigurationManager.AppSettings["Path"];
foreach (string file in selectedFiles)
{
string fileName = Path.GetFileName(file);
string targetPath = Path.Combine(targetFolder, fileName);
File.Copy(file, targetPath, true); //覆盖已存在的文件
}
//搜索文件夹下的MPR56的加工文件
List<string> selectedFiles2 = new List<string>();
foreach (string file in LBlChild.SelectedItems)
{
selectedFiles2.Add(file);
}
//复制mpr文件到指定文件夹
string Path2 = ConfigurationManager.AppSettings["Path2"];
foreach (string file in selectedFiles2)
{
string fileName = Path.GetFileName(file);
string targetPath = Path.Combine(Path2, fileName);
if (!string.IsNullOrEmpty(file))
{
File.Copy(file, targetPath, true); //覆盖已存在的文件
}
}
for (int i = 1; i <= LBlChild.Items.Count - 1; i++)
{
prog.Maximum = LBlChild.Items.Count -1;
prog.Minimum = 1;
prog.Visible = true;
prog.Value = i;
prog.Refresh();
Thread.Sleep(20);
prog.Visible = false;
}
}
4.文件地址修改
先在主窗体设置显示新的窗体“sz”(名字起的有点随意),然后
//设置
private void btnSz_Click(object sender, EventArgs e)
{
sz s = new sz();
s.Show();
}
5.设置窗体代码(记得添加新的窗体)
public sz()
{
InitializeComponent();
// 读取config文件中的文件夹路径
lbl_csvAddress.Text = ConfigurationManager.AppSettings["FolderPath"];
label2.Text = ConfigurationManager.AppSettings["FolderPath2"];
label3.Text = ConfigurationManager.AppSettings["Path"];
label4.Text = ConfigurationManager.AppSettings["Path2"];
}
private void btn_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
string name = (string)btn.Tag;
//string name = null;
// 使用FolderBrowserDialog控件选择文件夹路径
FolderBrowserDialog folderDialog = new FolderBrowserDialog();
if (folderDialog.ShowDialog() == DialogResult.OK)
{
// 获取用户选择的文件夹路径
string sharedFolderPath = folderDialog.SelectedPath;
// 将文件夹路径保存到config文件中
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//根据名称绑定相应的config位置
config.AppSettings.Settings["" + name + ""].Value = folderDialog.SelectedPath;
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
// 更新界面上的标签显示文件夹路径
lbl_csvAddress.Text = ConfigurationManager.AppSettings["FolderPath"];
label2.Text = ConfigurationManager.AppSettings["FolderPath2"];
label3.Text = ConfigurationManager.AppSettings["Path"];
label4.Text = ConfigurationManager.AppSettings["Path2"];
}
private void btnMag_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.CheckFileExists = false;
openFileDialog.ValidateNames = false;
openFileDialog.FileName = "Folder Selection.";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string folderPath = Path.GetDirectoryName(openFileDialog.FileName);
//textBox1.Text = folderPath;
}
}
新窗体样式大概这个样子就好:
执行程序:
执行先启动everything,如果需要读取网络映射盘的内容,需要提前设置,点击工具-> 再次点击选项->点击文件夹,如图:
效果图:
本次要点在于文件的模糊搜索功能,自行设计出想要的需求,参考使用例子:
限制
ES 无法访问书签或筛选器。
例子
导出全部 mp3 文件为 Everything 文件列表 mp3.efu:
es.exe *.mp3 -export-efu mp3.efu
显示最大的 10 个文件:
es.exe -sort size -n 10
显示最近修改的 10 个文件:
es.exe -sort dm -n 10
高亮搜索关键词 foo bar:
es.exe foo bar -highlight
使 ES 显示大小分栏、修改日期分栏和设置颜色且为默认设置:
es.exe -size -dm -sizecolor 0x0d -dmcolor 0x0b -save-settings
以下为官方文档基本的部分参考,需要详细设计,请参考 选项:
常规命令行选项
以下命令兼容于任意版本 Everything。
-r
-regex
使用正则表达式搜索。
-i
-case
匹配大小写。
-w
-ww
-whole-word
-whole-words
匹配全字。
-p
-match-path
匹配全路径和文件名。
-h
-help
显示帮助。
-o
-offset
以以零为基础偏移显示搜索结果。
-n
-max-results
限定结果显示数目为
。 -s
以全路径排序。
以上不对的地方请指正,需要源代码的可以私信我,文档供大家参考与学习。