How can I make a .NET Windows Forms application that only runs in the System Tray?
Asked Answered
D

13

268

What do I need to do to make a Windows Forms application to be able to run in the System Tray?

Not an application that can be minimized to the tray, but an application that will be only exist in the tray, with nothing more than

  • an icon
  • a tool tip, and
  • a "right click" menu.
Dissimilate answered 15/6, 2009 at 9:26 Comment(4)
codeproject.com/Articles/18683/Creating-a-Tasktray-ApplicationCubiform
There is something missing in most answers - don't forget to set icon.Visible = false, then Dispose() the icon when exiting your application. Otherwise you will still see the icon after your program exits. After testing it a couple of times, you'll no longer know, which icon is real.Mischance
If you are after a more modern WPF approach - you can try this: codeproject.com/Articles/36788/…Tann
Just for the record, here's a link to a very comprehensive article on tray applications (from an Answer that got deleted): simple-talk.com/dotnet/.net-framework/…Dissimilate
C
148

The code project article Creating a Tasktray Application gives a very simple explanation and example of creating an application that only ever exists in the System Tray.

Basically change the Application.Run(new Form1()); line in Program.cs to instead start up a class that inherits from ApplicationContext, and have the constructor for that class initialize a NotifyIcon

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.Run(new MyCustomApplicationContext());
    }
}


public class MyCustomApplicationContext : ApplicationContext
{
    private NotifyIcon trayIcon;

    public MyCustomApplicationContext ()
    {
        // Initialize Tray Icon
        trayIcon = new NotifyIcon()
        {
            Icon = Resources.AppIcon,
            ContextMenu = new ContextMenu(new MenuItem[] {
                new MenuItem("Exit", Exit)
            }),
            Visible = true
        };
    }

    void Exit(object sender, EventArgs e)
    {
        // Hide tray icon, otherwise it will remain shown until user mouses over it
        trayIcon.Visible = false;

        Application.Exit();
    }
}
Cubiform answered 20/4, 2012 at 16:33 Comment(5)
This is a great starting point. Note that "AppIcon" must be the name of a resource that you add with "Project -> Properties -> Resources -> Add Resource", and then recompile the project.Chalaza
I did properties..resources..add resource..icon.. recompiled, still get "Error CS0103 The name 'Resources' does not exist in the current context"Carillonneur
@Carillonneur I had to write it like this: Properites.Resources.AppIconBreazeale
@SimonPerepelitsa thanks, i'm not sure what I did ini my experiments, I meant to comment what worked but I must have forgotten some of teh things I did that worked. But ultimately the method I used was dragging a notificaton icon from the palette of things you can drag on. Then clicking on it on the form, clicking a little arrow which brings up a menu to choose an icon for it!Carillonneur
Note to anybody wanting to use this for .NET Core: it still works, but you have to replace the deprecated classes, like this.Shelton
R
19

As mat1t says - you need to add a NotifyIcon to your application and then use something like the following code to set the tooltip and context menu:

this.notifyIcon.Text = "This is the tooltip";
this.notifyIcon.ContextMenu = new ContextMenu();
this.notifyIcon.ContextMenu.MenuItems.Add(new MenuItem("Option 1", new EventHandler(handler_method)));

This code shows the icon in the system tray only:

this.notifyIcon.Visible = true;  // Shows the notify icon in the system tray

The following will be needed if you have a form (for whatever reason):

this.ShowInTaskbar = false;  // Removes the application from the taskbar
Hide();

The right click to get the context menu is handled automatically, but if you want to do some action on a left click you'll need to add a Click handler:

    private void notifyIcon_Click(object sender, EventArgs e)
    {
        var eventArgs = e as MouseEventArgs;
        switch (eventArgs.Button)
        {
            // Left click to reactivate
            case MouseButtons.Left:
                // Do your stuff
                break;
        }
    }
Ramose answered 15/6, 2009 at 9:46 Comment(0)
S
19

.NET Core

I adapted the accepted answer to .NET Core, using the recommended replacements for deprecated classes:

  • ContextMenu -> ContextMenuStrip
  • MenuItem -> ToolStripMenuItem

Program.cs

namespace TrayOnlyWinFormsDemo
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            ApplicationConfiguration.Initialize();
            Application.Run(new MyCustomApplicationContext());
        }
    }
}

MyCustomApplicationContext.cs

using TrayOnlyWinFormsDemo.Properties;  // Needed for Resources.AppIcon

namespace TrayOnlyWinFormsDemo
{
    public class MyCustomApplicationContext : ApplicationContext
    {
        private NotifyIcon trayIcon;

        public MyCustomApplicationContext()
        {
            trayIcon = new NotifyIcon()
            {
                Icon = Resources.AppIcon,
                ContextMenuStrip = new ContextMenuStrip()
                {
                    Items = { new ToolStripMenuItem("Exit", null, Exit) }
                },
                Visible = true
            };
        }

        void Exit(object? sender, EventArgs e)
        {
            trayIcon.Visible = false;
            Application.Exit();
        }
    }
}
Shelton answered 1/4, 2022 at 2:42 Comment(2)
I think your answer just asaved me a few hours of pain :-))) Thanks!!Sheugh
And definitely not an april fools joke ;-)Sheugh
E
16

I've wrote a traybar app with .NET 1.1 and I didn't need a form.
First of all, set the startup object of the project as a Sub Main, defined in a module.
Then create programmatically the components: the NotifyIcon and ContextMenu.
Be sure to include a MenuItem "Quit" or similar.
Bind the ContextMenu to the NotifyIcon.
Invoke Application.Run().
In the event handler for the Quit MenuItem be sure to call set NotifyIcon.Visible = False, then Application.Exit(). Add what you need to the ContextMenu and handle properly :)

Eucalyptus answered 15/6, 2009 at 10:51 Comment(0)
L
14
  1. Create a new Windows Application with the wizard.
  2. Delete Form1 from the code.
  3. Remove the code in Program.cs starting up the Form1.
  4. Use the NotifyIcon class to create your system tray icon (assign an icon to it).
  5. Add a contextmenu to it.
  6. Or react to NotifyIcon's mouseclick and differenciate between Right and Left click, setting your contextmenu and showing it for which ever button (right/left) was pressed.
  7. Application.Run() to keep the app running with Application.Exit() to quit. Or a bool bRunning = true; while(bRunning){Application.DoEvents(); Thread.Sleep(10);}. Then set bRunning = false; to exit the app.
Lawry answered 15/6, 2009 at 11:58 Comment(5)
The program stops executing when you reach the end of Main and has no UI thread. How do you take care of this is your solution? If you've solved those problems then you get my vote :)Geisel
You get my vote. Maybe just mention that you still need to call Application.Run without any params?Westbrook
Updated with an alternative to App.Run.Lawry
The thread.sleep is overkill I know, but if you have a better "sleep" loop alternative to Application.Run do post it :)Lawry
Thread.Sleep is a bad idea: you'll end up using more CPU and battery than if you just did Application.Run like you're meant to.Waikiki
G
13

"System tray" application is just a regular win forms application, only difference is that it creates a icon in windows system tray area. In order to create sys.tray icon use NotifyIcon component , you can find it in Toolbox(Common controls), and modify it's properties: Icon, tool tip. Also it enables you to handle mouse click and double click messages.

And One more thing , in order to achieve look and feels or standard tray app. add followinf lines on your main form show event:

private void MainForm_Shown(object sender, EventArgs e)
{
    WindowState = FormWindowState.Minimized;
    Hide();
} 
Gleanings answered 15/6, 2009 at 9:44 Comment(0)
G
8

As far as I'm aware you have to still write the application using a form, but have no controls on the form and never set it visible. Use the NotifyIcon (an MSDN sample of which can be found here) to write your application.

Geisel answered 15/6, 2009 at 9:31 Comment(3)
Not quite. Your form(s) can contain controls, but it should be hidden by default.Hanahanae
You do not need any form. After a new Window App creation wizard, just delete the Form1 and remove the code opening it. You can write it all from Program.cs with NotifyIcon and ContextMenu on it. Nothing more required.Lawry
I know it can contain controls, but OP doesn't want it toGeisel
P
4

It is very friendly framework for Notification Area Application... it is enough to add NotificationIcon to base form and change auto-generated code to code below:

public partial class Form1 : Form
{
    private bool hidden = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.ShowInTaskbar = false;
        //this.WindowState = FormWindowState.Minimized;
        this.Hide();
        hidden = true;
    }

    private void notifyIcon1_Click(object sender, EventArgs e)
    {
        if (hidden) // this.WindowState == FormWindowState.Minimized)
        {
            // this.WindowState = FormWindowState.Normal;
            this.Show();
            hidden = false;
        }
        else
        {
            // this.WindowState = FormWindowState.Minimized;
            this.Hide();
            hidden = true;
        }
    }
}
Prandial answered 15/6, 2009 at 9:27 Comment(0)
Z
4

Here is how I did it with Visual Studio 2010, .NET 4

  1. Create a Windows Forms Application, set 'Make single instance application' in properties
  2. Add a ContextMenuStrip
  3. Add some entries to the context menu strip, double click on them to get the handlers, for example, 'exit' (double click) -> handler -> me.Close()
  4. Add a NotifyIcon, in the designer set contextMenuStrip to the one you just created, pick an icon (you can find some in the Visual Studio folder under 'common7...')
  5. Set properties for the form in the designer: FormBorderStyle:none, ShowIcon:false, ShowInTaskbar:false, Opacity:0%, WindowState:Minimized
  6. Add Me.Visible=false at the end of Form1_Load, this will hide the icon when using Ctrl + Tab
  7. Run and adjust as needed.
Zumstein answered 26/7, 2011 at 14:18 Comment(0)
S
3

In .Net 6 I had to work the guts of my class like this:

private NotifyIcon trayIcon;
private ContextMenuStrip contextMenu1;
private ToolStripMenuItem menuItem1;

public MyCustomApplicationContext()
{
    contextMenu1 = new System.Windows.Forms.ContextMenuStrip();
    menuItem1 = new System.Windows.Forms.ToolStripMenuItem();
    this.menuItem1.Text = "E&xit";
    this.menuItem1.Click += new System.EventHandler(Exit);
    this.contextMenu1.Items.AddRange(
            new System.Windows.Forms.ToolStripMenuItem[] {this.menuItem1 });
    trayIcon = new NotifyIcon(){Icon = Resources.AppIcon, ContextMenuStrip = this.contextMenu1, Visible = true };            

}
Stewart answered 28/10, 2022 at 20:36 Comment(0)
H
1

You can create the form, modify it then pass it to the Application.Run as a parameter. :

    internal static class Program
    {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            ApplicationConfiguration.Initialize();
            var form = new Form1();
            form.Hide();
            form.Opacity = 0;
            form.ShowInTaskbar = false;
            Application.Run(form);
        }
    }

Add your NotifyIcon and ContextMenu (if needed) to your form at design time as a regular app. Make sure your Notifyicon is Visible and has an icon associated. This will also let you work with a form that you may need later for any reason

Hemmer answered 5/11, 2021 at 16:54 Comment(0)
S
0

Simply add

this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;

to your form object. You will see only an icon at system tray.

Skirl answered 1/7, 2015 at 15:39 Comment(5)
That puts the form above the taskbar. Not the same thing. Are you trying to respond to another post?Rhetoric
There isn't an icon on taskbar, we don't see form. Visually program exists only at system tray. What does above mean?Skirl
Your answer doesn't contain any context. Are you using the NotifyIcon class? If not, your form just minimizes to the bottom left corner above the task bar.Rhetoric
If you are not busy, please, try to write and run it.Skirl
this.ShowInTaskbar = false causes form not to show in taskbar (even when minimized) and this.WindowState = FormWindowState.Minimized causes the Form to start not visible on the screen. So the form doesn't show up anywhere. There's no way to focus it or restore it and the app runs happily in the background. If you add tray icon to your app then you have an app that shows up just as tray icon and nothing else. You can add ContextMenuStrip to notify icon to allow for interaction (and closing of the app).Falsity
K
0
notifyIcon1->ContextMenu = gcnew

System::Windows::Forms::ContextMenu();
System::Windows::Forms::MenuItem^ nIItem = gcnew
System::Windows::Forms::MenuItem("Open");

nIItem->Click += gcnew System::EventHandler(this, &your_class::Open_NotifyIcon);

notifyIcon1->ContextMenu->MenuItems->Add(nIItem);
Katlin answered 3/12, 2020 at 8:43 Comment(1)
Hi and welcome to Stack Overflow! Please take the tour. Thanks for contributing an answer but can you also add an explanation on how your code solves the problem?Quicken

© 2022 - 2024 — McMap. All rights reserved.