Single instance applications in Windows CE
I programmed a Windows CE application last month that had as 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.

July 14th, 2009 at 11:20 am
Thank you for this tip!
I worked with mutexes (with the “full” framework) before, but in a case like Windows CE I might have overseen the possibillity to import the native functions.
The question that comes to my mind is if I add native functions like this, do I need the release them again, e.g. like in a IDisposable implementation?
July 14th, 2009 at 6:49 pm
Glad you found it usefull
You do not need to release functions added in this way. You do however need to release any resources allocated for the functions, e.g. like i do in the example with the ReleaseMutex function.
July 23rd, 2009 at 4:01 pm
This worked great! Thanks.
Do you know of a way to set focus back to the running app instead of just exiting (if the application is minimized for example).
July 23rd, 2009 at 7:29 pm
That is a very good question Pete.
I guess you could use FindWindow and SetForegroundWindow to do it, but I don’t have any code available that does it.
Maybe this should be the subject of my next blog post
August 20th, 2009 at 12:18 am
Much needed. Thanks!
September 3rd, 2009 at 11:05 am
The solution do not have any concurrency problem, if the creation of the mutex is thread safe.
It is also a smart solution, if the mutex is destroyed, when the single instance application exits abnormally.
Regards
JRO
September 3rd, 2009 at 11:21 am
Hi Jan,
The creation of the mutex is thread-safe.
Also, according to Microsoft:
“The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.”
This means that abnormal program termination should release the mutex.
March 12th, 2010 at 2:37 pm
I was heading down the route of adding and deleting values to the Win32 API atom table and checking all references for any atoms that exist are still running. This is a much simpler and more elegant solution!
Saved me a lot of time, thanks!
May 6th, 2010 at 10:45 am
Very useful. I am going to try this now. IF there is any problem, I will contact you.
May 19th, 2010 at 4:29 pm
This worked great! Thanks.
Do you know of a way to set focus back to the running app instead of just exiting (if the application is minimized for example).
May 24th, 2010 at 1:25 pm
It works perfect.Thanks a lot!
July 9th, 2010 at 10:41 pm
I work in VB for Windows Mobile. I translated your code and this is what I have:
Dim Sistema As uso
Dim System.Windows.Forms As uso
Dim System.Runtime.InteropServices As uso
Dim System.Reflection As uso
Dim de As espacioDim Bitmatic As nombres
Dim clase As estáticoDim
( DllImport (” coredll.dll “, SetLastError = verdadero)) público estático externo CreateMutex IntPtr ( IntPtr Attr , bool Propios, cadena Nombre )
( DllImport (” coredll.dll “, SetLastError = verdadero)) público estático externo bool ReleaseMutex ( hMutex IntPtr )
Const ERROR_ALREADY_EXISTS As largo = 183
Function estático(Formulario As frm) As públicoEjecutar As vacío
Dim name As cadena = Assembly.GetExecutingAssembly (). getName () . Nombre
Dim mutexHandle As IntPtr = CreateMutex ( IntPtr.Zero , verdadero, Nombre)
Dim error As largo = Marshal.GetLastWin32Error ()
Dim (Error As siDim ERROR_ALREADY_EXISTS As Not = ) Application.Run (frm )
ReleaseMutex ( mutexHandle )
End Function
************************************************
It does not work. Please can you tell me am I doing wrong?
September 10th, 2010 at 9:49 am
THX! It is work in VB.net CF
Imports System
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Reflection
Public Class SingleInstanceApplication
_
Public Shared Function CreateMutex(ByVal Attr As IntPtr, ByVal Own As Boolean, ByVal Name As String) As IntPtr
End Function
_
Public Shared Function ReleaseMutex(ByVal hMutex As IntPtr) As Boolean
End Function
Const ERROR_ALREADY_EXISTS As Long = 183
Public Shared Sub Run(ByVal frm As Form)
Dim name As String = Assembly.GetExecutingAssembly().GetName().Name
Dim mutexHandle As IntPtr = CreateMutex(IntPtr.Zero, True, name)
Dim Rerror As Long = Marshal.GetLastWin32Error()
If (Not Rerror = ERROR_ALREADY_EXISTS) Then
Application.Run(frm)
End If
ReleaseMutex(mutexHandle)
End Sub
End Class
=========================================================
Execute the Application this way:
Imports System.IO
Imports System.Globalization
Public Class AppStart
Public Shared Sub Main()
Try
SingleInstanceApplication.Run(New FrmLogin())
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
End Class
September 27th, 2010 at 11:23 pm
[...] http://bitmatic.com/compact-framework/single-instance-applications-in-windows-ce [...]
July 14th, 2011 at 1:47 pm
Fantastic – Just what I wanted.
I added two additional Functions that suited my application
public static Boolean IsRunning()
{
Boolean IsRunning;
String name = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
IntPtr mutexHandle = CreateMutex(IntPtr.Zero, true, name);
long error = Marshal.GetLastWin32Error();
IsRunning = (error == ERROR_ALREADY_EXISTS);
ReleaseMutex(mutexHandle);
return (IsRunning);
}
public static Boolean IsNotRunning()
{
return (!IsRunning());
}
January 19th, 2012 at 8:45 am
This is a perfect and simple solution. Thanks Jacob!
May 17th, 2012 at 6:52 am
Is Windows CE on the way out? Compared with other OS’s I think they would be better off re-branding it