
| Last Modification: December 11, 1999 |
How do I prevent a the user from starting a second instance of my
app?
The safest way is to use a named Mutex. You can do it like this:
BOOL CMyApp::IsAppRunning ( )
{
HANDLE hMutex = NULL;
hMutex = CreateMutex ( NULL, TRUE, _T("MySpecialMutexNameHERE") );
if ( GetLastError() == ERROR_ALREADY_EXISTS )
{
CloseHandle ( hMutex );
return TRUE;
}
return FALSE;
}
Make sure you change the Mutex name to something unique for your app. Now, all you have to do from your InitInstance() is :
if ( IsAppRunning () ) return FALSE;
The only problem with this function is that you leak the mutex handle when it does
get created. It's not much of a problem because it will get closed by Windows when
the app exits (which is what we want, anyway), but it's consider bad programming
practice. For those of you more strict, here's another approach, provided by
Aaron J. Margosis, that uses a simple class. All you have to do is create an
instance of the class when your program starts and where it won't go out of
scope until it exits (a member of your CWinApp-derived class will be just fine):
// ----------------------------------------------------------------------
// Uses named mutex to guarantee a single instance with the same name
// on this machine. If another process has already created an instance
// with the same name, "First()" will return FALSE.
//
// The object must not be destroyed until the process exits.
class OnlyOne
{
public:
OnlyOne( LPCSTR mutexName )
: m_mutex( CreateMutex(NULL, TRUE, mutexName ) ),
m_error(GetLastError() )
{}
~OnlyOne()
{
if ( m_mutex)
{
CloseHandle( m_mutex );
}
}
BOOL First() const
{ return ( m_error == 0 ); }
private:
// These MUST be declared in this order:
HANDLE m_mutex ;
DWORD m_error ;
private:
// Not implemented:
OnlyOne( const OnlyOne & );
OnlyOne & operator = ( const OnlyOne & ) ;
};
Once again, pick a unique name for the mutex for each app you use any of the above methods
in. One way to virtually guarantee that the name will be unique is to use the textual
representation of a GUID generated for each app, which you can use using guidgen.exe
or a similar tool.
References and Samples: