Over the past few months, a few people on the CPB-Thread listserv have asked how to prevent more than one instance of an application from being started. (To subscribe to CPB-Thread, visit www.cobb.com/cpb.) Several people have worked very hard on a variety of answers to this question. It seems, though, that the simplest solution is one suggested by members of Borland's TeamB on their news server: a named mutex. As you know, Windows 95 provides a number of built-in functions for running multiple tasks and threads within a task. Accordingly, a group of Synchronization functions is available to ensure that your tasks and threads are able to work together effectively.
One of the more common problems in a multitasking environment is resource sharing. If you're using a resource--for example, a serial port--you don't want somebody else to start using it before you're finished. The standard solution to this problem is for you to get a mutual exclusion lock (mutex) on the resource. If you're able to get the lock, you can use the resource. If, while trying to lock the resource, you find that somebody else has it--you must wait.
In this article, we'll build a small and very simple function to return true if an instance of a program is already running. To do this, we'll use a simple named mutex. (You can download the code from this article at www.cobb.com/cpb.) Let's start by looking at how you can use a mutex.
Once a mutex exists, any tasks trying to create it again will get a handle to it and an error already exists error. If a task ends, all the mutex handles that it owns are closed. When all tasks have closed their handles to a mutex, it's destroyed. Therefore, a single call to the CreateMutex() function is all you need to find out if an instance of an application is already running!
By now you've probably realized that there really isn't much to it--you can very easily detect an existing instance of an application using this method. Listing A shows the source code for one way to do it.
Listing A: Detecting another instance of an application
//---------------------------------
-----------#include <vcl\vcl.h>
#pragma hdrstop
//--------------------------------
------------USEFORM("OneOnlyForm.cpp", Form1);
USERES("OneOnly.res");
//--------------------------------
------------// the name of the mutex for this program
const char *MutexName = "OneOnlyDemo";
//---------------------------
-----------------HANDLE
CheckInstance( const char *Name )
{
// 1st: create mutex. Request ownership.
HANDLE Mutex = CreateMutex(NULL,true,Name);
// Next, error result - should be zero
int r = GetLastError();
// if r != 0, probably ERROR_ALREADY_EXISTS
if ( r != 0 )
return 0; // disaster or another instance
return Mutex; // else, return the handle.
}
//----------------------------
----------------WINAPI WinMain
(HINSTANCE,HINSTANCE,LPSTR, int)
{
HANDLE Mutex = CheckInstance( MutexName );
if ( !Mutex )
{ MessageBox(HInstance,
"Another Instance is running!",
"Sorry", MB_OK );
ReleaseMutex( Mutex );
return 1;
};
try
{
Application->Initialize();
Application->CreateForm(__classid(
TForm1),&Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
//--------------------------------------------