我的程序在系统托盘中放置了一个图标,因为用户可以将其最小化。但是,如果应用程序崩溃,或者我停止应用程序在 VS 中运行,它会将图标留在其中,直到我将鼠标悬停在它上面。有时我会往下看,那里会有 10 个左右的图标。
我可以确保图标消失吗?
我的程序在系统托盘中放置了一个图标,因为用户可以将其最小化。但是,如果应用程序崩溃,或者我停止应用程序在 VS 中运行,它会将图标留在其中,直到我将鼠标悬停在它上面。有时我会往下看,那里会有 10 个左右的图标。
我可以确保图标消失吗?
没有办法做到这一点。Windows 不会轮询您的程序以查看它是否仍然存在。因此,您的图标将保留在系统托盘中,直到您告诉它离开(正常退出),或者用户执行了一些启动程序调用的操作(例如鼠标悬停)。只有这样,shell 才知道你的程序已经死了,它需要清理你的图标。
你有几个选择:
1)编写一个根结构化异常处理程序,确保在退出前销毁图标。这需要一些努力 - 但您基本上可以将自己的未处理异常处理程序添加到 Windows,在多种形式的“繁荣”的情况下将调用该处理程序,这将为您提供一些最后的清理机会。
2)编写一个监视应用程序,该应用程序在您的主进程句柄上休眠,并在它唤醒时杀死图标(主应用程序已死)。为了使后一种情况正常工作,您可能希望主进程不要杀死图标本身 - 或者您可以创建一种方法来告诉监视器应用程序它应该退出而不破坏图标(让监视器应用程序睡眠在进程句柄和命名事件上 - 如果被事件唤醒,那么它只是在主应用程序之后没有清理就死了)。
在退出之前,将 NotifyIcon Visible 属性设置为 false。
您需要在 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);
我不知道当一个进程终止时会发生什么,但是如果它由于异常而崩溃,当然可以处理它。最好的方法取决于应用程序的类型:控制台、表单、服务……
但在所有情况下,您都应该能够在 Program.cs 中使用 try / finally 结构,并在“finally”部分 Dispose() 中使用 TrayIcon。
例如,在 Forms 应用程序中,将您的 Form 类中的 NotifyIcon(在下面的示例中称为 TrayIcon)公开,并更改 Program.cs 中的“Application.Run(new Form1())”行,如下所示:
Form form = new Form1();
try { Application.Run(form); }
finally { form.TrayIcon.Dispose(); }
我们可以在表单关闭之前隐藏trayIcon。添加 FormClosing 事件
NotifyIcon ni;
...
...
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
ni.Visible = false;
}