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?

Cœur
  • 37,241
  • 25
  • 195
  • 267

7 Answers7

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
            }
        }
Dave
  • 1,721
  • 2
  • 23
  • 46
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();
    }
}
Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222
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;
        }
};
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
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;
}
Bogdan_Ch
  • 3,328
  • 4
  • 23
  • 39
  • 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. – Matthew Scharley Jul 01 '09 at 08:44
  • 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 this – Bogdan_Ch Jul 01 '09 at 14:18
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()
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);
}
slavoo
  • 5,798
  • 64
  • 37
  • 39
JDandChips
  • 9,780
  • 3
  • 30
  • 46
0

This code worked for me

this.Closed += (a, b) =>
            {
                if (notifyIcon1 != null)
                {
                    notifyIcon1.Dispose();
                    notifyIcon1.Icon = null;
                    notifyIcon1.Visible = false;
                }
            };
Ibraheem Osama
  • 324
  • 3
  • 6