Qt单一实例进程

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

发布了32 篇原创文章 · 获赞 4 · 访问量 3428

猜你喜欢

转载自blog.csdn.net/qq_35241071/article/details/100576077
今日推荐