Writing a pure SysTray Application without a Window

One nice day I had to implement a pure SysTray application. The application should stay in SysTray with a notification icon, but without a main window. So my first thought was to hide the application window within the OnLoad(). At this point my adventure started.

I really fast came to the conclusion that it's not possible to hide a main window by setting the visibility to false. So what to do. I was searching with google and found some hints like set the window size to 1,1 or opacity to 0% and so on. The best idea was to call a native Windows API which hides the window. Cruel … All this solutions operated as a workaround but did not solve the problem.

So I did some research and found a solution which works without having such cruel workarounds.

The idea is not to create a window and to hide it. You create your own application context which simply consists of a notification icon without a window. So you don't have to hide it, because it's not existend.

///
/// New Context class derived from the application context
///
public class SysTrayContext: ApplicationContext
{
    private SysTrayNotification notification;

    #region STA Thread

    ///
    /// Start Thread and run the new sys tray context
    ///
    [STAThread]
    private static void Main()
    {
        Application.Run(new SysTrayContext());
    }

    #endregion

    ///
    /// Initializes a new instance of the class.
    ///
    public SysTrayContext()
    {
        notification = new SysTrayNotification();
        notification.Visible = true;
    }
}

The SysTrayNotification class does only contain a simple NotificationIcon and a ContextMenu. So it's easy to implement.

///
/// Initializes a new instance of the class.
///
public SysTrayNotification ()
{
    /*
     * Set the systray icon
     */
    Assembly thisExe = Assembly.GetExecutingAssembly();
    Stream iconStream = thisExe.GetManifestResourceStream(NTSVC);
    notifyIcon.Icon = new System.Drawing.Icon(iconStream);

    /*
     * Create the context menu
     */
    menu.MenuItems.Add("&Say hello world", new EventHandler(SayHello) );
    menu.MenuItems.Add("-");
    menu.MenuItems.Add("&Close", new EventHandler(OnClose));

    notifyIcon.ContextMenu = menu;
}

As you can see you don’t have to care for hiding the main application window – because you don’t have any.

The whole example can be downloaded from:
Writing a pure SysTray Application without a window.

9 Responses to “Writing a pure SysTray Application without a Window”

  1. Gerhard Stephan Says:

    Don’t use the command : “Application.EnableVisualStyles();”
    As you can see in my following posts this leads to an error. System.Runtime.InteropServices.SEHException

  2. Zook’s Prog Blog - VB.Net, or whatever bleeding edge technology I’m hurting myself with today. » Email a Screen Shot Says:

    [...] You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. Leave aReply [...]

  3. nervos Says:

    damm
    i looked at it..
    it contains forms!!!
    using System.Windows.Forms;

    what about i have an application that
    using System.Windows;

    so i have an window and i also want an systray menu?
    what to do?

  4. ColoMan Says:

    Sure you can hide a main window…. just make sure it is done in the shown event

    void Form1_Shown(object sender, EventArgs e)
    {
    this.Hide();
    }

  5. Console.Write(this.Opinion) : Criando uma aplicação .Net 100% SysTray Says:

    [...] Writing a pure SysTray Application without a Window - Gerhard Stephan [...]

  6. Sebastian Werner Says:

    In “private void OnClose” there should be a “notifyIcon.Visible = false;” before the “Application.Exit();”. Otherwise the Icon would stay in the SysTray until you hover Mouse over it.

  7. telli Says:

    I do not agree, Sebastian, the correct way is to use “notifyIcon.Dispose();” in the onClose-Function.

    Just my 2 cent.

  8. Matt Emson Says:

    Simplest solution:

    1) Create a UserControl, ass your trayicon etc to it, visually design etc, be happy that it is letting you do this with little pain. e.g create a control called “HiddenWindow”, place the NotificationIcon and associated ContextMenuStrip on to it and design the logic etc.

    2) Alter the Program declaration to:

    [STAThread]
    static void Main()
    {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    //this instance will exist whilst the app is running
    HiddenWindow hw = new HiddenWindow();

    Application.Run(); //important, remove the Form from this!
    }

    Voila! You have a tray/notification icon.

  9. Heartburn Home Remedy Says:

    I noticed that this is not the first time at all that you write about the topic. Why have you chosen it again?


Leave a Reply