2010-11-03 8 views
10

Ich möchte, dass meine Anwendung nur einen Prozess öffnet, d. h. wenn der eine Prozess bereits geöffnet ist und der Benutzer die exe erneut öffnen möchte, wird kein anderer Prozess geöffnet.Wie erzwinge ich meine Anwendung, nur eine Exe zu öffnen? qt, linux

Wie kann ich es in Qt - Linux tun?

10x!

+3

Sie sollten wirklich Antworten auf Ihre Fragen akzeptieren, es sei denn, Sie wollen nicht, dass die Leute mehr antworten. – ereOn

Antwort

0

Ihre Anwendung könnte überprüfen, ob eine bestimmte Datei im Home-Verzeichnis des Benutzers vorhanden ist. Wenn es vorhanden ist, wird die Anwendung beendet. Wenn es nicht dort ist, erstellt die Anwendung es und fährt fort. Natürlich können Sie eine Wettlaufbedingung erhalten, wenn der Benutzer die Anwendung mehrmals gleichzeitig startet. In den meisten Fällen sollte diese einfache Lösung jedoch ausreichen.

+0

Ich weiß nicht, wer das aufgewertet hat, und warum. Aber das ist gefährlich und nicht tragbar. 'Qt' hat native Unterstützung für diese Funktion, daher ist es ratsam, sie zu verwenden. – ereOn

+0

Ich stimme "nicht tragbar" zu und dass QtSingleApplication die bessere Option ist. Aber warum gefährlich? Wegen der Race Condition? Ein offenes O_CREATE-Flag in der open() sollte damit umgehen .. – bew

+0

Gefährlich, weil jemand, der diese Datei von Hand erstellt, kann Ihr Programm verhindert werden. – ereOn

23

Was Sie suchen, ist QtSingleApplication.

Wenn Sie eine andere Instanz Ihrer Anwendung starten, wird die erste Instanz sogar benachrichtigt (Sie können die gewünschte Datenstruktur übergeben).

Ich habe es verwendet, um die vorhandene Anwendung in den Vordergrund zu bringen, wenn eine andere Instanz gestartet wird.

+0

Downvoted, da QtSingleApplication nur im aktuellen Benutzerprozess funktioniert.Es funktioniert nicht, wenn andere Benutzer den gleichen Prozess in anderen Benutzersitzungen starten. –

+5

@JimInTexas: Nichts für ungut, aber das OP wollte nur einen Weg, um zu verhindern, dass derselbe Benutzer mehrere Prozesse seiner eigenen Anwendung startet. Zu diesem Zweck ist "QtSingleApplication" genau das, was er benötigt. Nun wird es vielleicht nicht in Ihren speziellen Anwendungsfall passen, aber das ist für die Frage irrelevant. Normalerweise werden die Antworten wegen falscher Antworten abgelehnt, und was diese Frage angeht, ist dies nicht der Fall. Ist es ? – ereOn

15

Verwenden Sie den folgenden Code in der Datei main.cpp, um zu verhindern, dass mehr als eine Instanz Ihrer Anwendung ausgeführt wird. Ich habe diesen Code unter Linux (in QtCreator) getestet und es funktioniert (funktioniert auch für Windows). Ich finde diese Lösung einfach und einfach zu implementieren. Das Beispiel ist für eine Konsolenanwendung. Der Code bleibt für eine GUI-Anwendung gleich, überprüfen Sie die Kommentare im Code.

//main.cpp 
#include <QCoreApplication> //Console application 
//#include <QApplication>  //GUI application 
#include <QSharedMemory> 
#include <QDebug> 
//Your QMainWindow derivated class goes here : 
//#include "MainWindow.h" 

int main(int argc, char *argv[]) 
{ 

    QCoreApplication app(argc, argv); 

    app.processEvents(); 

    //---- Check for another instance code snippet ---- 

    //GUID : Generated once for your application 
    // you could get one GUID here: http://www.guidgenerator.com/online-guid-generator.aspx 
    QSharedMemory shared("62d60669-bb94-4a94-88bb-b964890a7e04"); 

    if(!shared.create(512, QSharedMemory::ReadWrite)) 
    { 
    // For a GUI application, replace this by : 
    // QMessageBox msgBox; 
    //msgBox.setText(QObject::tr("Can't start more than one instance of the application.")); 
    //msgBox.setIcon(QMessageBox::Critical); 
    //msgBox.exec(); 

    qWarning() << "Can't start more than one instance of the application."; 

    exit(0); 
    } 
    else { 
     qDebug() << "Application started successfully."; 
    } 
    //---- END OF Check for another instance code snippet ---- 

    // Only one instance is running, declare MainWindow 
    //MainWindow myMainWindow; 
    //myMainWindow.show(); 


    //We enter the Qt Event loop here, we don't leave until the MainWindow is closed 
    //or the console application is terminated. 
    return app.exec(); 
} 
+0

Wie kann ich das Hauptfenster der Anwendung öffnen, wenn die Anwendung bereits gestartet wurde? – devdev

+1

Wenn Sie Ihre Anwendung starten und es die einzige Instanz ist, wird die Ausführung die Qt-Ereignisschleife (app.exec) erreichen und Ihr Hauptfenster wird als normal angezeigt. Wenn es nicht die einzige Instanz ist, die ausgeführt wird, erreicht die neue Instanz exit(), bevor das Hauptfenster angezeigt wird. Ihr vorhandenes Fenster bleibt geöffnet. Ich habe einige weitere Kommentare in meinem obigen Beispiel hinzugefügt. –

+3

Zu zerbrechlich denke ich - wenn die Anwendung abstürzt, hinterlässt sie das sharedmem-Segment und Sie können den Prozess nicht neu starten. "Wenn der letzte Thread oder Prozess jedoch abstürzt, ohne den Desaster QSharedMemory auszuführen, überlebt das Shared Memory-Segment den Absturz." (QSharedMemory-Dokumentation) –

3

Das mag Sie nicht interessieren, aber ich dachte, es wäre nützlich, es zu bringen. Ich benutze selbst QtSingleApplication und habe vor ein paar Tagen ein seltsames Verhalten erlebt. QtSingleApplication scheint nicht unter allen Umständen zu funktionieren. Ich habe diese Erfahrung in Windows gemacht, aber abhängig davon, ob dies ein Windows-spezifischer Fehler ist oder durch das Design von QtSingleApplication beabsichtigt ist, kann es auch für Linux gelten.

Je nachdem, wie Sie Ihre Anwendung starten, sind mehrere Instanzen möglich. Ich habe diese Erfahrung gemacht, als ich mit meinem Installer eine Testversion meiner Anwendung erstellte. Das Installationsprogramm startet die Anwendung nach dem Beenden automatisch. Als ich dann meine Anwendung über den Desktop-Link gestartet habe, hatte ich zwei Instanzen ausgeführt. Die Funktionalität von QtSingleApplication hängt also davon ab, wie (und von welchem ​​Benutzer?) Die Anwendung gestartet wird. Die Dokumentation ist unklar. Aber ich denke normalerweise würde man erwarten, dass dies unter allen Umständen funktioniert, wenn nicht anders angegeben.

Also, wenn Sie nicht die zusätzliche Funktionalität von QtSingleApplication, QSystemSemaphore oder QSharedMemory hinzugefügt scheint der beste Weg zu gehen.

Verwandte Themen