Qt单一实例进程
想让自己的程序只被启动一次,如果已经运行,则不再重复开启。看了网上很多资料,我这里主要记录其中两种:
1. QSystemSemaphore、QSharedMemory
尊重原创:实现QT单例程序 QSystemSemaphore QSharedMemory
代码稍作改动:
#include "mainwindow.h"
#include <QCoreApplication>
#include <QApplication>
#include <QSystemSemaphore>
#include <QSharedMemory>
#include <QMessageBox>
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
// 信号量的意义,把操作共享内存的代码锁住。因为有可能同时点击2次APP, 防止并发
QSystemSemaphore sema("SingleApp Key", 1, QSystemSemaphore::Open);
sema.acquire();
#ifdef Q_OS_LINUX
/* Windows平台上不存在应用程序崩溃后,共享内存段还存在的情况
* LINUX应用程序崩溃后,共享内存段不会自动销毁,则该程序再次运行会出问题
* 所以程序启动时先去检查是否有程序崩溃后还存留的共享内存段,如果有,先销毁,再创建
*/
QSharedMemory mem("SingleApp");
// 尝试将进程附加到共享内存段
if (mem.attach()) {
// 将共享内存与主进程分离, 如果此进程是附加到共享存储器段的最后一个进程,则系统释放共享存储器段,即销毁内容
mem.detach();
}
#endif
/*
* 每个App打开的时候,获取一次共享内存。
* 如果获取失败,说明是第一个启动的APP,直接创建共享内存就好了。
* 如果获取成功,说明不是第一个,直接退出就好了。
* 保证App在系统里只能打开一个。
*/
QSharedMemory unimem("SingleApp");
bool isRunning = false;
if (unimem.attach()) {
isRunning = true;
} else {
unimem.create(1);
isRunning = false;
}
sema.release();
if (isRunning) {
QMessageBox::warning(nullptr, "warning", "The app is running.");
exit(0);
}
MainWindow mainwindow;
mainwindow.show();
return app.exec();
}
2. QtSingleApplication
2.1.源码下载
QSingleApplication是Qt提供的一个solution,它不包含在Qt的library中。遵循LGPL协议。
下载链接:qtsingleapplication
2.2.添加依赖
依赖于QtNetwork模块(在使用的时候,记得添加QT + = network )
2.3.引入qtsingleapplication 源码
include ($$PWD/qtsingleapplication/src/qtsinglecoreapplication.pri)
2.4.使用
可以参考:
Qt实现应用单实例运行(3)-使用QTSingleApplication
QTSingleApplication的用法
没搞成功。。。所以就不写了,解决了再补上。
老是报错:
main.obj? error: LNK2019: 无法解析的外部符号 “public: __thiscall QtSingleApplication::QtSingleApplication(int &,char * *,bool)” (??0QtSingleApplication@@QAE@AAHPAPAD_N@Z),该符号在函数 _main 中被引用
main.obj? error: LNK2019: 无法解析的外部符号 “public: bool __thiscall QtSingleApplication::isRunning(void)” (?isRunning@QtSingleApplication@@QAE_NXZ),该符号在函数 _main 中被引用
值得mark的是,对于使用QGuiApplication的Qml应用是不能直接支持的。所以,需要修改qtsingleapplication的源代码。 见:Qt单一实例进程——使用qtsingleapplication