2010-11-03 26 views

回答

0

您的應用程序可以檢查用戶主目錄中的某個文件是否存在。如果它存在,則應用程序退出。如果它不存在,應用程序將創建它並繼續。當然,如果用戶一次啓動應用程序多次,您可能會遇到競爭狀況。但是對於大多數情況下這個簡單的解決方案應該足夠了

+0

我不知道是誰投了票,爲什麼。但這是危險的和不可移植的。 'Qt'對這個特性有本地支持,所以使用它是明智的。 – ereOn 2010-11-03 13:10:41

+0

我同意'不可移植',並且QtSingleApplication是更好的選擇。但爲什麼危險?由於競爭條件? open()中的開放O_CREATE標誌應該處理該問題.. – bew 2010-11-03 13:23:03

+0

危險的是因爲任何人手動創建此文件都可能會阻止您的程序運行。 – ereOn 2010-11-03 14:10:51

23

您要找的是QtSingleApplication

如果你啓動另一個應用程序實例,第一個實例甚至會收到有關它的通知(你可以傳遞你想要的任何數據結構)。

無論何時啓動另一個實例,我都會使用它將現有應用程序置於前端。

+0

因爲QtSingleApplication只適用於當前用戶的進程而被低估。如果其他用戶在其他用戶會話中啓動相同的進程,它將不起作用。 – 2011-12-14 00:33:34

+5

@JimInTexas:沒有冒犯,但OP只是想阻止同一用戶啓動他自己的應用程序的幾個進程。爲此目的'QtSingleApplication'完全**是他所需要的。現在也許它不適合**你的**特殊用例,但這與問題無關。通常情況下,答案因爲錯誤而被低估,就這個問題而言,情況並非如此。是嗎 ? – ereOn 2011-12-14 00:53:23

15

在main.cpp中使用以下代碼可防止運行多個應用程序實例。我在Linux下測試了這個代碼(在QtCreator中),它的工作原理(也適用於Windows)。我發現這個解決方案簡單易用。該示例適用於控制檯應用程序。該代碼對於GUI應用程序保持不變,請檢查代碼中的註釋。

//main.cpp 
#include <QCoreApplication> //Console application 
//#include <QApplication>  //GUI application 
#include <QSharedMemory> 
#include <QDebug> 
//Your QMainWindow derivated class goes here : 
//#include "MainWindow.h" 

int main(int argc, char *argv[]) 
{ 

    QCoreApplication app(argc, argv); 

    app.processEvents(); 

    //---- Check for another instance code snippet ---- 

    //GUID : Generated once for your application 
    // you could get one GUID here: http://www.guidgenerator.com/online-guid-generator.aspx 
    QSharedMemory shared("62d60669-bb94-4a94-88bb-b964890a7e04"); 

    if(!shared.create(512, QSharedMemory::ReadWrite)) 
    { 
    // For a GUI application, replace this by : 
    // QMessageBox msgBox; 
    //msgBox.setText(QObject::tr("Can't start more than one instance of the application.")); 
    //msgBox.setIcon(QMessageBox::Critical); 
    //msgBox.exec(); 

    qWarning() << "Can't start more than one instance of the application."; 

    exit(0); 
    } 
    else { 
     qDebug() << "Application started successfully."; 
    } 
    //---- END OF Check for another instance code snippet ---- 

    // Only one instance is running, declare MainWindow 
    //MainWindow myMainWindow; 
    //myMainWindow.show(); 


    //We enter the Qt Event loop here, we don't leave until the MainWindow is closed 
    //or the console application is terminated. 
    return app.exec(); 
} 
+0

如果應用程序已經啓動,如何打開應用程序的主窗口? – devdev 2010-11-07 10:55:48

+1

如果你開始你的應用程序並且它是唯一的實例,那麼執行將會到達Qt事件循環(app.exec),你的主窗口將會正常顯示。如果它不是唯一一個正在運行的實例,則新實例將在顯示主窗口之前到達exit()。您現有的窗口將保持打開狀態。我在上面的示例中添加了更多評論。 – 2010-11-07 14:41:28

+3

我認爲太脆弱了 - 如果應用程序崩潰,它會將sharedmem段留在後面,並且無法重新啓動進程。 「但是如果最後一個線程或進程崩潰而沒有運行QSharedMemory析構函數,那麼共享內存段會在崩潰中倖存下來。」 (QSharedMemory文檔) – 2011-12-14 06:48:28

3

這可能不關你,但我認爲這將是有用的提出來。我自己使用QtSingleApplication,並在幾天前經歷了一些奇怪的行爲。 QtSingleApplication似乎在任何情況下都不起作用。我在Windows下創建了這個文件,但根據這個窗口的具體錯誤或者設計QtSingleApplication,它可能也適用於linux。

根據您啓動應用程序的方式,可能有多個實例。當我使用我的安裝程序對我的應用程序進行測試驅動時,我做出了這樣的體驗。安裝程序在完成後自動啓動應用程序。當我使用桌面鏈接開始我的應用程序時,我有兩個實例正在運行。所以QtSingleApplication的功能似乎取決於如何(以及由哪個用戶?)應用程序啓動的方式。有關這方面的文件不清楚。但我認爲,如果沒有另行說明,通常人們會認爲這在任何情況下都可行。

因此,如果您不需要通過QtSingleApplicationQSystemSemaphoreQSharedMemory添加的額外功能似乎是更好的方法。

相關問題