简体   繁体   中英

How to restart QtSingleApplication?

I can restart my application with

QProcess::startDetached(QApplication::applicationFilePath());
exit(12);

But if I have QtSingleApplication new instance will not run. Is there way to trick QtSingleApplication to allow it to run new instance when isRunning() returns true maybe by some command line arguments or another aspects?

I'll be fully fine if I will add Sleep(5000); in the beginning but it doesn't look alike good design, I think I just need an additional mutex to detect if my application is gone :S what do you think?

One way to do such a thing is to use a little helper application (or script). The helper application is started detached and receives an identifier (ie PID) of the currently running program as a command line argument. It then waits until that identifier has disappeared from the process table, then restarts the application and exits.

This is a bit hacky/racy, but it works okay for me in practise. I use this in an update system, where I need to replace the running program with a new version of itself, which on Windows cannot be done while the program is running.

When you want to start your app as new running instance, pass a specific argument to signal it should close any existing rather the usual opposite.

This can be handled as

//code to send to instances
if(myturn)
{
    if (a.isRunning()) {
        QString rep("Another instance is running, so I will ask to leave.");
         bool sentok = a.sendMessage(message_gtfo,1000);

        if(!sentok)
           return "some error";
    }
}

//code to receive message from instance
connect(&a, SIGNAL(messageReceived(const QString&)),
                        &this, SLOT(handlMessage(const QString &))
                        );
...

void instancecomhandler::handlMessage(const QString & msg)
{
  if(msg == message_gtfo)
     //proceed to exit
}

edit:

You still need to pass the argument to modify the behavior. Default behavior quit when another instance is running. New behavior waits till the other instance terminate.

If you are restarting your application from inside itself, it is by definition no more a single-process application (since for a short time at least, two processes running the same application exist).

I would recommend using some shell tricks to restart it.

On Linux with a X11 desktop, you might eg popen(3) some at (or batch ) command which would restart your application. You'll probably need to explicitly set the DISPLAY environment variable.

On Linux or other POSIX systems, a possible way would be to wrap the application in a shell script (for example mywrapper ) like eg

 #! /bin/sh
 # script file mywrapper
 aftersource=$(tempfile -p app)
 myapp --aftersource $aftersource "$@"
 source $aftersource
 rm $aftersource

You'll need to improve the above script to handle failures and trap some signals... I guess you might adapt that script to Windows if so needed

Then your application would process the --aftersource argument to write some shell commands in it. If it want to restart itself it would eg write some command into that file to do that, etc.

Feel free to improve the script (trapping some signals and exit, looping, etc...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM