|
|
Home » U++ Library support » TopWindow&PopUp, TrayIcon » How to check whether application is running
|
Re: How to check whether application is running [message #27875 is a reply to message #27874] |
Mon, 09 August 2010 04:16   |
 |
bushman
Messages: 134 Registered: February 2009
|
Experienced Member |
|
|
I´ve been proceeding as follows:
// global function:
HWND GetRunningWindow() {
// Check if exists an application with the same TITLE as this application
HWND hWnd = FindWindow(NULL, "My TopWindow Title");
if (IsWindow(hWnd)) {
HWND hWndPopup = GetLastActivePopup(hWnd);
if (IsWindow(hWndPopup))
hWnd = hWndPopup; // Previous instance exists
} else {
hWnd = NULL; // Previous instance doesnt exist
}
return hWnd;
}
GUI_APP_MAIN
{
// Checks for previous instance of our app
HWND hOtherWnd = GetRunningWindow();
// Allow only one app instance
if (hOtherWnd) {// hOtherWnd != NULL -> Previous instance exists
PromptOK("The program is already running");
SetForegroundWindow(hOtherWnd); // Activate it &
if (IsIconic(hOtherWnd))
ShowWindow(hOtherWnd, SW_RESTORE); // restore it
return; // Abort current app execution
}
// ... otherwise, run app here ...
}
Thanks again.
[Updated on: Mon, 09 August 2010 04:29] Report message to a moderator
|
|
|
|
|
Re: How to check whether application is running [message #27922 is a reply to message #27877] |
Tue, 10 August 2010 21:28   |
Mindtraveller
Messages: 917 Registered: August 2007 Location: Russia, Moscow rgn.
|
Experienced Contributor |

|
|
The *recommended* (by M$) way of detecting other instances of application is using of named mutex. Making mutex is much cheaper and much more atomic operation than creating window. Why is that important?
Imagine you have system with many programs running. And your program makes some complex initialization prior to creating window (i.e. reading XML configuration, constructing objects, etc.)
User runs your app. But OS is busy, it starts swapping. Your app is actually started, but user doesn't see any window, because your app is still initializing (please note that creating window is very resource consuming operation, especially for "busy" OS).
What happens next? User thinks that he did something wrong and executes your app again. This is problem #1.
The problem #2 arises next. Your app which was started second checks window (remember that window of the first app is not finished it's creation), doesn't find it and creates it's own window as if it is the first.
If you think this is rare situation, I must admit it is not. Multitasking can be hard sometimes. And app #2 can potentially be initialized even BEFORE app #1.
That is all why we should use much cheaper and quicker operation in the program start instead of checking opened window.
Let's return to recommended scheme:
1. Check mutex with name "*****"
2. If exists, exit app. If not - immediately create one and start app.
3. Important: all initialization should be done AFTER (1) and (2).
I don't know which is POSIX recommended way. I think our POSIX specialists may consult us.
|
|
|
|
Re: How to check whether application is running [message #28041 is a reply to message #27925] |
Fri, 13 August 2010 16:21   |
 |
kohait00
Messages: 939 Registered: July 2009 Location: Germany
|
Experienced Contributor |
|
|
i used in my app stuff like this:
which is exactely what Mindtraveler described. code snipet like this can be found online in many places..
the name define doesnt really matter, it was only for me. it has to be something unique though, beeing shure noone else will ever use on your system except you.
with SINGLE_APPINSTANCE you can enable or disable this behaviour
//at beginning of your programm#define SEMAPHORE_UNIQUE "Global\\LIPANv2Unique_2FA34E51"
#ifdef SINGLE_APPINSTANCE
#ifdef PLATFORM_WIN32
USemh = OpenSemaphore(STANDARD_RIGHTS_ALL, FALSE, SEMAPHORE_UNIQUE);
if(USemh == NULL)
USemh = CreateSemaphore(NULL, 0, 1, SEMAPHORE_UNIQUE);
else
{
wq & THISBACK1(Closer, "Application already started!!"); //prepare
return;
}
#elif defined(PLATFORM_POSIX)
#endif
#endif
//program runtime....
//at end of your program
#ifdef SINGLE_APPINSTANCE
#ifdef PLATFORM_WIN32
if(USemh != NULL)
CloseHandle(USemh);
USemh = NULL;
#elif defined(PLATFORM_POSIX)
#endif
#endif
[Updated on: Fri, 13 August 2010 16:22] Report message to a moderator
|
|
|
Re: How to check whether application is running [message #38770 is a reply to message #27874] |
Wed, 16 January 2013 12:29   |
 |
Alboni
Messages: 216 Registered: January 2012 Location: Kajaani, Finland
|
Experienced Member |
|
|
GUI_APP_MAIN
{
HANDLE mutex = ::CreateMutex(0, true, "__MYAPP_EXE__");
if (!mutex)
{
PromptOK("Cannot open MUTEX.");
return;
}
if (GetLastError()==ERROR_ALREADY_EXISTS)
{
PromptOK("Program is already started.");
CloseHandle(mutex);
return;
}
App().Run();
CloseHandle(mutex);
}
[Updated on: Wed, 16 January 2013 12:29] Report message to a moderator
|
|
|
|
|
|
Re: How to check whether application is running [message #38776 is a reply to message #27874] |
Wed, 16 January 2013 17:11   |
|
BTW, when looking at CreateMutex docs, I found this:
Quote: | If you are using a named mutex to limit your application to a single instance, a malicious user can create this mutex before you do and prevent your application from starting. To prevent this situation, create a randomly named mutex and store the name so that it can only be obtained by an authorized user. Alternatively, you can use a file for this purpose. To limit your application to one instance per user, create a locked file in the user's profile directory.
|
It sounds reasonable and logical... and it never occurred to me before that I should do it 
Honza
|
|
|
Re: How to check whether application is running [message #38777 is a reply to message #27874] |
Wed, 16 January 2013 17:38   |
 |
Alboni
Messages: 216 Registered: January 2012 Location: Kajaani, Finland
|
Experienced Member |
|
|
Except at least on Windows, if you have rights to execute the program, finding out what an application is creating is a matter of running a debugtool. The app doesn't need debugsymbols for that.
So this scheme would only work if 2 mutexes were used:
The app would then:
1)generate a new name and create a new mutex
2)try to open a mutex with the previous name stored in an encrypted file and if succeeds store this name, if not terminate.
other ideas that I used in practise
1)instead of displaying an error message, you can also bump the running instance.
2)instead of terminating, close the running instance by sending a signal to it, wait for it to terminate, if it doesn't terminate on time, forcefully kill it. Then proceed starting the app.
[Updated on: Wed, 16 January 2013 17:48] Report message to a moderator
|
|
|
|
|
Re: How to check whether application is running [message #38789 is a reply to message #38772] |
Fri, 18 January 2013 01:56  |
lectus
Messages: 329 Registered: September 2006 Location: Brazil
|
Senior Member |
|
|
Alboni wrote on Wed, 16 January 2013 09:44 | Yes, I've seen a number of programs that do just that. Moest of them were on linux.
Disadvantage is that the program doesn't want to start anymore after a crash, and then an admin has to come who knows where that file is located and delete the file.
That could also be feature btw, if the program also checks for the existance of an application window or mutex to determine if it was a crash or a double start and then can take special measures in case of a crash such as rebuilding a databaseindex, submit a crash report or restoring the state of the program.
|
void ChangeStatus() {
SaveFile(GetExeDirFile("lock"), "Finished succesfully");
}
if(!FileExists(GetExeDirFile("lock")))
SaveFile(GetExeDirFile("lock"), "Finished sucessfully");
String status = LoadFile(GetExeDirFile("lock"));
if(status == "running")
{
Exclamation("There's another instance!");
return;
}
if(status == "crashed") {
Exclamation("The program crashed on the last run. Please restart the application.");
RecoverData();
ChangeStatus();
return;
}
SaveFile(GetExeDirFile("lock"), "running");
atexit(ChangeStatus);
Before critical part of the program:
SaveFile(GetExeDirFile("lock"), "crashed");
DoLongOperations(); // if it crashes now we're safe
SaveFile(GetExeDirFile("lock"), "running"); // We survived
If you want to get fancy, add time stamps.
|
|
|
Goto Forum:
Current Time: Fri Apr 25 20:35:58 CEST 2025
Total time taken to generate the page: 0.03322 seconds
|
|
|