Seite 1 von 1

Mehrfachausführen der Applikation unter Linux/Unix verhinder

Verfasst: 8. September 2006 10:24
von gerome69
Hallo zusammen,
würde gerne dafür sorgen, daß ein Anwender ein QT-Prog nur einmal unter Linux/Unix ausführen kann.

Unter QT-Windows löse ich das so:

Code: Alles auswählen

#include <windows.h>

[... in main()...]
HANDLE hMutex=CreateMutexA(NULL,TRUE,"ED-NewsEditor");
 bool foundInstance=FALSE;
if (GetLastError()==ERROR_ALREADY_EXISTS) foundInstance=TRUE;
if (hMutex) ReleaseMutex(hMutex);
if (foundInstance) {
    QMessageBox::warning(NULL,"","Programm ist bereits gestartet!"));
    QCoreApplication::exit();
    return 0;
}
Tja, unter Linux/Unix habe ich da erstmal nicht wirklich ne Idee.
Habe mir QMutex und QSemaphore angesehen, aber das geht wohl nur innerhalb der Child-Threads, nicht bei 2 unabhängig gestarteten Anwendungen.

Über Shell-Console-Aufruf ginge es sicher so:
ps ux|grep "appName"|grep -cv "grep" => Anzahl der Starts dieser Anwendung

Finde ich aber nicht wirklich elegant.

Hat jemand ne bessere Idee?

Danke für Tips, Bernd

Verfasst: 8. September 2006 10:47
von atlastraeger
Schau doch mal auf http://www.trolltech.com/products/qt/ad ... plication/.

Vielleicht reicht die spärliche Dokumentation ja für eine eigene Implementierung.

Verfasst: 8. September 2006 12:39
von gerome69
atlastraeger hat geschrieben:Schau doch mal auf http://www.trolltech.com/products/qt/ad ... plication/.

Vielleicht reicht die spärliche Dokumentation ja für eine eigene Implementierung.
Ja, sieht sehr gut aus. Genau das bräuchte ich.
Aber auf der Seite gibt es scheinbar keinen Download, nur den Hinweis:
Download Commercial Edition:
Only available for Qt Solutions license holder with a valid Support and Maintenance agreement (authentication required).
Tja, ich habe keine kommerzielle Lizenz. Dann bleibt mir der Zugang verschlossen?!

Gruß, Bernd

Verfasst: 8. September 2006 13:35
von ChMaster
genau so wie du es bei windows machst, kannst du es auch unter linux
lösen. schau dir mal QMutex und QMutexLocker an. empfehlenswert währe
auch noch, dir QProcess an zu schauen

das dürfte dir evtl weiter helfen.

ps.:
ist nur ein tip. ich habe QMutex und QMutexLocker noch nicht verwendet :)

Verfasst: 8. September 2006 14:26
von gerome69
ChMaster hat geschrieben:genau so wie du es bei windows machst, kannst du es auch unter linux
lösen. schau dir mal QMutex und QMutexLocker an. empfehlenswert währe
auch noch, dir QProcess an zu schauen

das dürfte dir evtl weiter helfen.

ps.:
ist nur ein tip. ich habe QMutex und QMutexLocker noch nicht verwendet :)
QMutex hatte ich mir ja schon angeschaut. Bei Windows sind Mutexe systemweit, sogar benutzerübergreifend. Die QMutexe, die ich in der 1. Instanze erzeuge, sind nur für diese Applikation und deren Childs greifbar.
Die als 2. gestartete Appl. kann nicht drauf zugreifen und weiß nicht, daß Appl. 1 schon läuft.
Oder ich hab es grob falsch gemacht?!

Gelöst habe ich es jetzt halt erstmal Shellaufruf:

Code: Alles auswählen

QProcess shell;
shell.start("ps ux");
if (shell.waitForStarted()) { // Falls kein Zugreif auf 'ps' möglich ist, geht der ganze Check nicht :-(
if (shell.waitForFinished()) {
QByteArray result = bash.readAll();
QStringList lines=QString(result).split("\n");
int count=0;
for (int i=0;i<lines.size();++i) 
    if (lines.at(i).indexOf("MyApplication")!=-1) count++;
if (count>1) {QMessageBox::warning(NULL,"","Application already runs.");
Gruß, Bernd

Verfasst: 9. September 2006 09:57
von patrik08
Ich habe es so geloest auf alle OS:

So dass jeder user nur einmal die applikation startet...
und die destrukt class loescht dass file LOCK_FILE_APPLICATION
und alles ist im butter ....

probleme gibt es nur wenn die applikation unstabil ist ... einfriert oder crascht...
dann muuss man per hand dass file loeschen...

Code: Alles auswählen

#define WORK_CACHEDIR \
              QString( "%1/.%2/" ).arg( QDir::homePath() , _PROGRAM_SHORT_NAME )

#define LOCK_FILE_APPLICATION \
              QString( "%1_application.lock" ).arg( WORK_CACHEDIR )

main .......

 QDir dira(WORK_CACHEDIR);
    if ( dira.mkpath(WORK_CACHEDIR) ) { } else {
    QMessageBox::warning( 0, "File error!", "Not possibel to create a work dir on: "+WORK_CACHEDIR);
    return -1;
    } 



if (!db.is_file(LOCK_FILE_APPLICATION)) {
                    db.file_put_contents(LOCK_FILE_APPLICATION,"");
                    Shop_Main::self()->setWindowTitle( _PROGRAM_TITLE );
                    Shop_Main::self()->show();
                    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
                    return a.exec();  
                } else {
                    return -1;
                }

Verfasst: 11. September 2006 00:27
von Nassian
Wenn ich keine Lösung ala Qt-Solutions hätte würde ich einen Socket verwenden. Die Applikation sendet vor dem Start an einen bestimmten Port bestimmte Daten, wenn was zurückkommt läuft schon eine Instanz und tschüss. Besser als die Lösung mit dem File, die wird schon inkonsisten wenn die Applikation absolut stabil läuft.

Verfasst: 11. September 2006 12:29
von Emperor_L0ser
Das mit den Sockets finde ich auch eine schlechte Idee, die Firewall gibt sofort Alarm, was mich als Anwender doch recht stuzig machen würde, wenn ich grade ein Programm starte, das sonst villeicht keine Netzwerkaktivitäten benötigt. Wahrscheinlich würde ich den Netzwerkzugriff blockieren und könnte das Programm damit wieder beliebig oft starten...

Die Version mit den Dateien ist unter Linux bereits ins System eingebaut. Den jeder Prozess bekommt seine eigene pid-Datei
Die beste Möglichkeit ist wohl leider für jedes BS das ganze selber zu bauen, unter Windows mit Mutex und unter Linux mit Dateien. Wobei ich mich frage, was ist es für ein außergewöhnliches Programm, das nur einmal unter Linux gestartet werden soll, warum darf nicht jeder benutzer eins haben?