NotifyIcon remains in Tray even after application closing but disappears on Mouse Hover
Asked Answered
B

15

90

There are many questions on SO asking same doubt. Solution for this is to set

notifyIcon.icon = null and calling Dispose for it in FormClosing event.

In my application, there is no such form but has Notification icon which updates on Events. On creation, I hide my form and make ShowInTaskbar property false. Hence I can not have a "FormClosing" or "FormClosed" events.

If this application gets event to exit, It calls Process.GetCurrentProcess().Kill(); to exit.

I have added notifyIcon.icon = null as well as Dispose before killing, but still icon remains taskbar until I hover mouse over it.

EDIT: If I assume that this behaviour is due to calling GetCurrentProcess().Kill(), Is there any elegant way to exit from application which will clear all resources and remove icon from system tray.

Burglarize answered 6/2, 2013 at 7:36 Comment(4)
Time to accept an answer don't you think :D Let me suggest you the one of "The Muffin Man" :DRevers
@Nudity Problem is I just got rid of that notify icon... And now I don't have that code to verify any solution :-)Burglarize
Will I just did :D and the Dispose() fixed it :DRevers
One option is to refresh the traybar after killing the process, see the posts at #2312377 and #55704483 for detailsProbity
M
22

The only solution that worked for me was to use the Closed event and hide and dispose of the icon.

icon.BalloonTipClosed += (sender, e) => { 
                                            var thisIcon = (NotifyIcon)sender;
                                            thisIcon.Visible = false;
                                            thisIcon.Dispose(); 
                                        };
Matildematin answered 25/5, 2016 at 18:17 Comment(5)
This should be the accepted answer ... Dispose() is what you need there !Revers
what is this called? += (sender, e) => { // code };Fishbowl
@user3365695 It's a lambda expression. Check this link out with examples of the 3 ways to specify the delegate msdn.microsoft.com/en-us/library/…Matildematin
I remember when I was learning delegates were not explained well. A delegate is simply a way to provide the name of a method to be invoked later by something. You can use any method you've made that matches the signature the event expects. In this case we register a method to be called once the Balloon tip internally invokes the BalloonTipClosed event. In this example, syntactically we don't provide the name of a method, we define what's called an anonymous function/method. This is a newer code feature which is why you see multiple ways to do it notably delegate(string s) {//code}.Matildematin
Application.Exit(); NotifyIcon = null; works every time on multiple "windows reinstalls" - seperate issue lolArpent
D
56

You can either set

notifyIcon1.Visible = false;

OR

notifyIcon.Icon = null;

in the form closing event.

Deodorant answered 24/5, 2013 at 18:42 Comment(9)
Does not fix the problem.Shiite
@Shiite Did you try it ?Deodorant
I did with WPF NotifyIcon.Shiite
works for me in WPF. You must do it before closing the application thoughMedeah
icon.BalloonTipClosed += (sender, e) => { var thisIcon = (NotifyIcon)sender; thisIcon.Visible = false; thisIcon.Dispose(); };Matildematin
@TheMuffinMan: This is genious! Solved my problem just as I wanted to solve it. Thanks a lot!Dagny
@TheMuffinMan mayhaps you want to make that an answerViehmann
Thx :) Work fine :)Uncritical
For those that will fall on this answer it is important to note that this DOES fix the issue. If your icon stays it's because you are debugging (not all PC does that but we have 2 out of 11 that does it here). If you run the exe the icon will in fact disappear.Poona
M
22

The only solution that worked for me was to use the Closed event and hide and dispose of the icon.

icon.BalloonTipClosed += (sender, e) => { 
                                            var thisIcon = (NotifyIcon)sender;
                                            thisIcon.Visible = false;
                                            thisIcon.Dispose(); 
                                        };
Matildematin answered 25/5, 2016 at 18:17 Comment(5)
This should be the accepted answer ... Dispose() is what you need there !Revers
what is this called? += (sender, e) => { // code };Fishbowl
@user3365695 It's a lambda expression. Check this link out with examples of the 3 ways to specify the delegate msdn.microsoft.com/en-us/library/…Matildematin
I remember when I was learning delegates were not explained well. A delegate is simply a way to provide the name of a method to be invoked later by something. You can use any method you've made that matches the signature the event expects. In this case we register a method to be called once the Balloon tip internally invokes the BalloonTipClosed event. In this example, syntactically we don't provide the name of a method, we define what's called an anonymous function/method. This is a newer code feature which is why you see multiple ways to do it notably delegate(string s) {//code}.Matildematin
Application.Exit(); NotifyIcon = null; works every time on multiple "windows reinstalls" - seperate issue lolArpent
C
18

Components just must be disposed in the right order like this :

NotifyIcon.Icon.Dispose();

NotifyIcon.Dispose();

Add this to the MainWindow closing event.

Hope this will help.

Czerny answered 21/11, 2017 at 13:28 Comment(1)
i think that perhaps it's important to note that stopping debugging doesn't trigger override void OnExit(ExitEventArgs e), disposing will not be triggerdHollington
F
12

Use this code when you want to do it when you press the Exit or Close button:

private void ExitButton_Click(object sender, EventArgs e)
{
    notifyIcon.Dispose();
    Application.Exit(); // or this.Close();
}

Use this code when you want to do it when the form is closing:

private void Form1_FormClosing(object sender, EventArgs e)
{
    notifyIcon.Dispose();
    Application.Exit(); // or this.Close();
}

The important code is this:

notifyIcon.Dispose();
Footage answered 30/5, 2015 at 10:9 Comment(1)
I tried the following code and it worked. private void Window_Closed(object sender, EventArgs e) { mNotifyIcon.Dispose(); }Irretrievable
T
11

Use notifyIcon.Visible = False in FormClosing event

Theorbo answered 28/2, 2014 at 19:34 Comment(3)
To do a clean cleanup you still should call notifyIcon.Dispose(). When your class doesn't have a function wehre you could call this, you should implement IDisposable.Fogy
Not sure why this is not marked as the answer but it fixed my issue as well...thanks @TheorboCoaptation
@KevinMoore because the OP explicitly stated that he has no Form on which they could handle the FormClosing eventUnchartered
M
4

The only way that works to me was:

  1. On design screen changing notifyicon1 property visible=false

  2. Insert the code below on main form "activated" event:

NotifyIcon1.Visible = True
  1. Insert the code below on main form "closing" event:
NotifyIcon1.Visible = false
NotifyIcon1.Icon.Dispose()
NotifyIcon1.Dispose()
Marinemarinelli answered 24/7, 2020 at 20:36 Comment(0)
S
3

This is normal behaviour, unfortunately; it's due to the way Windows works. You can'r really do anything about it.

See Issue with NotifyIcon not dissappearing on Winforms App for some suggestions, but none of them ever worked for me.

Also see Notify Icon stays in System Tray on Application Close

Microsoft have marked this as "won't fix" on Microsoft Connect.

Spiral answered 6/2, 2013 at 7:38 Comment(7)
i feel like windows has been doing this forever.Perch
OSX will often leave a GAP in the task bar in similar situation, just a quirk i guess of how both OSes draw their task / menu bars.Perch
Isn't there any elegant way to Exit from this process instead of "GetCurrentProcess.Kill()" and Will that change my this behaviour?Burglarize
It could! I feel like the fact you are killing it, is what is causing some of the issue. You could try waiting for the next run loop before killing, after your set the icon nil and disposing.Perch
@MatthewWatson Can you provide me any link where it says "Won't fix"?Burglarize
I guess there must be some fix for this - utorrent for example has also icon in system tray. But, when it exits, the icon disapears.Dibbrun
This is normal behavior, but you can get around it. See answers about NotifyIcon.VisibleEncumber
E
2

I don't think WPF has it's own NotifyIcon, does it? If you're using the 3rd party Harcodet.Wpf.TaskbarNotification, then try this:

In order to prevent my app from closing when the window is closed (run in background), I separated the logic for closing the window (hitting the x button in the upper right) and actually shutting it down (through the context menu). To make this work, make your context menu set _isExplicitClose to true. Otherwise, it'll just hide the window and continue to run.

What this does is, on explicit close, hide tray icon and the form before closing. This way the icon isn't hanging around after the application is shutdown.

private bool _isExplicitClose;
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    base.OnClosing(e);

    if (!_isExplicitClose)
    {
        e.Cancel = true;
        Hide();
    }
}

protected void QuitService(object sender, RoutedEventArgs e)
{
   _isExplicitClose = true;
   TaskbarIcon.Visibility = Visibility.Hidden;
   Close();
}
Eustace answered 22/3, 2014 at 21:42 Comment(0)
C
2

Try Application.DoEvents(); after setting notifyIcon.Icon to null and disposing:

notifyIcon.Icon = null;
notifyIcon.Dispose();
Application.DoEvents();

And consider Environment.Exit(0); instead of Process.GetCurrentProcess().Kill().

Chromophore answered 14/2, 2015 at 0:59 Comment(0)
A
1

i can tell you can solve the problem simply using the .dispose() method, but that is not called if you kill the process instead of exit the application.

please refer to Application.Exit if you have built a simple Windows Form application else refer to Environment.Exit that is more general.

Aplenty answered 12/2, 2014 at 18:0 Comment(0)
J
1

I tried all of these and none of them worked for me. After thinking about it for a while I realized that the application creating the "balloon" was exiting before it had a chance to actually dispose of the balloon. I added a while loop just before Application.Exit() containing an Application.DoEvents() command. This allowed my NotifyIcon1_BalloonTipClosed to actually finish disposing of the icon before exiting.

while (notifyIcon1.Visible)
{
    Application.DoEvents();
}
Application.Exit();

And the tip closed method: (You need to include the thisIcon.visible = false in order for this to work)

private void NotifyIcon1_BalloonTipClosed(object sender, EventArgs e)
{
    var thisIcon = (NotifyIcon)sender;
    thisIcon.Icon = null;
    thisIcon.Visible = false;
    thisIcon.Dispose();
}
Jutland answered 12/1, 2019 at 16:5 Comment(0)
S
0

I had the exact same problem as you.

The proper way are send WM_CLOSE message to a process.
I use the c# code I found in this article.
http://social.msdn.microsoft.com/Forums/vstudio/en-US/82992842-80eb-43c8-a9e6-0a6a1d19b00f/terminating-a-process-in-a-friendly-way

Staciestack answered 28/6, 2013 at 8:10 Comment(0)
P
0

edit codes of ...Designer.cs as below coding.

        protected override void Dispose(bool disposing)
           {
           if (disposing )
               {
               this.notifyicon.Dispose();
               }
           base.Dispose(disposing);
           }
Pouch answered 29/8, 2017 at 14:22 Comment(1)
Please add some explanation.Indulge
C
0

I couldn't make any one of the other solutions work. It turned out to be kind of a hybrid of all the above! I hunted and pecked until I had a consistently working solution both in debug and in EXE execution modes! I have no idea why MSFT would mark this as "Not going to fix"? I wish I had that liberty!

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    {
        //THIS CODE IS CRAZY BUT MUST BE DONE IN ORDER TO PROPERLY REMOVE THE SYSTEM TRAY ICON!
        //GREAT ARTICLE ON THIS ON STACK OVERFLOW
        //https://mcmap.net/q/235610/-notifyicon-remains-in-tray-even-after-application-closing-but-disappears-on-mouse-hover

        //BTW THIS IS KIND OF A BLEND OF ALL THE SOLUTIONS BECAUSE I COULD NOT FIND A SINGLE SOLUTION THAT WOULD WORK!
        systray_icon.Visible = false;
        while (systray_icon.Visible)
        {
            Application.DoEvents();
        }
        systray_icon.Icon.Dispose();
        systray_icon.Dispose();
        Environment.Exit(1);
    }
Carbine answered 9/1, 2022 at 21:37 Comment(0)
S
-2

The right answer has already been given. But you must also provide a delay, for example with a timer. Only then the application can still remove the icon in the background.

private System.Windows.Forms.Timer mCloseAppTimer;
private void ExitButton_Click(object sender, EventArgs e) 
{ 
    notifyIcon.Visible = false; notifyIcon.Dispose; 
    mCloseAppTimer = new System.Windows.Forms.Timer(); 
    mCloseAppTimer.Interval = 100; 
    mCloseAppTimer.Tick += new EventHandler(OnCloseAppTimerTick); 
} 
private void OnCloseAppTimerTick(object sender, EventArgs e) 
{ 
    Environment.Exit(0); // other exit codes are also possible 
}
Spagyric answered 12/4, 2017 at 9:41 Comment(1)
Surely the use of a timer is an overkill - wouldn't Thread.Sleep(1000), do the same thing? You could even use it within a new thread so it doesn't 'pause' any GUI ectBenco

© 2022 - 2025 — McMap. All rights reserved.