Solution I
I used to use following simple way to manage the single instance of the app.
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;
}
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:
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;
}
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");