Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » TopWindow&PopUp, TrayIcon » How to check whether application is running
How to check whether application is running [message #27874] Mon, 09 August 2010 03:59 Go to next message
bushman is currently offline  bushman
Messages: 134
Registered: February 2009
Experienced Member
I need to run just one single instance of a TopWindow application per user at a time.
Is there a simple way of doing so in UPP? I mean, how do I check whether the app has been started before in Windows and abort (this) execution if so?

Thanks
Re: How to check whether application is running [message #27875 is a reply to message #27874] Mon, 09 August 2010 04:16 Go to previous messageGo to next message
bushman is currently offline  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 #27876 is a reply to message #27875] Mon, 09 August 2010 04:54 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

Hi Kropniczki,

This problem was already discussed here some time ago. Have a look at this thread, there are two solutions mentioned (including code) and hopefully helpful discussion.

Honza
Re: How to check whether application is running [message #27877 is a reply to message #27876] Mon, 09 August 2010 05:18 Go to previous messageGo to next message
bushman is currently offline  bushman
Messages: 134
Registered: February 2009
Experienced Member
The thread you pointed to did help. It does show a UPP-like, much "cleaner" way of doing the job. Thank you for that.
Re: How to check whether application is running [message #27922 is a reply to message #27877] Tue, 10 August 2010 21:28 Go to previous messageGo to next message
Mindtraveller is currently offline  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 #27925 is a reply to message #27922] Tue, 10 August 2010 22:47 Go to previous messageGo to next message
unodgs is currently offline  unodgs
Messages: 1366
Registered: November 2005
Location: Poland
Ultimate Contributor

I used the "windows way" in ultimate player (bazzar) so you can check it there.
Re: How to check whether application is running [message #28041 is a reply to message #27925] Fri, 13 August 2010 16:21 Go to previous messageGo to next message
kohait00 is currently offline  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 Go to previous messageGo to next message
Alboni is currently offline  Alboni
Messages: 214
Registered: January 2012
Location: Deventer, Netherlands
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 #38771 is a reply to message #38770] Wed, 16 January 2013 14:38 Go to previous messageGo to next message
lectus is currently offline  lectus
Messages: 329
Registered: September 2006
Location: Brazil
Senior Member
Another way would be to create a file when the app starts.

The app then always check for the existance of this file. If it exists then there's another instance, so quit.

The app needs to delete the file before finishing.
Re: How to check whether application is running [message #38772 is a reply to message #27874] Wed, 16 January 2013 15:44 Go to previous messageGo to next message
Alboni is currently offline  Alboni
Messages: 214
Registered: January 2012
Location: Deventer, Netherlands
Experienced Member
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.
Re: How to check whether application is running [message #38774 is a reply to message #38772] Wed, 16 January 2013 17:02 Go to previous messageGo to next message
nlneilson is currently offline  nlneilson
Messages: 644
Registered: January 2010
Location: U.S. California. Mojave &...
Contributor
Alboni wrote on Wed, 16 January 2013 03:29


CloseHandle(mutex);


lectus wrote on Wed, 16 January 2013 05:38

The app needs to delete the file before finishing.


Alboni wrote on Wed, 16 January 2013 06:44


Disadvantage is that the program doesn't want to start anymore after a crash,


Spent many hours related to this. That is ending a thread correctly.

CloseHandle(mutex);
delete the file before finishing
etc.

Which results in:
program doesn't want to start anymore after a crash,

A thread in many respects is like a separate application.
If it is not ended correctly it causes problems like an app cannot be started again until that thread is closed.

Or for something like a GPS USB receiver if the thread that it is run in does not close that port connection there is no easy way to close that except to pull the plug.

If a socket server has a port open another instance of that app or any other app that uses that port will not run unless error handling changes to another port number.

The best way I have found to close a thread is from INSIDE that thread.

There are many ways to check if an app is running but if that app crashes it can leave something hanging. Task Manager in Win, System Manager in Ubuntu, etc. is good if you know what you are looking for to close that thread.

To deploy an app this needs to be considered and have error handling and even instruction for a user.

If there is some 'magic' option it would be good to know.
Re: How to check whether application is running [message #38776 is a reply to message #27874] Wed, 16 January 2013 17:11 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

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 Smile

Honza
Re: How to check whether application is running [message #38777 is a reply to message #27874] Wed, 16 January 2013 17:38 Go to previous messageGo to next message
Alboni is currently offline  Alboni
Messages: 214
Registered: January 2012
Location: Deventer, Netherlands
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 #38778 is a reply to message #27874] Wed, 16 January 2013 18:01 Go to previous messageGo to next message
Alboni is currently offline  Alboni
Messages: 214
Registered: January 2012
Location: Deventer, Netherlands
Experienced Member
Neil,
The mutex is really a good solution because Windows will destroy it for you if your app terminates incorrectly.
Another idea is the use of memoryfiles, that is files that are created in memory instead of on disk.
I know it can be done with the CreatFile() system call on Windows.
Sadly I don't have sourcecode to share for that anymore because I wrote it for a previous employer.
More info: http://msdn.microsoft.com/en-us/library/windows/desktop/aa36 6542%28v=vs.85%29.aspx

Re: How to check whether application is running [message #38781 is a reply to message #38778] Wed, 16 January 2013 21:32 Go to previous messageGo to next message
BioBytes is currently offline  BioBytes
Messages: 307
Registered: October 2008
Location: France
Senior Member
Hi all,

I use the following code using SysInfo package:


bool QSkillsWin::IsSingleInstance()
{
    if(GetWindowIdFromCaption(GetTitle().ToString())>0)return true;
	  else return false;
}

GUI_APP_MAIN
{
	SetLanguage(GetSystemLNG());
	SetLNGCharset(GetSystemLNG(),CHARSET_UTF8);
	
	if(QSkillsWin().IsSingleInstance())
	{
		Exclamation("[=*A4@5 "+DeQtfLf(t_("QSkills s'exécute déjà !"))+"]");
		return;
	}
	 else QSkillsWin().Run();
}



hope this could be helpful

Cheers

Biobytes

Re: How to check whether application is running [message #38789 is a reply to message #38772] Fri, 18 January 2013 01:56 Go to previous message
lectus is currently offline  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.
Previous Topic: TopWindow minimum size
Next Topic: Timeout on PromptYesNo?
Goto Forum:
  


Current Time: Thu Mar 28 23:40:17 CET 2024

Total time taken to generate the page: 0.01610 seconds