Thursday, August 16, 2007

Single Instance of a .Net App

Many times, we want to allow our user to run just a single instance of our application. Such is the case when we want to:
  1. Avoid resource sharing collisions (your application opens and writes to a file, a second instance would encounter a "file is being use by another process" exception).
  2. Pollute a resource with outputs from 2 instances (same file now contains outputs from 2 different applications that look the same).
  3. Our server side is not build to deal with 2 clients from the same location.
Here is an easy way to ensure a single instance of a .Net application per session.
This is C# code but can easily be replicated in VB.Net. If you go to your Program.cs file, the one the project wizard creates for you, you may see the following code:

static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
Add a using System.Threading; to the head of the file, and channge the main function to look like this:
static Mutex mutex;  // <-- corrected 8/24/2007!
static void Main()
{
bool isFirstInstanceOfApp;
mutex = new Mutex(true, "Global\\" + "MyApplicationName",
out isFirstInstanceOfApp);
if (isFirstInstanceOfApp)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
MessageBox.Show("An instance of MyApplicationName is already running",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
This adds a global mutex with your application name, since only one such mutex can exist, the next time we try to create it, we'd fail. Since the mutex is a local variable to the main function, it would exist until we exit the program.

Of course, change MyApplicationName to your application name. If you then run a second instance of the application you'd get:

The code to this demo app can be found here.

2 comments:

Ariel said...

Pay attention to the fact that when you use "Global", only one instance can be used by all running sessions. If you want every session (terminal session, Citrix session) to run an instance, just remove the "Global" string.

Traveling Tech Guy said...

You're absolutely right. After testing with "Global" on Citrix, I switched to "Local\\" - just didn't update the post :)
Thanks