PDA

View Full Version : QT app Run once



bunjee
12th February 2008, 20:38
Is there a way to prevent a QT app to be executed twice ?

marcel
12th February 2008, 20:49
If you are a commercial user and willing to pay a few bucks more, then QtSingleApplication (http://trolltech.com/products/qt/addon/solutions/catalog/4/Utilities/qtsingleapplication/) is for you :).

przemoc
12th February 2008, 21:16
if you are not a commercial user, then you have few choices.
On *NIX often used approach is creating a lock file (Unix Daemon Server Programming (http://www.enderunix.org/documents/eng/daemon.php)), on Windows - creating a mutex (MSDN: Mutex Objects (http://msdn2.microsoft.com/en-us/library/ms684266(VS.85).aspx)).

marcel
12th February 2008, 21:21
There are better ways on Windows than with an interprocess mutex.
One would be: "On Windows the implementation uses FindWindow() to detect a running instance, and the WM_COPYDATA message to send string data." This is from the QtSingleApplication documentation. One could also use lock files on windows too.

przemoc
12th February 2008, 21:41
There are better ways on Windows than with an interprocess mutex.
I didn't say that mutexes are the best.

One could also use lock files on windows too.
Of course, and mutexes (or semaphores, depends on chosen "backend" - POSIX or not) on unix. There are also named pipes, shared memory (without mutexes we can get races, but I bet there exists a program using only shm to achieve only one instance running, in most cases it'll work...) and others that I not remember right now.

marcel
12th February 2008, 21:47
I only wanted to point the solution used by the QtSingleApplication.
I am sure they opted for the most efficient solution when they implemented that class.



Of course, and mutexes (or semaphores, depends on chosen "backend" - POSIX or not) on unix. There are also named pipes, shared memory (without mutexes we can get races, but I bet there exists a program using only shm to achieve only one instance running, in most cases it'll work...) and others that I not remember right now.
There are many methods, I can't argue with that. But some of them are almost "theoretical". There's no winning in implementing them.
On Unix they use: "On X11 systems the implementation uses X atoms to communicate through the selection mechanism.".

bunjee
13th February 2008, 00:34
Can't believe you have to pay additional fees for such a class.

marcel
13th February 2008, 10:00
Why don't you create it yourself?
You have all the necessary information...

bunjee
13th February 2008, 13:41
Well that's why you use Qt over MFC, because you don't have to code architecture specific components. If one purchase a Qt license he could expect to have this crucial feature out of the box.

Correct me if I'm wrong but QtSinglaApp feels more like : "Too bad you need to pay extra bucks for doing that crucial feature".
Instead of
"It's so complicated to develop we've decided to charge you more".

Anyway, thanks for the help guys :).

marcel
13th February 2008, 13:44
If one purchase a Qt license he could expect to have this crucial feature out of the box.

It is not a crucial feature. You just feel like that because you need it right now.
If you'd have started to implement your own last night when you first asked about it, it would have been ready right now. Twice :).

bunjee
13th February 2008, 13:49
It is not a crucial feature. You just feel like that because you need it right now.
If you'd have started to implement your own last night when you first asked about it, it would have been ready right now. Twice :).

I guess that's the difference between you and me marcel. I'm taking one week to develop such a feature :-).

marcel
13th February 2008, 13:53
I guess that's the difference between you and me marcel. I'm taking one week to develop such a feature :-).
But why? It shouldn't. I find it very useful that Trolltech offered some insight on how QtSingleApplication was implemented. Once you had this information, the Internet is full of documentation on FindWindow and WM_COPYDATA, and the other methods used on the other platforms.

bunjee
13th February 2008, 14:00
Right,
I'll take a look and I'll post my home-made implementation.

And guess what ? It'll be free.

THRESHE
13th February 2008, 15:29
Anybody knows where can I get first parameter for FindWindow function? It is registered window class name and I don't know how to obtain it :(

jpn
13th February 2008, 15:53
Just as docs (http://msdn2.microsoft.com/en-us/library/ms633499(VS.85).aspx) say, use RegisterClass(). If title is enough, you can do:


WId QxtWindowSystem::findWindow(const QString& title)
{
std::wstring str = title.toStdWString();
return ::FindWindow(NULL, str.c_str());
}

THRESHE
13th February 2008, 16:01
It's funny today I've asked two questions and 5 minutes after I've found a solution myself :)
But I suppose that hardcoding window name is not the best idea...
I've done it like this

wchar_t *str = new wchar_t[16];
mbstowcs(str,"My Window Title", 16 );
qDebug()<<"------------------------------------";
qDebug()<<FindWindow(0, str);
qDebug()<<"------------------------------------";

But anyway thanks jpn ;)

THRESHE
15th February 2008, 18:04
Does anybody know how to implement run once application on Mac OS X ? In the docs on QSingleApplication I've read that they use "named ports". Anyone knows what is it ? Some links would be very useful... :)

bpetty
4th March 2008, 20:55
Yeah, I needed that class... but then I found out that even though I have a commercial developer license I needed to buy a special license just to get it. So to make a long story short... I spent 5 minutes and I wrote my own. I have my own cross platform mutex/semaphore class and I used it.

Here is a quick example of how it works using semaphore.h... as if you didn't know.


// Example using <semaphore.h> under linux.
string sSemaphoreKey = "test777";

cout << "Opening semaphore: " << sSemaphoreKey << endl;

sem_t* mySemaphore = sem_open(sSemaphoreKey.c_str(), O_CREAT|O_EXCL, S_IRUSR|S_IRGRP|S_IROTH, 1);

if (mySemaphore == SEM_FAILED)
{
cout << "Failed to open semaphore: " << sSemaphoreKey << endl;
return 1;
}

Anyone thinking about buying that crappy class should light a 100$ bill on fire so they can learn before hand what it is like to burn money.

codeslicer
5th March 2008, 00:25
Anyone thinking about buying that crappy class should light a 100$ bill on fire so they can learn before hand what it is like to burn money.

Hmm, not bad, but what's sem_open? Nvm, I'll figure something out and post here.

codeslicer
6th March 2008, 01:38
I was going to make my own code, but then I decided to look around for some open source apps which already implemented this. Then I found the infamous QGRUBEditor (now known as KGRUBEditor). I looked in the source code and I found this in main.cpp:



QFile lockFile( QDir::tempPath() + "/qgrubeditor.lock" );
if ( lockFile.open( QIODevice::ReadOnly ) )
{
QTextStream lockStream( &lockFile );
if ( QDir( "/proc/" + lockStream.readLine() ).exists() )
{
qWarning( "QGRUBEditor: Already running" );
return 0;
}
lockFile.close();
}
if ( lockFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
{
QTextStream lockStream( &lockFile );
lockStream << getpid() << endl;
lockFile.close();
}


Now, this code isn't very system independent. To make it system-independent, we /proc/ and getpid() has to be eliminated. So, how would I find out an "id" of the application?

Or, is there an alternative way? Using sockets seems wrong... it looks like it can cause problems for other applications.

This is another idea: What if I create, in the event loop, a function which will constantly update the lockfile with the current time, and then have a new instance of the application check if the time of the file is different from the current file. This will use too much hard drive though...
Locking a file seems a good idea, and the Qxt extension contains a file locking class. Perhaps I could import some of the more vital functions from there? Also, is the file unlocked when the process is terminated?


If there is no system-independent way, how would I achieve this? I already have the code for Linux, but I don't have a Mac to test the code on nor do I know of any way to check it on Windows. Semaphores - do they work in between applications?

Well... if anyone has any bright ideas, please make a new thread or reply here. Thanks!

bunjee
6th May 2008, 22:30
Alright, I did the implementation for Windows if anyone is interested.

ramazangirgin
9th May 2008, 13:39
Hi,
Can we use this with network shared files?How? We have files on network and if somebody open file for write,others mustn't open it.How can understant file was opened?
i want to use this approach with microsoft network and samba shares.Is this lock file approach enough for me???
Thanks in advance
Ramazan

GreyGeek
9th May 2008, 16:07
I only wanted to point the solution used by the QtSingleApplication.
I am sure they opted for the most efficient solution when they implemented that class.

There are many methods, I can't argue with that. But some of them are almost "theoretical". There's no winning in implementing them.
On Unix they use: "On X11 systems the implementation uses X atoms to communicate through the selection mechanism.".

We didn't.

I'm using Qt 4.3.3 and the "QtSingleApplication" class is not listed in the Assistant.

What version was/is it in?