如何让FileSystemWatcher检测多卷回收站的文件删除操作?
解决FileSystemWatcher仅监听C盘回收站的问题
问题核心是每个逻辑磁盘都有独立的$Recycle.Bin目录,你当前代码只监听了C盘的回收站,自然无法响应其他磁盘的变化。以下是具体解决步骤和修改后的代码:
解决方案思路
- 遍历系统中所有逻辑驱动器(如C:\、D:\、E:\等)
- 为每个可访问的驱动器创建对应的
FileSystemWatcher,监听其根目录下的$Recycle.Bin文件夹 - 统一绑定变化事件处理逻辑,确保任意磁盘回收站的变动都能触发托盘图标更新
修改后的完整代码
enum RecycleFlags : uint { SHRB_NOCONFIRMATION = 0x00000001, SHRB_NOPROGRESSUI = 0x00000002, SHRB_NOSOUND = 0x00000004 } [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] static extern uint SHEmptyRecycleBin(IntPtr hwnd, string pszRootPath, RecycleFlags dwFlags); static Shell shell = new Shell(); Folder recycleBin = shell.NameSpace(10); // 存储所有Watcher实例,防止被GC回收导致监听失效 private List<FileSystemWatcher> _recycleWatchers = new List<FileSystemWatcher>(); public Form1() { InitializeComponent(); SetupMultiDriveRecycleWatchers(); } private void SetupMultiDriveRecycleWatchers() { // 获取系统所有逻辑驱动器 string[] drives = Directory.GetLogicalDrives(); foreach (string drive in drives) { try { string recyclePath = Path.Combine(drive, "$Recycle.Bin"); // 跳过不存在或无法访问的驱动器(比如光驱、未挂载的网络盘) if (!Directory.Exists(recyclePath)) continue; FileSystemWatcher watcher = new FileSystemWatcher(recyclePath); // 绑定所有可能触发回收站变化的事件 watcher.Changed += OnRecycleBinChanged; watcher.Created += OnRecycleBinChanged; watcher.Deleted += OnRecycleBinChanged; watcher.Renamed += OnRecycleBinChanged; watcher.EnableRaisingEvents = true; _recycleWatchers.Add(watcher); } catch (UnauthorizedAccessException) { // 跳过无权限访问的驱动器 continue; } catch (Exception ex) { Console.WriteLine($"无法监听驱动器 {drive} 的回收站: {ex.Message}"); } } // 初始化托盘图标状态 UpdateRecycleBinIcon(); } private void OnRecycleBinChanged(object sender, FileSystemEventArgs e) { // 跨线程更新UI,避免异常 Invoke(new Action(UpdateRecycleBinIcon)); } private void UpdateRecycleBinIcon() { NotifyIcon.Icon = recycleBin.Items().Count == 0 ? Properties.Resources.Empty : Properties.Resources.Full; } private void openToolStripMenuItem_Click(object sender, EventArgs e) { System.Diagnostics.Process.Start("explorer.exe", "shell:RecycleBinFolder"); } private void emptyToolStripMenuItem_Click(object sender, EventArgs e) { SHEmptyRecycleBin(IntPtr.Zero, null, RecycleFlags.SHRB_NOSOUND); // 清空后手动更新图标,避免Watcher延迟 UpdateRecycleBinIcon(); } // 窗体关闭时释放所有Watcher资源 protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); foreach (var watcher in _recycleWatchers) { watcher.Dispose(); } }
关键修改说明
- 多驱动器监听:通过
Directory.GetLogicalDrives()遍历所有磁盘,为每个磁盘的回收站创建独立监听 - 事件全覆盖:绑定
Created/Deleted/Renamed等事件,确保回收站的所有变动都能被捕获 - 资源管理:用List存储Watcher实例,避免被垃圾回收;窗体关闭时统一释放资源
- 异常防护:跳过无权限或无法访问的驱动器,防止程序崩溃
- UI更新优化:提取独立的图标更新方法,清空回收站后手动触发更新,避免监听延迟
内容的提问来源于stack exchange,提问作者429
相关产品推荐
相关产品推荐

