c# everthing

using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace EverythingLikeApp
{
    public partial class MainForm : Form
    {
        // Everything API 常量
        private const int EVERYTHING_OK = 0;
        private const int EVERYTHING_ERROR_MEMORY = 1;
        private const int EVERYTHING_ERROR_IPC = 2;
        private const int EVERYTHING_ERROR_REGISTERCLASSEX = 3;
        private const int EVERYTHING_ERROR_CREATEWINDOW = 4;
        private const int EVERYTHING_ERROR_QUERY = 5;

        // Everything API 导入
        [DllImport(@"C:\Program Files\Everything\Everything64.dll", CharSet = CharSet.Unicode)]
        private static extern int Everything_SetSearch(string lpSearchString);

        [DllImport(@"C:\Program Files\Everything\Everything64.dll")]
        private static extern bool Everything_Query(bool bWait);

        [DllImport(@"C:\Program Files\Everything\Everything64.dll")]
        private static extern int Everything_GetNumResults();

        [DllImport(@"C:\Program Files\Everything\Everything64.dll", CharSet = CharSet.Unicode)]
        private static extern void Everything_GetResultFullPathName(int nIndex, StringBuilder lpString, int nMaxCount);

        [DllImport(@"C:\Program Files\Everything\Everything64.dll")]
        private static extern int Everything_GetLastError();
        [DllImport(@"C:\Program Files\Everything\Everything64.dll", CharSet = CharSet.Unicode)]
        public static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount);

        private ContextMenuStrip listViewContextMenu;
        // 添加缓存机制
        private ConcurrentDictionary<string, ListViewItem[]> searchCache = new ConcurrentDictionary<string, ListViewItem[]>();
        private CancellationTokenSource searchTokenSource;
        // 在类成员变量区域添加
        private const int BUFFER_SIZE = 260; // Windows MAX_PATH 标准值
        public MainForm()
        {
            InitializeComponent();
            InitializeContextMenu();
            SetupListView();
            CheckEverythingService();
        }

        private void InitializeContextMenu()
        {
            listViewContextMenu = new ContextMenuStrip();

            // 添加菜单项
            var openItem = new ToolStripMenuItem("打开");
            openItem.Click += (s, e) => OpenSelectedItem();

            var renameItem = new ToolStripMenuItem("重命名");
            renameItem.Click += (s, e) => RenameSelectedItem();

            var openPathItem = new ToolStripMenuItem("打开所在文件夹");
            openPathItem.Click += (s, e) => OpenContainingFolder();

            var copyPathItem = new ToolStripMenuItem("复制路径");
            copyPathItem.Click += (s, e) => CopyItemPath();

            var propertiesItem = new ToolStripMenuItem("属性");
            propertiesItem.Click += (s, e) => ShowProperties();

            listViewContextMenu.Items.AddRange(new ToolStripItem[] {
                openItem, renameItem, openPathItem,
                new ToolStripSeparator(),
                copyPathItem,
                new ToolStripSeparator(),
                propertiesItem
            });
        }

        private void SetupListView()
        {
            listView1.View = View.Details;
            listView1.FullRowSelect = true;
            listView1.Columns.Add("名称", 300);
            listView1.Columns.Add("路径", 500);
            listView1.Columns.Add("大小", 100);
            listView1.Columns.Add("修改日期", 150);

            listView1.MouseDoubleClick += (s, e) => OpenSelectedItem();
            listView1.KeyDown += (s, e) =>
            {
                if (e.KeyCode == Keys.Enter) OpenSelectedItem();
            };
            listView1.ContextMenuStrip = listViewContextMenu;
        }

        private void CheckEverythingService()
        {
            try
            {
                if (Everything_GetLastError() != EVERYTHING_OK)
                {
                    MessageBox.Show("Everything服务未运行,请先启动Everything", "错误",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (DllNotFoundException)
            {
                MessageBox.Show("找不到Everything64.dll,请确保Everything已安装", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 修改后的并行搜索代码
        private async void SearchButton_Click(object sender, EventArgs e)
        {
            string searchText = searchTextBox.Text.Trim();
            if (string.IsNullOrEmpty(searchText)) return;

            searchTokenSource?.Cancel();
            searchTokenSource = new CancellationTokenSource();
            var token = searchTokenSource.Token;

            // 显示加载状态
            UpdateStatus("搜索中...");

            try
            {
                var results = await Task.Run(() =>
                {
                    token.ThrowIfCancellationRequested();

                    // 设置搜索参数
                    Everything_SetSearch(searchText);
                    if (!Everything_Query(true)) return Array.Empty<ListViewItem>();

                    int resultCount = Everything_GetNumResults();
                    var items = new ListViewItem[resultCount];

                    // 使用线程安全的并行处理
                    Parallel.For(0, resultCount, i =>
                    {
                        token.ThrowIfCancellationRequested();

                        // 每个线程使用独立的StringBuilder
                        var localBuilder = new StringBuilder(BUFFER_SIZE);
                        Everything_GetResultFullPathName(i, localBuilder, localBuilder.Capacity);

                        string fullPath = localBuilder.ToString();
                        items[i] = CreateListViewItem(fullPath);
                    });

                    return items;
                }, token);

                if (!token.IsCancellationRequested)
                {
                    DisplayResults(results);
                }
            }
            catch (OperationCanceledException)
            {
                UpdateStatus("搜索已取消");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"搜索出错: {ex.Message}", "错误");
            }
        }

        // 创建ListViewItem的辅助方法
        private ListViewItem CreateListViewItem(string fullPath)
        {
            var item = new ListViewItem(Path.GetFileName(fullPath));
            item.SubItems.Add(fullPath);

            try
            {
                var fileInfo = new FileInfo(fullPath);
                item.SubItems.Add(FormatSize(fileInfo.Length));
                item.SubItems.Add(fileInfo.LastWriteTime.ToString("yyyy-MM-dd HH:mm"));
                item.Tag = fullPath;
            }
            catch
            {
                item.SubItems.Add("");
                item.SubItems.Add("");
            }

            return item;
        }

        // 状态更新方法
        private void UpdateStatus(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateStatus(message)));
                return;
            }
            toolStripStatusLabel1.Text = message;
        }
        // 优化后的文件大小格式化
        private string FormatSize(long bytes)
        {
            if (bytes < 1024) return $"{bytes} B";
            if (bytes < 1048576) return $"{bytes / 1024f:0.##} KB";
            if (bytes < 1073741824) return $"{bytes / 1048576f:0.##} MB";
            return $"{bytes / 1073741824f:0.##} GB";
        }
        // 高效显示结果的方法
        private void DisplayResults(ListViewItem[] items)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(() => DisplayResults(items)));
                return;
            }

            listView1.BeginUpdate();
            try
            {
                listView1.Items.Clear();

                // 使用AddRange批量添加(比逐个添加快10倍以上)
                if (items.Length > 0)
                {
                    listView1.Items.AddRange(items);

                    // 自动调整列宽
                    foreach (ColumnHeader column in listView1.Columns)
                    {
                        column.Width = -2; // -2表示根据内容自动调整
                    }
                }
                else
                {
                    listView1.Items.Add("没有找到匹配结果").ForeColor = Color.Gray;
                }
            }
            finally
            {
                listView1.EndUpdate();
            }
        }
        private void OpenSelectedItem()
        {
            if (listView1.SelectedItems.Count == 0) return;

            string path = listView1.SelectedItems[0].Tag as string;
            if (string.IsNullOrEmpty(path)) return;

            try
            {
                Process.Start(new ProcessStartInfo
                {
                    FileName = path,
                    UseShellExecute = true
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show($"无法打开文件: {ex.Message}", "错误");
            }
        }

        private void RenameSelectedItem()
        {
            if (listView1.SelectedItems.Count == 0) return;

            string oldPath = listView1.SelectedItems[0].Tag as string;
            if (string.IsNullOrEmpty(oldPath)) return;

            string newName = Microsoft.VisualBasic.Interaction.InputBox(
                "输入新文件名:", "重命名", Path.GetFileName(oldPath));

            if (!string.IsNullOrEmpty(newName))
            {
                try
                {
                    string newPath = Path.Combine(Path.GetDirectoryName(oldPath), newName);
                    File.Move(oldPath, newPath);
                    SearchButton_Click(null, null); // 刷新搜索
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"重命名失败: {ex.Message}", "错误");
                }
            }
        }

        private void OpenContainingFolder()
        {
            if (listView1.SelectedItems.Count == 0) return;

            string path = listView1.SelectedItems[0].Tag as string;
            if (string.IsNullOrEmpty(path)) return;

            try
            {
                Process.Start("explorer.exe", $"/select,\"{path}\"");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"无法打开所在文件夹: {ex.Message}", "错误");
            }
        }

        private void CopyItemPath()
        {
            if (listView1.SelectedItems.Count == 0) return;

            string path = listView1.SelectedItems[0].Tag as string;
            if (!string.IsNullOrEmpty(path))
            {
                Clipboard.SetText(path);
            }
        }

        private void ShowProperties()
        {
            if (listView1.SelectedItems.Count == 0) return;

            string path = listView1.SelectedItems[0].Tag as string;
            if (string.IsNullOrEmpty(path)) return;

            try
            {
                var psi = new ProcessStartInfo
                {
                    FileName = "explorer.exe",
                    Arguments = $"/e,/root,\"{path}\"",
                    Verb = "properties"
                };
                Process.Start(psi);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"无法显示属性: {ex.Message}", "错误");
            }
        }

        private void SearchButton_Click_1(object sender, EventArgs e)
        {
            string searchText = searchTextBox.Text.Trim();
            if (string.IsNullOrEmpty(searchText)) return;

            listView1.Items.Clear();

            Everything_SetSearch(searchText);
            if (!Everything_Query(true))
            {
                MessageBox.Show($"搜索失败,错误代码: {Everything_GetLastError()}", "错误");
                return;
            }

            int resultCount = Everything_GetNumResults();
            StringBuilder pathBuilder = new StringBuilder(260);

            for (int i = 0; i < resultCount; i++)
            {
                Everything_GetResultFullPathName(i, pathBuilder, pathBuilder.Capacity);
                string fullPath = pathBuilder.ToString();

                var item = new ListViewItem(Path.GetFileName(fullPath));
                item.SubItems.Add(fullPath);

                try
                {
                    var fileInfo = new FileInfo(fullPath);
                    item.SubItems.Add(fileInfo.Length.ToString("N0"));
                    item.SubItems.Add(fileInfo.LastWriteTime.ToString());
                    item.Tag = fullPath; // 存储完整路径
                }
                catch
                {
                    item.SubItems.Add("");
                    item.SubItems.Add("");
                }

                listView1.Items.Add(item);
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值