Zach Burlingame

Programming, Computers, and Other Notes on Technology

Limiting an Application to a Single Instance with Named Events

Sometimes it’s desirable to allow only a single instance of an application per user or even per system. There are several ways you can do this.

FindWindow

In the case of a single instance per user session, you can use FindWindow to enumerate through the window handles for the current user session based on the window class and window title. This is actually how Microsoft Outlook does it. The drawback is that this only supports limiting the current session and it requires a window handle (i.e. doesn’t work in Console applications without creating a hidden window).

Use a File or Registry as a Lock

This method is used by VMware to establish whether a .vmdk file is locked by another process. Sometimes when you get an unclean shutdown of the owning VMware process, the file lock hangs around and the user must manually delete the file in order to boot the VM. This solution does not rely on a window handle and is thus applicable for any application that can access the disk which is good. However just like with with VMWare, using this as a solution for a single application instance could get us into a state where the user can’t run the app at all until they delete the lock file – not good.

CreateMutex

This is one of the most prevalent and well documented. This technique places a uniquely named mutex in the either the global namespace (for a single system-wide instance) or the local namespace (for a single session-wide instance) using the CreateMutex Win32 API call and then detecting whether the object already exists when the application first starts. The mutex is torn down when the last process that holds a handle to the object exits. This prevents use from getting in a stale state where we can’t start any instances of the application at all. Since this solution doesn’t require a handle to a window, it’s suitable for any type of Windows application (e.g. Windows Application/WinForm, Console, Service).

CreateEvent

This technique uses the same concept of a uniquely named event as the mutex technique. Also like the mutex solution, it’s suitable for any type of Windows application and the event is torn down when the last process that holds a handle to the event exits. The reason I choose this method over the global mutex however is that I overload the use of this event to serve as my shutdown signal. This allows me to use the same object to determine if an instance of an application is running as well as signal all instances of the application to terminate if necessary.

Based on my signal terminate solution here, you can limit an application to a single instance by removing this from initialize_terminate_event in signal_terminate.c

  // Make sure our instance of the application didn't already initialize the event
  if( fh_terminate_event != NULL )
  {
    return SUCCESS;
  }

and calling it at the beginning of your application’s main routine like this.

// Library Includes
#include <Windows.h>
#include <stdio.h>

// Application Includes
#include "error_codes.h"
#include "terminate.h"
#include "types.h"

Int32 main( Int32 argc, Char* argv[] )
{
  Int32 return_code = initialize_terminate_event( );
  // If the event already exists or if there is an error 
  // creating the event, just exit. 
  if( return_code != SUCCESS )
  {
     return return_code;
  }

  // Main routine here
}
Tags: ,

Leave a Reply

*