Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

.NET

Run a Single Instance of a .NET Application


How do you ensure that only one instance of a .NET application runs on your machine? Multitasking operating systems are useful in many respects, but sometimes you want to have just one instance of your application running at a time—for example, if the application has a large resource usage or requires exclusive access to a resource. In such a situation, you’ll want to make sure that when a second instance starts, it will check to see if another instance is running and if this is the case shut itself down. In this article, I will tell you how to do this and the related situation of only allowing the most recent application instance to run.

The simplest way to ensure that only a single instance of an application runs is to use a mutex object. For example, in the following code, the form constructor creates a mutex object and then attempts to gain access to it. If WaitOne() returns true then the current thread owns the mutex, if it returns false then the mutex is owned by another thread.

using System;
using System.Windows.Forms;
using System.Threading;

class App : Form
{
   Mutex mutex;
   App()
   {
      Text = "Single Instance!";
      mutex = new Mutex(false, "SINGLE_INSTANCE_MUTEX");
      if (!mutex.WaitOne(0, false)) 
      {
         mutex.Close();
         mutex = null;
      }
   }
   protected override void Dispose(bool disposing)
   {
      if (disposing)
         mutex.ReleaseMutex();
      base.Dispose(disposing);
   }
   static void Main()
   {
      App app = new App();
      if (app.mutex != null) Application.Run(app);
      else MessageBox.Show("Instance already running");
   }
}

In this code, the Dispose() method is not strictly necessary because when the application dies, the garbage collector will dispose the mutex object, which will release it. However, I have added this just in case the disposal of the form takes a long time and another instance of the form is attempting to start.

This solution allows only the first instance of the process to run. What about the situation when you want just the last instance to run? By this I mean that if I start a new instance of the process and there is another instance already running, that first instance should stop. One situation of when this is useful is the Screen Saver tab of the Display Properties dialog. This dialog shows a small window with a preview of the screensaver; when the user clicks on the Preview button, another instance of the screensaver is started and told to run full screen. When the full screen instance stops (you move the mouse, for example) another instance of the screensaver is started to run in the small preview window. Clearly, when the full screen instance starts, the preview window instance of the screensaver should quit.

One way to do this is for each instance to access a named event kernel object. If the event object is nonsignaled, then the instance should continue to run, and if the event is signaled then the instance should quit. The application can periodically test the event to see if it has signaled. When a new instance starts, it should set the event (to close any other instances) and then reset the event so that it can continue to run. This scheme is fine except for one small problem: The .NET framework does not allow you to give a name to a kernel event. Here’s a class that will do this work for you:

public class NamedEventHelper
{
   [DllImport("kernel32")]
   static extern uint CreateEvent(
      uint sec, bool manualReset, bool initialState, string name);
   static IntPtr CreateEvent(bool manualReset, bool initialState, string name)
   {
      return new IntPtr(CreateEvent(0, manualReset, initialState, name));
   }
   [DllImport("kernel32")]
   static extern bool CloseHandle(IntPtr handle);
   public static ManualResetEvent CreateNamedEvent(
      bool initialState, string name)
   {
      ManualResetEvent mre = new ManualResetEvent(false);
      CloseHandle(mre.Handle);
      mre.Handle = CreateEvent(true, initialState, name);
      return mre;
   }
}

In this code, the static method CreateNamedEvent() creates a ManualResetEvent object and then releases the underlying Win32 handle. The method then creates a named event and initializes the ManualResetEvent object with the handle of this new event. The event object can then be used to communicate between two applications.

The weak point in this scheme is the fact that an application has to poll to see if it should die. One way to do this is to run a background thread to monitor the event:

  
ManualResetEvent mre;
mre = NamedEventHelper.CreateNamedEvent(false, "LAST_INSTANCE_ONLY");
// Stop the other instances
mre.Set();
// Reset the event so that we can run
mre.Reset();
// Create a monitor thread
Thread t = new Thread(new ThreadStart(Monitor));
// Make sure that this thread cannot keep the app alive
t.IsBackground = true;
t.Start();

The Monitor() method looks like this:

void Monitor()
{
   mre.WaitOne();
   Application.Exit();
}

If the application has a window, then another solution to this issue is for the new instance to tell the other window to close. If this was a Win32 application, then the application can simply call FindWindowEx() to get the window with a specified Windows class and then post the WM_CLOSE message. However, you cannot do this with Windows Forms because most forms will have the same class name, as I explained in the last newsletter. In the next newsletter, I will explain another way to get around this issue.


Richard Grimes speaks at conferences and writes extensively on .NET, COM, and COM+. He is the author of Developing Applications with Visual Studio .NET (Addison-Wesley, 2002). If you have comments about this topic, Richard can be reached at [email protected].


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.