如何重启QtSingleApplication?
How to restart QtSingleApplication?
我可以用
重新启动我的应用程序
QProcess::startDetached(QApplication::applicationFilePath());
exit(12);
但如果我有 QtSingleApplication
个新实例,则不会 运行。有没有办法在 isRunning()
returns true
时通过某些命令行参数或其他方面来欺骗 QtSingleApplication
以允许它 运行 新实例?
如果我在开头添加 Sleep(5000);
我会完全没问题,但它看起来不像好的设计,我想我只需要一个额外的互斥锁来检测我的应用程序是否消失了:S你怎么看?
如果您从内部重新启动应用程序,根据定义,它不再是单进程应用程序(因为至少在短时间内,存在两个进程 运行 同一个应用程序)。
我建议使用一些 shell 技巧来重新启动它。
在使用 X11 桌面的 Linux 上,您可能例如popen(3) some at(或batch
)命令将重新启动您的应用程序。您可能需要明确设置 DISPLAY
环境变量。
在 Linux 或其他 POSIX 系统上,一种可能的方法是将应用程序包装在 shell 脚本(例如 mywrapper
)中,例如
#! /bin/sh
# script file mywrapper
aftersource=$(tempfile -p app)
myapp --aftersource $aftersource "$@"
source $aftersource
rm $aftersource
您需要改进上述脚本以处理故障和 trap
一些信号...我想如果需要的话您可能会将该脚本调整为 Windows
然后您的应用程序将处理 --aftersource
参数以在其中写入一些 shell 命令。如果它想自行重启,例如将一些命令写入该文件以执行该操作等
随时改进脚本(捕获一些信号并退出、循环等...)
做这样的事情的一种方法是使用一个小的辅助应用程序(或脚本)。助手应用程序以分离方式启动,并接收当前 运行 程序的标识符(即 PID)作为命令行参数。然后等待该标识符从进程中消失 table,然后重新启动应用程序并退出。
这有点hacky/racy,但在实践中对我来说没问题。我在更新系统中使用它,我需要用它自己的新版本替换 运行 程序,这在 Windows 上无法完成,而程序是 运行.
当您想将您的应用程序作为新的 运行 实例启动时,传递一个特定的参数以指示它应该关闭任何现有的而不是通常相反的方式。
这可以处理为
//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
}
编辑:
您仍然需要传递参数来修改行为。当另一个实例为 运行 时,默认行为退出。新行为会一直等到另一个实例终止。
我可以用
重新启动我的应用程序QProcess::startDetached(QApplication::applicationFilePath());
exit(12);
但如果我有 QtSingleApplication
个新实例,则不会 运行。有没有办法在 isRunning()
returns true
时通过某些命令行参数或其他方面来欺骗 QtSingleApplication
以允许它 运行 新实例?
如果我在开头添加 Sleep(5000);
我会完全没问题,但它看起来不像好的设计,我想我只需要一个额外的互斥锁来检测我的应用程序是否消失了:S你怎么看?
如果您从内部重新启动应用程序,根据定义,它不再是单进程应用程序(因为至少在短时间内,存在两个进程 运行 同一个应用程序)。
我建议使用一些 shell 技巧来重新启动它。
在使用 X11 桌面的 Linux 上,您可能例如popen(3) some at(或batch
)命令将重新启动您的应用程序。您可能需要明确设置 DISPLAY
环境变量。
在 Linux 或其他 POSIX 系统上,一种可能的方法是将应用程序包装在 shell 脚本(例如 mywrapper
)中,例如
#! /bin/sh
# script file mywrapper
aftersource=$(tempfile -p app)
myapp --aftersource $aftersource "$@"
source $aftersource
rm $aftersource
您需要改进上述脚本以处理故障和 trap
一些信号...我想如果需要的话您可能会将该脚本调整为 Windows
然后您的应用程序将处理 --aftersource
参数以在其中写入一些 shell 命令。如果它想自行重启,例如将一些命令写入该文件以执行该操作等
随时改进脚本(捕获一些信号并退出、循环等...)
做这样的事情的一种方法是使用一个小的辅助应用程序(或脚本)。助手应用程序以分离方式启动,并接收当前 运行 程序的标识符(即 PID)作为命令行参数。然后等待该标识符从进程中消失 table,然后重新启动应用程序并退出。
这有点hacky/racy,但在实践中对我来说没问题。我在更新系统中使用它,我需要用它自己的新版本替换 运行 程序,这在 Windows 上无法完成,而程序是 运行.
当您想将您的应用程序作为新的 运行 实例启动时,传递一个特定的参数以指示它应该关闭任何现有的而不是通常相反的方式。
这可以处理为
//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
}
编辑:
您仍然需要传递参数来修改行为。当另一个实例为 运行 时,默认行为退出。新行为会一直等到另一个实例终止。