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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章