CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    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;
      }
    }

    Last edited by Andreas Masur; July 24th, 2005 at 04:46 PM.

  2. #2
    Join Date
    Nov 2003
    Location
    Portland, OR
    Posts
    894

    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
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured