12

I want my application to open only one process, i.e. if the one process is already opened and the user want to open the exe again - it won't open another process.

how can I do it in Qt - linux?

10x!

devdev
  • 211
  • 2
  • 9
  • 3
    You really should accept answers to your questions unless you don't want people to answer anymore. – ereOn Nov 06 '10 at 15:57

4 Answers4

23

What you're looking for is QtSingleApplication.

If you start another instance of your application, the first one will even get notified about it (you can pass whatever data structure you want).

I used it to bring the existing application to the front whenever another instance is started.

ereOn
  • 53,676
  • 39
  • 161
  • 238
  • Downvoted because QtSingleApplication only works in the current user's process. It will not work if other users start the same process in other user sessions. – Jim In Texas Dec 14 '11 at 00:33
  • 5
    @JimInTexas: No offense, but the OP just wanted a way to prevent the same user from starting several processes of his own application. For that purpose `QtSingleApplication` is **exactly** what he needed. Now perhaps it won't fit in **your** particular use case, but that's irrelevant to the question. Usually, answers get downvoted because they are wrong, and as far as this question is concerned, it is not the case. Is it ? – ereOn Dec 14 '11 at 00:53
15

Use the following code in the main.cpp to prevent to run more than one instance of your application. I tested this code under Linux (in QtCreator) and it works (works for Windows too). I find this solution simple and easy to implement. The example is for a console application. The code remain the same for a GUI application, check the comments in the 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();
}
Symbiosoft
  • 4,681
  • 6
  • 32
  • 46
  • How can I open the main window of the application if the application already started? – devdev Nov 07 '10 at 10:55
  • 1
    If your start your application and it is the only instance, the execution will reach the Qt event loop (app.exec) and your main window will be shown as normal. If it is not the only one instance running, the new instance will reach the exit() before showing the main window. Your existing window will remain open. I have added some more comments in my example above. – Symbiosoft Nov 07 '10 at 14:41
  • 3
    Too fragile I think - if the application crashes, it leaves the sharedmem segment behind and you cannot restart the process. "But if that last thread or process crashes without running the QSharedMemory destructor, the shared memory segment survives the crash." (QSharedMemory docs) – Frank Osterfeld Dec 14 '11 at 06:48
3

This may not concern you, but I thought it would be useful to bring it up. I'm using QtSingleApplication myself and experienced some odd behavior a few days ago. QtSingleApplication doesn't seem to work under all circumstances. I made this expierence in windows, but depending on wether this is a windows specific bug or intended by the design of QtSingleApplication, it may also apply to linux.

Depending on the way you start your application multiple instances are possible. I made this experience when I did a testdrive of my application using my installer. The installer automatically starts the application after finishing. When I then started my application using the desktop link, I had two instances running. So the functionality of QtSingleApplication seems to depend on the way how (and by which user?) the application is started. The documentation is unclear about this. But I think usually one would expect this to work under all circumstances, if not stated otherwise.

So, if you don't need the extra functionality added by QtSingleApplication, QSystemSemaphore or QSharedMemory seems to be the better way to go.

bjoern.bauer
  • 699
  • 3
  • 6
0

Your application could check if a certain file in the user's home directory is present. If it is present, the application exits. If it is not there, the application creates it and continues. Of course, you might get a race condition if the user starts the application several times at once. But for most cases this simple solution should be sufficient.

bew
  • 631
  • 3
  • 4
  • I don't know who upvoted this, and why. But this is dangerous and non-portable. `Qt` has native support for this feature, so it is wise to use it. – ereOn Nov 03 '10 at 13:10
  • I agree on 'non-portable' and that QtSingleApplication is the better option. But why dangerous? Because of the race condition? An open O_CREATE flag in the open() should deal with that.. – bew Nov 03 '10 at 13:23
  • Dangerous because anyone that creates this file by hand can prevent your program from running. – ereOn Nov 03 '10 at 14:10
  • 1
    If I read the source of QtSingleApplication /QtLocalPeer correctly, Qt does almost the same thing I've proposed. Qt creates a lock file in /tmp, with the user id encoded in the file name. Your attack should be even simpler with QtSingleApplication, as all users can create files in /tmp. – bew Nov 03 '10 at 14:52