Preventing multiple instances of an application
Question
Monday, April 26, 2010 1:32 PM
I want to know which way to use to prevent multiple instances of my program.. i fount some information about some win32 API like GetActiveWindow BringWindowToTop to verify the window name but the topic wasn't clear.. so can anyone help me about this or direct me towards a docs section.
Thanks in advance :)
P.S : if possible, native solution please cause my application is a native c++.
/* Best Regards SectorC .....*/
All replies (7)
Monday, April 26, 2010 1:50 PM ✅Answered
Use mutex:
HANDLE hSingleInstanceMutex = CreateMutex(NULL, TRUE, L"SingleInstanceMutex");
DWORD dwError = GetLastError();
if (dwError == ERROR_ALREADY_EXISTS)
{
// Application already lunched
}
Nikita Leontiev
Monday, April 26, 2010 1:56 PM ✅Answered
class CMyApp : public CWinApp
{
.....
private:
HANDLE m_hMutexOneInstance;
};
BOOL CMyApp::InitApplication()
{
BOOL Ret = CWinApp::InitApplication();
m_hMutexOneInstance = CreateMutex(NULL,TRUE,MyMainWndClassName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
return FALSE;
}
return Ret;
}
int CLSEditorApp::ExitInstance()
{
if(m_hMutexOneInstance)
{
ReleaseMutex(m_hMutexOneInstance);
}
return CWinApp::ExitInstance();
}
Ali
Monday, April 26, 2010 2:00 PM ✅Answered | 3 votes
Hello SecotrC,
1. The classic technique of ensuring one single running instance of an application is to use a named Mutex object.
2. This can be achieved by calling the CreateMutex() API and specifying a name for the Mutex object to be created, e.g. :
HANDLE hMutexCurrentApp = CreateMutex
(
(LPSECURITY_ATTRIBUTES)NULL,
(BOOL)TRUE,
(LPCTSTR)"MY_APPLICATION"
);
3. Thereafter, call the GetLastError() API and check to see if the return value is ERROR_ALREADY_EXISTS :
DWORD dwLastError = GetLastError();
if (dwLastError == ERROR_ALREADY_EXISTS)
{
// Process already running.
CloseHandle(hMutexCurrentApp);
hMutexCurrentApp = NULL;
}
If the last error is indeed ERROR_ALREADY_EXISTS, it means that the Mutex object with the specified name has already been created previously (by an instance of the same program). Your program can then gracefully exit.
If the return value of GetLastError() is 0, it means that the named Mutex object has not been created previously. The current application thus owns the named mutex object.
4. Of course, at the end of the program itself, make sure that the handle of the mutex is closed, e.g. :
CloseHandle(hMutexCurrentApp);
hMutexCurrentApp = NULL;
This is to ensure that the Mutex object is released and another instance of the application can start up and own it. However, note that this is not strictly required because when the application ends, the owned Mutex object will be released by the OS.
- Bio.
Monday, April 26, 2010 2:00 PM
Thank you so much ;) very short very clear !/* Best Regards SectorC .....*/
Monday, April 26, 2010 2:04 PM
I was asking my self to find it in MFC too because right now im only using c++ native and win32 APIs but its good to keep your solution because i'll port my app to MFC soon. it's good to work with native cpp and direct win APIs to understand every piece of my app but it's a little bit difficult lol so i think a flash of interest to the famous MFC will matter ;). thank you for your help guys.
I love this MSDN place
/* Best Regards SectorC .....*/
Monday, April 26, 2010 2:14 PM | 1 vote
Well, there are two easy ways I can think of.
If your application is installed then it will be run from the same location as yours. So you can use the Tool Help functions to look for an executable named the same as yours with the exact same executable file path. You can get the executable name and path for the process you are checking through the tool help library and you can get the path of the current process through GetModuleFileName. (Just be sure that you are looking for the old instance of the executable, not your new instance, since there is always going to be one process with that name and path running.) The easiest way to figure out if the process you found using Tool Help is your process or another is by comparing the process ID. You can use GetCurrentProcessId to get your process' ID and compare it to the ID found using the Tool Help library.
The second easy option is to use a mutex. If you create a named mutex using CreateMutex and then check GetLastError, if you see that it returned the error ERROR_ALREADY_EXISTS then you know that the mutex has been created before so an instance of the application has existed. It also doesn't matter whether you make the current thread the initial owner because this mutex is there to just stop other instances of the program to start. Because you can guarantee that the mutex will be removed when your program terminates, it doesn't matter if it crashes the mutex will be removed. But on closing the program, close the mutex handle using CloseHandle just for good practice.
This is there to make sure that only one instance of the application exists. Now, if you find that your application is already being run what do you do. If it is a GUI application then you may want to bring the old instance of the application to the top. This is where you use GetActiveWindow, EnumWindows and BringWindowToTop. So you first check the current active Window, if it is the main Window of your application then just do nothing more and exit. If not then you will need to call EnumWindows to enumerate all top level windows to find your application, then call BringWindowToTop.
Of course, if there is no previous instance of your application, you just start up normally.
Visit my (not very good) blog at http://c2kblog.blogspot.com/
Monday, April 26, 2010 2:28 PM
Lim Bio Liong, you're a diamon mate :D very well explained .. Thank you !
Im so happy cause i added a new API to my bagage lol and thank you for taking all that time for explaining that to me i appreciated thank you.
your explaining is a cristal one .. you know i hope that microsoft explains its MSDN library like you did for the mutex thing .. lol but its good to read from real experts rather than a documentation ! because i believe in experience more than the theories.
Thanks a lot my app is already preventing multiple instances ;)
/* Best Regards SectorC .....*/