Categories
Uncategorized

Limiting Program Instances On Windows.

I discovered this issue while I was working on a Windows utility. I wanted to allow only one instance of my utility to run at a time. In this article, I will explain two potential methods and provide code for limiting program instances via a named mutex.

This article has been edited and re-posted from my old blog.

Two solutions come to mind for dealing with this specific issue: first, you can iterate over all processes and check for a process by your process name but with a different PID (process ID). The pitfall with this solution is that were a user to rename your process or have a separate versions installed, this would fail the check.

The second solution I discovered was to create a named mutex. A mutex is a mechenism used to synchronise access to a resource. When the mutex exists, that resource is busy. If the mutex can be acquired (meaning that it did not exist and you can create it), you have access to the resource. In this case, the resource is a single instance of our process.

You can accomplish this using the following code:

#define SHARED_MUTEX_NAME "MyApplicationMutex"
bool IsFirstInstance()
{
HANDLE instance = OpenMutex(STANDARD_RIGHTS_READ, false, SHARED_MUTEX_NAME);
if (instance)
{
return false;
}
instance = CreateMutex(NULL, false, SHARED_MUTEX_NAME);
return true;
}

Breaking this down:
#define SHARED_MUTEX_NAME "MyApplicationMutex"
It helps to use a define here so that you will avoid any issues. For example, if you update the string for the call to OpenMutex but forget to update the string for the creation of the mutex should it not exist, you will have introduced a bug.

bool IsFirstInstance()
{
HANDLE instance = OpenMutex(STANDARD_RIGHTS_READ, false, SHARED_MUTEX_NAME);

Here we call OpenMutex to attempt to open the mutex with the specified name. We want only read rights, which we request as the first parameter.

if (instance)
{
return false;
}

If this mutex is valid, that means that OpenMutex found a mutex by the specified name and this is not the first instance.

instance = CreateMutex(NULL, false, SHARED_MUTEX_NAME);

Because the mutex was not able to be opened, we create a new mutex here.

return true;
}

Here too, there are some notable pitfalls. First, if a process with higher access owns the mutex, you may be unable to open it, which would tell the program that it is not the first instance. The OpenMutex docs state that GetLastError will return ERROR_FILE_NOT_FOUND if the mutex was not found, which may be a useful secondary check.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.