2010-11-03 5 views
10

Deseo que mi aplicación abra solo un proceso, es decir, si el único proceso ya está abierto y el usuario desea abrir el exe nuevamente, no abrirá otro proceso.¿Cómo forzar a mi aplicación a abrir solo un exe? qt, linux

¿cómo puedo hacerlo en Qt - linux?

10x!

+3

Realmente debería aceptar respuestas a sus preguntas a menos que ya no quiera que la gente responda. – ereOn

Respuesta

0

Su aplicación podría verificar si un determinado archivo en el directorio de inicio del usuario está presente. Si está presente, la aplicación sale. Si no está allí, la aplicación lo crea y continúa. Por supuesto, puede obtener una condición de carrera si el usuario inicia la aplicación varias veces a la vez. Pero para la mayoría de los casos, esta solución simple debería ser suficiente.

+0

No sé quién votó a favor y por qué. Pero esto es peligroso y no portátil. 'Qt' tiene soporte nativo para esta característica, por lo que es aconsejable usarlo. – ereOn

+0

Estoy de acuerdo en 'no portátil' y que QtSingleApplication es la mejor opción. Pero, ¿por qué peligroso? Debido a la condición de carrera? Un indicador O_CREATE abierto en el abierto() debería ocuparse de eso ... – bew

+0

Peligroso porque cualquier persona que crea este archivo a mano puede evitar que se ejecute su programa. – ereOn

23

Lo que estás buscando es QtSingleApplication.

Si inicia otra instancia de su aplicación, la primera incluso recibirá una notificación al respecto (puede pasar cualquier estructura de datos que desee).

Lo usé para llevar la aplicación existente al frente cada vez que se inicia otra instancia.

+0

Downvoted porque QtSingleApplication solo funciona en el proceso del usuario actual.No funcionará si otros usuarios comienzan el mismo proceso en otras sesiones de usuario. –

+5

@JimInTexas: sin ofender, pero el OP solo quería una forma de evitar que el mismo usuario inicie varios procesos de su propia aplicación. Para ese propósito, 'QtSingleApplication' es ** exactamente ** lo que necesitaba. Ahora quizás no encajará en ** su ** caso de uso particular, pero eso es irrelevante para la pregunta. Por lo general, las respuestas se rechazan porque están equivocadas, y en lo que respecta a esta pregunta, no es el caso. Lo es ? – ereOn

15

Use el siguiente código en main.cpp para evitar que se ejecute más de una instancia de su aplicación. Probé este código bajo Linux (en QtCreator) y funciona (también funciona para Windows). Encuentro esta solución simple y fácil de implementar. El ejemplo es para una aplicación de consola. El código sigue siendo el mismo para una aplicación GUI, verifique los comentarios en el código.

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

¿Cómo puedo abrir la ventana principal de la aplicación si la aplicación ya se inició? – devdev

+1

Si inicia su aplicación y es la única instancia, la ejecución alcanzará el ciclo de eventos Qt (app.exec) y su ventana principal se mostrará como normal. Si no se trata de la única instancia en ejecución, la nueva instancia alcanzará la salida() antes de mostrar la ventana principal. Su ventana existente permanecerá abierta. He agregado algunos comentarios más en mi ejemplo anterior. –

+3

Demasiado frágil, creo, si la aplicación falla, deja atrás el segmento sharedmem y no puede reiniciar el proceso. "Pero si el último subproceso o proceso se bloquea sin ejecutar el destructor QSharedMemory, el segmento de memoria compartida sobrevive al bloqueo". (QSharedMemory docs) –

3

Puede que esto no le preocupe, pero pensé que sería útil sacarlo. Estoy usando QtSingleApplication y experimenté un comportamiento extraño hace unos días. QtSingleApplication no parece funcionar en todas las circunstancias. Hice esta muestra en Windows, pero dependiendo de si este es un error específico de Windows o previsto por el diseño de QtSingleApplication, también se puede aplicar a Linux.

Dependiendo de la forma en que inicie su aplicación, son posibles varias instancias. Hice esta experiencia cuando hice una prueba de mi aplicación usando mi instalador. El instalador inicia automáticamente la aplicación después de terminar. Cuando comencé mi aplicación usando el enlace del escritorio, tuve dos instancias ejecutándose. Entonces la funcionalidad de QtSingleApplication parece depender de la forma en que (y por qué usuario?) Se inicia la aplicación. La documentación no está clara al respecto. Pero creo que generalmente uno esperaría que esto funcione en todas las circunstancias, si no se establece lo contrario.

Por lo tanto, si no necesita la funcionalidad adicional agregada por QtSingleApplication, QSystemSemaphore o QSharedMemory parece ser la mejor manera de hacerlo.

Cuestiones relacionadas