如何防止在退出时在系统托盘中留下图标?

时间:2009-10-26 20:27:00

标签: c# .net system-tray

我的程序在系统托盘中放置一个图标,因为用户可以将其最小化。但是,如果应用程序崩溃,或者我阻止应用程序在VS中运行,它会在其中留下图标,直到我用鼠标悬停它。有时我会向下看,那里会有10个左右的图标。

我可以确定图标消失吗?

6 个答案:

答案 0 :(得分:21)

没有办法做到这一点。 Windows不会轮询您的程序以查看它是否仍然存在。因此,您的图标将保留在系统托盘中,直到您要求它离开(正常退出),或者用户执行启动程序调用的操作(例如鼠标悬停)。只有这样,shell才知道你的程序已经死了,它需要清理你的图标。

答案 1 :(得分:4)

您有几种选择:

1)编写一个根结构化异常处理程序,确保在退出之前销毁该图标。这个需要付出一些努力 - 但你基本上可以添加你自己的未处理的异常处理程序到Windows,在多种形式的“繁荣”的情况下将调用它,这将允许你最后一次清理机会。

2)编写一个睡眠在主进程句柄上的监视器应用程序,并在唤醒时杀死该图标(主应用程序已经死亡)。为了使后一个场景运行良好,您可能希望主进程不要杀死图标本身 - 或者您可以创建一种方法告诉监视器应用程序它应该退出而不会破坏图标(让监视器应用程序睡眠在进程句柄和命名事件上 - 如果被事件唤醒,那么它就会在主应用程序之后完成清理而无需清理。

答案 2 :(得分:3)

在退出之前,将NotifyIcon Visible属性设置为false。

答案 3 :(得分:3)

你需要在NotifyIcon上调用Dispose,让它离开托盘。

编辑:你可以在Program.cs中找到一个事件。对于所有Windows应用程序,您将拥有以下内容:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

Application类有一些事件,您可以利用这些事件来了解应用程序何时死亡:

        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        Application.ApplicationExit += new EventHandler(Application_ApplicationExit);

答案 4 :(得分:0)

我不知道杀死进程会发生什么,但是如果由于异常而崩溃,当然可以处理它。最好的方法取决于应用程序的类型:控制台、表单、服务……

但在所有情况下,您都应该能够在 Program.cs 中使用 try/finally 结构,并在“finally”部分 Dispose() 中使用 TrayIcon。

例如,在 Forms 应用程序中,将 Form 类中的 NotifyIcon(在下面的示例中称为 TrayIcon)设为 public,并更改 Program.cs 中的“Application.Run(new Form1())”行,如下所示:

Form form = new Form1();
try { Application.Run(form); }
finally { form.TrayIcon.Dispose(); }

答案 5 :(得分:-1)

我们可以在表单关闭之前隐藏trayIcon。 添加FormClosing事件

NotifyIcon ni;
...
...
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
     ni.Visible = false;
}