Detecting a second instance of a program
by Richard Russell, July 2006
There may be situations when you need to ensure that only one copy of a program can be run at a time; an attempt to run a second copy should fail (with or without an error message being displayed). There are several ways in which this can be achieved, but the one described here is relatively simple and free from unwanted side effects; it uses the Windows API.
At the very start of your program add the following code:
SYS "CreateMutex", 0, 1, "UniqueLockName" TO Mutex% SYS "GetLastError" TO lerr% IF lerr% = 183 THEN SYS "CloseHandle", Mutex% QUIT ENDIF
You should replace the string UniqueLockName with a name which is extremely unlikely to be chosen by another program. It can consist of up to 260 characters so you can incorporate your program's name, your name and other distinguishing features to achieve this (the only character not allowed is backslash). One method is to generate a Globally Unique Identifier, or GUID, to use as the unique lock name for your program. A GUID is a 128-bit pseudo-random number which is statistically guaranteed to be unique. The number of possible unique values is so large (2^128 or 3.4028×10^38) that the chance of the same value being generated twice is virtually zero.
At the end of your program, just before it exits, add the following code:
SYS "ReleaseMutex", Mutex% SYS "CloseHandle", Mutex%
Ideally you should execute this code even if the program terminates abnormally, but in the event of a crash Windows should automatically delete the mutex for you.
With the above code an attempt to run a second copy of a program will fail with no error message. If you want to alert the user to the problem you can display a message box by amending the code at the beginning of the program as follows:
SYS "CreateMutex", 0, 1, "UniqueLockName" TO Mutex% SYS "GetLastError" TO lerr% IF lerr% = 183 THEN SYS "MessageBox", @hwnd%, "A copy of this program is already running", 0, 48 SYS "CloseHandle", Mutex% QUIT ENDIF