Windows services 清除过程中托盘图标不会消失

Windows services 清除过程中托盘图标不会消失,windows-services,windows-xp,c#-2.0,Windows Services,Windows Xp,C# 2.0,我的应用程序有一个窗口服务。当我通过使用任务管理器终止进程来停止该操作时,托盘图标不会消失。这是一个窗口错误还是别的什么?我们有解决这个问题的办法吗?提前感谢:)。将鼠标移到图标上,图标将消失。我在所有版本的windows中都注意到了这种行为,包括Win7 这个问题没有解决办法。如果使用任务管理器终止进程,它不会收到终止通知,因此无法从任务栏中删除其图标。试着用这种方式避免杀戮过程。您可以使用netstart/stop终止服务或services.mscGUI。我也经常注意到,在各种应用程序中。只

我的应用程序有一个窗口服务。当我通过使用任务管理器终止进程来停止该操作时,托盘图标不会消失。这是一个窗口错误还是别的什么?我们有解决这个问题的办法吗?提前感谢:)。

将鼠标移到图标上,图标将消失。我在所有版本的windows中都注意到了这种行为,包括Win7

这个问题没有解决办法。如果使用任务管理器终止进程,它不会收到终止通知,因此无法从任务栏中删除其图标。试着用这种方式避免杀戮过程。您可以使用
netstart/stop
终止服务或
services.msc
GUI。

我也经常注意到,在各种应用程序中。只有当您将鼠标移到图标上时,应用程序才会死机


我认为“bug”是Windows的问题,而不是你的应用程序。(我不愿意将其称为“bug”,因为这可能是一个有意识的决定。Explorer可以检查注册图标的应用程序是否仍在运行,但这可能过于昂贵。)

可以通过调用指定NotifyIcon对象的Dispose()-方法让图标消失。在大多数情况下,这些容器对象不是应用程序中组件树的一部分,因此不会因为终止进程而消失。当用户移动到图标上方时,图标找不到父图标,因此图标消失。但通过调用Dispose方法,它至少在我的应用程序中消失了。因此:

//creating a NotifyIcon
NotifyIcon notifyicon = new NotifyIcon();
notifyicon.Text = "Text"; 
notifyicon.Visible = true; 
notifyicon.Icon = new Icon(GetType(),"Icon.ico");
//let it disappear
notifyicon.Dispose();

如果应用程序被强制终止(例如通过任务管理器),则Windows不会删除通知图标。Windows资源管理器甚至没有注意到应用程序已经离开,直到它尝试向拥有通知图标的窗口发送消息(通常是鼠标移动消息)。此时,Windows将从通知区域中删除现在已死亡的图标

考虑到您的情况,您的程序本身对此无能为力

我想Windows资源管理器可以监视所有者窗口是否被破坏(比如当应用程序意外退出时),但事实并非如此

即使应用程序正常关闭,它也必须记住删除任何通知图标。也就是说:如果在应用程序关闭时(即使是优雅地)不调用
Shell\u NotifyIcon(NIM\u DELETE)
(相当于
NotifyIcon.Dispose
),图标将一直保留在那里,直到鼠标移到它上面


哦,如果这是一个显示通知图标的服务进程,请注意Windows Vista和Windows 7中的会话0隔离将破坏它。

我通过处理事件并在该事件处理程序中处理托盘图标来完成此操作。

使用此工具


它在TrayNotifyWnd&NotifyIconOverflowWindow中迭代工具栏按钮,并删除那些具有空文件名的按钮。

是的,它可以工作,但我必须通过代码使其消失。我的意思是,我的测试团队正在运行一些脚本来停止该服务,我觉得他们实际上是在终止进程,而不是优雅地退出服务。我必须为他们找到一个解决方案(你知道测试人员:D)。这并不是一个确切的解决方案。更像是一个肮脏的黑客。这是一个windows的东西,我能想到的唯一建议是创建一个助手应用程序(隐藏),当主应用程序意外中止(在计时器上)时,它有一个简单的用途来监控,如果第一个应用程序宕机-然后采取行动,确切的行动是什么-我真的不知道。否决投票,因为没有答案,也没有暗示为什么没有答案。。。为什么它经常被升级?谢谢,听起来不错,但我不知道该把代码放在哪里。如果你能帮我,那就太好了。我认为你应该定义一个方法,这样当你的应用程序退出时,它就会调用这个方法。因此,如果它是一个窗口应用程序(带有表单)。我认为您可能会使用方法Application.Run(yourForm);关闭表单后,方法完成,因此主方法将继续。如果在主类中定义了notifyIcon,则可以让它在Run方法之后消失。当然,我不能笼统地回答这个问题。你需要找到一个在结束你的应用程序时可以运行的线程。编辑(我重新阅读了你的问题):如果你在进程中添加了一个方法。Exited事件,并且该方法完成了任务,我认为它应该可以运行,但我还没有测试它。好luckHi,我想它应该适合我。谢谢你让我成为一个快乐的人:)。@Lalit,你可以做的另一件事(但这当然不是一个优雅的解决方案,当程序加载时,启动另一个程序来监视你的第一个程序,当第一个程序关闭时,另一个程序会使图标消失。如果第二个程序被杀死,第一个程序只会创建一个新程序。但当然,这种工作方式看起来很像病毒的行为。嘿,威尔,控件不会在终止进程时执行ThreadException,因此它不会工作:(@lalit嗯,如果您实际使用的是服务(即扩展ServiceBase),则可以重写Dispose方法。这完全取决于您使用的应用程序类型以及托盘图标的创建位置。@lalit Hmmm…您使用的是真正的服务吗?(如扩展ServiceBase)?很难告诉您要做什么和在哪里做,因为我们不知道您正在开发什么类型的应用程序,以及您如何构建TrayIcon以及将其存储在哪里。代码肯定会有帮助。如果您实际使用服务,并且在服务类中创建TrayIcon(我不确定这是否可行)你可以在
this.components
集合中删除TrayIcon,当服务被释放时,它将被释放。但我不确定你是否是这样做的,因此给我代码。很好,我正在寻找一种自动处理方法。这个应用程序不能“按需”运行(它希望保持作为一个持久的托盘应用程序)。它还删除了几个虚拟磁盘