Building a Formless WinForms Application with a NotifyIcon in VB.Net 2008

Published on
38,024 Points
13 Endorsements
Last Modified:
Community Pick
This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray.

The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Run() instead of a Form instance.  With this approach we automatically get a built-in message pump and do not see any ugly Console windows.  Having a message pump means that an infinite loop is not necessary to keep the app "alive".  It also means that we can freely create Controls and Forms at run-time and respond to their events as usual.  We can even elegantly multi-thread the application by using a BackgroundWorker() Control from within the Inherited ApplicationContext Class.

Why would you want to do this?  Perhaps you have a "background" operation that needs to run all the time and would like to give the user a way to interact with the application.  The tray icon gives you the option to display menus or simply popup a configuration dialog if clicked.  This is an easy approach compared to implementing a full blown service.

The ApplicationContext provides complete freedom in controlling when the program is closed.  You are no longer constrained to just the two shutdown mode choices of "When startup form closes" or "When last form closes".  With no "startup form" you can now freely switch between forms without worrying about the app closing on you.  You can display a Login form and then actually completely close it before moving on to the Main form.  No more need to show the Main form with ShowDialog() or keep the Login form hidden just to keep the app alive!  Shared variables in the ApplicationContext class can be used to store information that the entire program needs access to (such as privilege levels).  Since the app only shuts down when you explicitly call Application.Exit() you can build a program that only closes when the conditions are right for your particular scenario.

Note that this technique can also be used without any GUI elements at all!  The app will happily run without any interface and will still have a message pump making it easier to work with than a Console app.

Let's get started:

1. Project Type

Start with a standard WinForms ApplicationStart with a standard WinForms Project

2. Project Properties

Click on Project --> PropertiesClick on Project --> Properties

3. Change the Entry Point

Disable the Application Framework and set the "Startup Object"Disable the Application Framework and Change the "Startup Object"

4. Add Tray Icon

Switch to the Resources Tab and add your Icon File (.ico)Add the Icon for you NotifyIcon to the Resources Tab

5. Embed the Icon

Change the Persistence Mode of the Icon to EmbeddedChange the Persistence Mode of the Icon

6. Add Module

Add a Module to the Project.  Leave the default name, Module1Add a Module to the Project

7. ([b]Optional[/b]) Remove Form1

Delete the default Form if you don't need it
(Forms can still be used in the application if you desire!)Optionally Delete the default Form if you don't need it

8. Add Code

Replace the code in the Module with the listing below.
Important! Change "My.Resources.Happy" in line #17 so that it correctly reflects the name of your Embedded Icon
Module Module1

    Public Sub Main()
        Application.Run(New MyContext)
    End Sub

End Module

Public Class MyContext
    Inherits ApplicationContext

    Private WithEvents TrayIcon As New NotifyIcon
    Private WithEvents CMS As New ContextMenuStrip
    Private WithEvents ExitMenu As New ToolStripMenuItem("Exit")

    Public Sub New()
        TrayIcon.Icon = My.Resources.Happy
        TrayIcon.Text = "ApplicationContext with a NotifyIcon" ' <-- Tooltip on the NotifyIcon
        TrayIcon.Visible = True

        TrayIcon.ContextMenuStrip = CMS

        ' You can add a BackgroundWorker control to the class and start a lengthy process from here...
    End Sub

    Private Sub CMS_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles CMS.Opening
        ' From this event you can control which menu items appear (visibility or disabled) or 
        ' even cancel the event and prevent the context menu from appearing at all
    End Sub

    Private Sub ExitMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ExitMenu.Click
    End Sub

    Private Sub MyContext_ThreadExit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ThreadExit
        TrayIcon.Visible = False
    End Sub

End Class

Open in new window

9. Test it out!

Run the Project
Hopefully you'll get an Icon in the System Tray that has an "Exit" option when you Right Click it

In the images below, the Happy face is the icon being displayed by the application:The NotifyIcon in the System Tray displaying its ToolTipThe NotifyIcon in the System Tray displaying its ContextMenuStrip
LVL 50

Expert Comment

Excellent article!  You made it sound so easy (and showed that it is :-)
You got my Yes vote!
LVL 96

Expert Comment

by:Bob Learned
Mike, sometimes, I wonder just how idle your mind really  is!! *WINK*  There is something subtle, yet powerful, in this article about the ApplicationContext, which is the glue that pulls all the pieces together in one simple line:

     Application.Run(New MyContext)



Expert Comment

This article rocking.. This is what i need for my application.
CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

LVL 38

Expert Comment

Great article and very useful!  
LVL 48

Expert Comment

by:Jorge Paulino
Great article Idle_Mind!

Expert Comment

Thanks for the article.One of the best article I ever read.
As always brilliant and truly Genius IDLE_MIND.


Expert Comment

X E Lent. Works in VS 2005 as well.
LVL 19

Expert Comment

by:Shahan Ayyub

Idle_Mind great Article. Thanks for sharing it.
I think the rumor is not rumor it is reality. ;)  just kidding
LVL 15

Expert Comment

Thanks, very useful.

Great Article...

Expert Comment

Hi guys

Thanks for all your comments unfortuntately all seem to have a problem in that if "Enable application framework" is unchecked then the Splash Screen I have added is not called and displayed.

Any ideas?


Featured Post

Why Diversity in Tech Matters

Kesha Williams, certified professional and software developer, explores the imbalance of diversity in the world of technology -- especially when it comes to hiring women. She showcases ways she's making a difference through the Colors of STEM program.

Learn how to collaborate with office 365 Office Online
If you, like me, have a dislike for using Online Subscription anti-spam services, then this video series is for you. I have an inherent dislike of leaving decisions such as what is and what isn't spamming to other people or services for me and insis…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month