MFC Application: How can I limit my application to one instance?
Q: How can I limit my application to one instance?
A: You need to create a named mutex semaphore when you start your application. When the second one starts it tries to get access to the mutex but will fail...
Code:
// app.h
class CYourApp : public CWinApp
{
...
private:
HANDLE hMutex;
};
// app.cpp
BOOL CYourApp::InitInstance()
{
// Create mutex
hMutex = ::CreateMutex(NULL, TRUE, "GlobalMutex");
switch(::GetLastError())
{
case ERROR_SUCCESS:
// Mutex created successfully. There is no instance running
break;
case ERROR_ALREADY_EXISTS:
// Mutex already exists so there is a running instance of our app.
return FALSE;
default:
// Failed to create mutex by unknown reason
return FALSE;
}
}
<br><br>
1 Attachment(s)
Re: MFC Application: How can I limit my application to one instance?
First of all, thank you for this post. I want to update it with additional specification. In my case I needed to limit the app to single instance across all terminal server sessions (i.e., multiple users logged on at the same time in Windows XP).
When the app initializes:
Code:
//Declare security attributes
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
//Initialize security descriptor
BOOL bGotSA = FALSE;
SECURITY_DESCRIPTOR sd;
if(InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
//Set security descriptor (Null DACL)
if(SetSecurityDescriptorDacl(&sd, TRUE, (PACL)NULL, FALSE))
{
bGotSA = TRUE;
sa.lpSecurityDescriptor = &sd;
}
}
//Create named mutex
BOOL bSecondInstance;
HANDLE hMutex;
LPCTSTR pMutexName = "Global\\Logon_Session_Mutex_1";
int nErr;
if(bGotSA)
{
//Got security descriptor
hMutex = CreateMutex(&sa, FALSE, pMutexName);
nErr = ::GetLastError();
bSecondInstance = hMutex && nErr == ERROR_ALREADY_EXISTS;
}
else
{
//No security descriptor
hMutex = CreateMutex(NULL, FALSE, pMutexName);
nErr = ::GetLastError();
bSecondInstance = (hMutex && nErr == ERROR_ALREADY_EXISTS) || nErr == ERROR_ACCESS_DENIED;
}
if(bSecondInstance)
{
//More than one instance of this app is running
//Show message and exit
}
And then release the mutex when the app exits:
Code:
//Close mutex
if(hMutex)
CloseHandle(hMutex);
In case someone is interested in the source code, it is attached.
Cheers :)