views:

364

answers:

7

Hi, I have a window service for my application. When i stops that by killing process with task manager, tray icon does not disappears. Is it a window bug or something else? Do we have a solution for that problem? Thanks in advance :).

+4  A: 

Move your mouse over the icon, and it will disappear. I've noticed this behavior in all versions of windows, including Win 7.

JL
I've noticed it too :)
Jenea
Yeah it works but i have to make it disappear by code. I mean there is some script my testing team is running to stop that service and i feel that they are actually killing process instead of quiting service gracefully. I have to find a solution for them (you know testing guys :D).
Lalit
This is not exactly a fix. More like a dirty filthy hack.
Will
This is a windows thing, the only suggestion I can think of is create a helper app (hidden) that has 1 simple purpose to monitor when the main app gets aborted unexpectedly (on a timer), if the first app goes down - then take an action, exactly what that action is - I really do not know.
JL
Downvote because no answer, no hint to why no answer either... why is it upvoted so often?
BeowulfOF
+1  A: 

There is no solution to this problem. If you kill process with task manager, it does not receive termination notification, and hence can not remove its icon from the tray. Try avoiding killing process this way. You can use net start/stop to kill a service or services.msc GUI.

alemjerus
+3  A: 

I often notice that too, with various applications. The death of the application is only noticed when you move the mouse over the icon.

I think the "bug" is with Windows, not your application. (I'm reluctant to call it a "bug", per se, because it was probably a conscious decision to leave this in. Explorer could check whether applications that registered icons are still running, but that might be too expensive.)

Thomas
+5  A: 

You can let the icon disappear by calling the Dispose()-method of the specified NotifyIcon-object. In most cases these Container-object isn't part of the tree of components in your application so it will not disappear by killing the proces. When the user moves over the icon, the icon doesn't find it parent so it dissapears. But by calling the Dispose-method, it disapeared at least in my applications. So:

//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();
CommuSoft
Thanks,It sounds nice but i dont know where to put that code. That will be great if you can help me with that.
Lalit
I think you should define a method so when your application quits it will call that method. So if it is a Window-application (with a form). I think you will propably use the method Application.Run(yourForm); after the form is closed, the method is completed, so the main method will move on. If you have defined the notifyIcon in your main-class you can let it dispear after the Run-method. But of course I can't answer the question in general. You will need to find a thread that works when ending your application.
CommuSoft
EDIT (I reread your question):if you add a method to the Process.Exited event and that method does the job, I think it should work, but I didn't tested it yet. Good luck
CommuSoft
Hi,I guess it should work for me. Thanks for making me a happy man :).
Lalit
Hi,Its not working as none of my code part is getting hit on killing process. No luck yet :(.
Lalit
Does the code works without killing the process but by for example closing the Form or something else, another way could be to put the icon in a way as an object intro the process space.
CommuSoft
Hi, that is great, it just works, at least on XP... did know the problem as XP-Bug only till today.
BeowulfOF
@Lalit, another thing you could do (but of course this isn't a elegant solution is when the program is loaded, start up another program that monitors your first program, when the first is closed, the other will make the icon disapear. If the second is killed, the first simply creates a new program. But of course such a way of working looks much as the behaviour of a virus.
CommuSoft
A: 

If an application is forcefully terminated (e.g. through Task Manager), then Windows does not remove the notification icon. Windows Explorer doesn't even notice that the application has gone away until it attempts to send a message (usually a mouse movement message) to the window that owns the notification icon. At that point, Windows will remove the now dead icon from the notification area.

Given that you can't intercept TerminateProcess, there's nothing that your program can do about this by itself.

I guess that Windows Explorer could watch for the owner window being destroyed (as when the application quits unexpectedly), but it doesn't.

Even if the application is shut down gracefully, it must still remember to remove any of its notification icons. That is: if you don't call Shell_NotifyIcon(NIM_DELETE) (the equivalent of NotifyIcon.Dispose) when your application shuts down (even gracefully), the icon will remain there until the mouse moves over it.

Oh, and if this is a service process that's displaying the notification icon, be aware that session 0 isolation in Windows Vista and Windows 7 will break it.

Roger Lipscombe
A: 

I've done it by handling the ThreadException event and disposing the tray icon in that event handler.

Will
Hey will,control is not going on ThreadException on killing process, so it wont work :(.
Lalit
@lalit well, if you're actually using a service (i.e., extends ServiceBase), you can override the Dispose method. It all depends on exactly what kind of application you have and where the tray icon is created.
Will
@lalit Hmmm.... are you using a real service? (as in, extends ServiceBase)? Its hard to tell you what to do and where because we don't know *exactly* what kind of app you're developing and how you are constructing the TrayIcon and where you're storing it. Code would definitely help. If you're actually using a service and you create the TrayIcon in your service class (I'm not sure if that's even possible) you can drop the TrayIcon in the `this.components` collection and it will be disposed when the service is disposed. But I'm not sure if that's how you're doing it, hence gimme code.
Will
A: 

I think I found the cause and a workaround. I posted the answer on my blog below, and have included a sample WinForm project to demonstrate it. I hope this solves your issues as well.

http://www.bitsofgenius.com/?p=79

John J Schultz