Issue with NotifyIcon not disappearing on Winforms App
Asked Answered
A

7

12

I've got a .Net 3.5 C# Winforms app. It's got no GUI as such, just a NotifyIcon with a ContextMenu.

I've tried to set the NotifyIcon to visible=false and dispose of it in the Application_Exit event, as follows:

        if (notifyIcon != null)
        {
            notifyIcon.Visible = false;
            notifyIcon.Dispose();
        }

The app gets to the code inside the brackets, but throws a null ref exception when it tries to set Visible = false.

I've read in a few places to put it in the form closing event, but that code never gets hit (maybe as I don't have a form showing as such?).

Where can I put this code so it actually works? If I don't put it in, I get the annoying lingering icon in the tray until you move the mouse over it.

Cheers.

EDIT

Just something extra I've noticed...........

I'm using ClickOnce in the app.........if I just exit the app via the ContextMenu on the NotifyIcon, no exception is logged.

Just when the Application_Exit event is fired after the applicaiton has checked for an upgrade here..

private void CheckForUpdate()
{
    EventLogger.Instance.LogEvent("Checking for Update");
    if (ApplicationDeployment.IsNetworkDeployed && ApplicationDeployment.CurrentDeployment.CheckForUpdate())
    {
        EventLogger.Instance.LogEvent("Update available - updating");
        ApplicationDeployment.CurrentDeployment.Update();
        Application.Restart();
    }
}

Does this help?

Afford answered 1/7, 2009 at 8:0 Comment(0)
D
12

On Windows 7, I had to also set the Icon property to null. Otherwise, the icon remained in the tray's "hidden icons" popup after the application had closed. HTH somebody.

// put this inside the window's class constructor
Application.ApplicationExit += new EventHandler(this.OnApplicationExit);


        private void OnApplicationExit(object sender, EventArgs e)
        {

            try
            {
                if (trayIcon != null)
                {
                    trayIcon.Visible = false;
                    trayIcon.Icon = null; // required to make icon disappear
                    trayIcon.Dispose();
                    trayIcon = null;
                }

            }
            catch (Exception ex)
            {
                // handle the error
            }
        }
Devisor answered 21/11, 2010 at 16:16 Comment(0)
P
4

This code works for me, but I don't know how you are keeping your application alive, so... without further ado:

using System;
using System.Drawing;
using System.Windows.Forms;

static class Program
{
    static System.Threading.Timer test = 
        new System.Threading.Timer(Ticked, null, 5000, 0);

    [STAThread]
    static void Main(string[] args)
    {
        NotifyIcon ni = new NotifyIcon();
        ni.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
        ni.Visible = true;

        Application.Run();
        ni.Visible = false;
    }

    static void Ticked(object o) {
        Application.Exit();
    }
}
Porte answered 1/7, 2009 at 8:8 Comment(0)
P
3

This is what I'm doing in WPF.

I am using this in conjunction to David Anson's Minimize to tray sample app, which lets you hook up a tray icon to a window (you may have multiple windows open).

Just added this code to the constructor for MinimizeToTrayInstance.

_window.Closed += (s, e) => 
{
        if (_notifyIcon != null)
        {
            _notifyIcon.Visible = false;
            _notifyIcon.Dispose();
            _notifyIcon = null;
        }
};
Plotinus answered 1/10, 2010 at 0:41 Comment(2)
On Window Close Event, it worked for me. On App_Exit it throws error while disposing notifyIcon.Mintamintage
just wrap it in a try catch and ignore the exceptionPlotinus
R
0

Sometimes Application_Exit event can be raised several times Just put notifyIcon = null; in the end

if (notifyIcon != null)
{
    notifyIcon.Visible = false;
    notifyIcon.Dispose();
    notifyIcon = null;
}
Reposit answered 1/7, 2009 at 8:21 Comment(2)
Actually, now that I think about it, I'd recommend against using this event for this because it's possible to have several Application.Run() loops going on different threads and they will all trigger an Exit event which might cause your icon to disappear prematurely.Porte
Totally agree with you! I prefer not to use this event in my applications for any clean-up purposes. However, it is the most simple answer to the question "why this code throws an exception". As to my ideas how to design this code in another way, I could propose to create a wrapper disposable class around notifyIcon, so it will control the lifetime of the notifyIcon. and then write using (new NotifyIconController()) { Application.Run() }; or something like thisReposit
A
0

Have you overridden the dispose method of the object where you've initialised the notifyIcon to also dispose the notifyIcon?

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        notifyIcon.Dispose();
        notifyIcon = null;
    }
    base.Dispose(disposing);
}
Autolycus answered 3/11, 2011 at 12:9 Comment(0)
S
0

This code worked for me

this.Closed += (a, b) =>
            {
                if (notifyIcon1 != null)
                {
                    notifyIcon1.Dispose();
                    notifyIcon1.Icon = null;
                    notifyIcon1.Visible = false;
                }
            };
Scholem answered 18/3, 2012 at 15:34 Comment(0)
E
0

before im sorry for my bad english. if u use "end" for exit program. then dont close notify icon. before u will close notifyicon later close form. u need to use me.close() for run form closing

example its work...

notifyIcon1.Icon = Nothing
notifyIcon1.Visible = False
notifyIcon1.Dispose()
Me.Close()

but its not work

End

or only

Me.Close()
Eliott answered 19/5, 2020 at 4:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.