Tags

, , , ,

There is a requirement that only one instance could run at the same time. Had it been Windows Mobile, this had been handled by the OS, but on Windows CE you have to take care of this yourself.
I was a bit surprised that there is no easy way of accomplishing this. Searching the internet gave me basically no easy answer either, but there seems to be 3 standard ways of accomplishing this.

  • Write a dummy text file on startup, and check the existance of this file.
  • Write to a registry-key on startup, and use that as a “mutex”.
  • Use a named mutex with a system-wide scope.

Obviously the first two have the problem that they may break the program, if the program exits without resetting the file/registry-key used as a pseudo-mutex. They are also very crude and not very elegant…. But that’s up to personal taste i guess.
I went for the third choice; The named mutex.

The named mutex in Windows CE

The .NET Compact Framework does not support named mutexes. Luckily Windows CE does however, and it can be imported through a few functions in coredll.dll.
A named mutex is an object created by the OS with a name specified on creation. The actual functionality of the object is not very interesting right now. The interesting bit is that only one object can exist with any given name. If you try to create another object with the same name, you get an error.
Basically, if you create a named mutex with the name of the application itself, this can be used to ensure that only one instance of the application can be run.

Wrapping it up

I decided to wrap it all up nicely in a class, so that it will be easy to use. The class is called SingleInstanceApplication, and here is what i came up with:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;

namespace Bitmatic
{
  static class SingleInstanceApplication
  {
    [DllImport("coredll.dll", SetLastError = true)]
    public static extern IntPtr CreateMutex(IntPtr Attr, bool Own, string Name);

    [DllImport("coredll.dll", SetLastError = true)]
    public static extern bool ReleaseMutex(IntPtr hMutex);

    const long ERROR_ALREADY_EXISTS = 183;

    public static void Run(Form frm)
    {
      string name = Assembly.GetExecutingAssembly().GetName().Name;
      IntPtr mutexHandle = CreateMutex(IntPtr.Zero, true, name);
      long error = Marshal.GetLastWin32Error();

      if (error != ERROR_ALREADY_EXISTS)
        Application.Run(frm);

      ReleaseMutex(mutexHandle);
    }
  }
}

Feel free to steal….
The class imports the two native functions for creating and destroying mutexes, and has only a single public function.
The Run function tries to create a mutex with the name of the application. It then checks the error code returned, to see if the mutex already exists, and if it doesn’t; starts the application. Finally it releases the mutex.
Very simple, and quite a bit more elegant than the file/registry based solutions.

Using it

Using the class is very very simple. Just add the class itself to your project, open up Program.cs and replace:

[MTAThread]
static void Main()
{
  Application.Run(new Form1());
}

with:

[MTAThread]
static void Main()
{
  SingleInstanceApplication.Run(new Form1());
}

You only really changed one line, and now you have an application that is guaranteed to run only as a single instance.

 

http://bitmatic.com/c/single-instance-applications-in-windows-ce/

Advertisements