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
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?