65.9K
CodeProject 正在变化。 阅读更多。
Home

LP#TrayIconBuster

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (24投票s)

2007年7月16日

CPOL

5分钟阅读

viewsIcon

115548

downloadIcon

5266

一个用于从图标托盘中删除假图标的实用程序

以前 操作后
Screenshot - LPTrayIconBuster1.gif Screenshot - LPTrayIconBuster2.gif

引言

许多程序会在托盘图标区域安装一个 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”进行构建。
© . All rights reserved.