How to avoid multiple instances of your Windows application






4.67/5 (3 votes)
Solution II used to use following simple way to manage the single instance of the app.//Usually I append the UID to the application name to achieve the unique object name.TCHAR szAppName[] = _T("Application_Name_999e7ba3-e8fc-4c21-985b-ab11f39ce759");HANDLE hMutex =...
Solution I
I used to use following simple way to manage the single instance of the app.
//Usually I append the UID to the application name to achieve the unique object name. TCHAR szAppName[] = _T("Application_Name_999e7ba3-e8fc-4c21-985b-ab11f39ce759"); HANDLE hMutex = NULL; bool IsSecondInstance() { bool isSecondInstance = false; hMutex = CreateMutex(NULL, NULL, szAppName); int iLastError = GetLastError(); if(hMutex && (ERROR_ACCESS_DENIED == iLastError || ERROR_ALREADY_EXISTS == iLastError)) { ReleaseMutex(hMutex); hMutex = NULL; isSecondInstance = true; } return isSecondInstance; }Code usage is as follows:
int main() { if(IsSecondInstance()) { MessageBox(NULL, _T("One Instance Is Already Running."), _T("Information"), 0); return 0; } /*App Code Goes Here...*/ ReleaseMutex(m_hMutex); m_hMutex = NULL; return 0; }Solution II In the meanwhile, I modified the logic to achieve the OOPs concept.
class CAppGuard
{
private:
HANDLE m_hMutex;
const TCHAR *m_pszAppName;
public:
CAppGuard(TCHAR *szAppName = NULL): m_hMutex(NULL), m_pszAppName(szAppName)
{}
bool IsSecondInstance()
{
bool isSecondInstance = false;
m_hMutex = CreateMutex(NULL, NULL, m_pszAppName);
int iLastError = GetLastError();
if(hMutex && (ERROR_ACCESS_DENIED == iLastError || ERROR_ALREADY_EXISTS == iLastError))
{
ReleaseMutex(m_hMutex);
m_hMutex = NULL;
isSecondInstance = true;
}
return isSecondInstance;
}
~CAppGuard()
{
if(m_hMutex)
ReleaseMutex(m_hMutex);
m_hMutex = NULL;
}
};
Code usage is as:
//Append the UID to the application name to achieve the unique object name.
TCHAR szAppName[] = _T("Application_Name_999e7ba3-e8fc-4c21-985b-ab11f39ce759");
int main()
{
CAppGuard objAppGuard(szAppName);
if(objAppGuard.IsSecondInstance())
{
MessageBox(NULL, _T("One Instance Is Already Running."), _T("Information"), 0);
return 0;
}
/*App Code Goes Here...*/
return 0;
}
As the named kernel objects can be assessed across the terminal sessions, they can be named by prefixing the namespace. i.e. Global namespace or Local namespace.
i.e. "Global\\ObjectName", "Local\\ObjectName"
By considering Ajay's comment what minimum changes I could do is specify the app name as:
TCHAR szAppName[] = _T("Global\\Application_Name_999e7ba3-e8fc-4c21-985b-ab11f39ce759");or
TCHAR szAppName[] = _T("Local\\Application_Name_999e7ba3-e8fc-4c21-985b-ab11f39ce759");