LP#TrayIconBuster






4.91/5 (24投票s)
一个用于从图标托盘中删除假图标的实用程序
以前 | 操作后 |
![]() |
![]() |
引言
许多程序会在托盘图标区域安装一个 NotifyIcon
。您的系统可能显示音量控制、任务管理器、网络连接等图标。当一个进程安装了一个 NotifyIcon
然后在没有正确处理(dispose)的情况下退出时,该图标会一直存在,直到您将鼠标指针移到它上面,它才会突然消失。当开发新应用程序,但应用程序由于严重异常或调试会话中断而退出时,可能会累积许多此类“幽灵”图标。此实用程序将自动处理托盘图标清理。
图标托盘
图标托盘是 Windows Explorer 管理的众多窗口之一。它实际上是一个包含许多按钮的工具栏。其中一些按钮是隐藏的,而另一些则是可见的。对于每个按钮,Explorer 都保存着一个“进程映像名称”,即创建 NotifyIcon
的进程的文件名。
.NET Framework 没有直接支持操作图标托盘的功能,因此我们需要大量的 P/Invoke 调用 Win32 函数,首先定位正确的工具栏,然后枚举按钮并获取它们的名称,即创建它们的进程的文件名。最后一步是删除没有文件名的图标,即进程退出时文件名被替换为 null。
程序
该程序很简单。它不显示 Form
;它只显示另一个 NotifyIcon
。它提供一个带有三个菜单项的上下文菜单:定期运行(每 5 秒运行一次,默认选中)、立即运行(立即单次运行)和退出。当 TrayIconBuster 尝试移除“幽灵”图标时,它首先会定位正确的 ListView。然后它会枚举所有图标一次,寻找自己的图标(稍后详述)。接着它会再次枚举所有图标,并移除没有关联文件名的图标。基本上有四个源文件。它们是主窗体 (main Form)、TrayIconBuster 以及两个帮助类:LP_Process 和 LP_Pinner。
主窗体
是的,确实有一个主窗体。默认情况下,它是不可见的。您可以更改源代码使其可见。然后它将只包含一个按钮,相当于上下文菜单的“立即运行”项。
TrayIconBuster
此类有一个静态方法,用于移除“幽灵”图标。任何希望清理图标的程序都可以直接调用它。通常,这会在应用程序启动时发生,并且希望移除上一次运行残留的图标。
public static uint RemovePhantomIcons() {...}
该方法尝试移除所有“幽灵”图标,并返回实际移除的图标数量。如果事情进展不顺利,它会抛出异常。
LP_Process
此类代表另一个进程。它支持读写其内存。它与参数为指针的 Win32 函数一起使用。由于这些指针在其他进程中必须是有效的,因此必须采取特殊步骤来首先获取有效的指针,并从/向我们的内存映射中的那些位置复制数据。
LP_Pinner
此类由 LP_Process 使用,用于固定(pin down)一个缓冲区,以便垃圾回收器无法移动它。当使用指针时,有时这是必需的,就像 LP_Process 执行跨进程边界的读写操作时一样。
安全性
TrayIconBuster 类会删除一些窗口。如果出现任何问题,可能会删除过多的东西。虽然删除图标对 Windows Explorer 来说不是致命的,但似乎只有一种恢复方法,那就是重启 Windows。我们想避免这种情况发生。作为一项安全措施,TrayIconBuster 会对图标进行两次枚举。
- 第一次扫描时,它不会更改或删除任何图标;它只是查找与之关联的文件名。特别是,它会尝试找到一个以“.exe”结尾的作为健全性检查。
- 如果第一次扫描成功,则开始第二次扫描,只有此时才会移除“幽灵”图标——即没有文件名的图标。因此,如果由于任何原因未能检索到任何文件名,第二次扫描将不会启动,所有图标将保持原样。
该程序已在 32 位 Windows XP 版本上进行了测试。它尚未在其他 Windows 版本上测试,也未在任何 64 位 Windows 版本上测试。得益于安全预防措施,我们相信在其他系统上运行它也是安全的,但我们无法保证它能实现其预期功能。请随时报告在任何 Windows 版本上的成功或遇到的问题。
关注点
以下几项与 CodeProject 消息板上的近期主题相关
- 读取或写入属于另一个进程的内存
- 应用“using 语句”可在退出语句块时自动调用
Dispose()
- 使用一些 GC 方法临时固定内存中的缓冲区
- 在静态
Main()
方法中具有全局 try-catch 结构 - Form1.cs 还包含将 JPEG 图像转换为图标文件的代码
历史
- 2007 年 7 月 16 日 -- LP#TrayIconBuster 1.0(首次发布)
- 2014 年 12 月 22 日 -- 2.0 版本现在支持 64 位 Windows(使用两种不同的工具栏按钮数据结构),并且可以在 Windows 7 和 Windows 8 上运行(处理新的 NotifyIconOverflowWindow。警告:为了在 Win64 上正常运行,必须为“AnyCPU”进行构建。