2010-11-03 233 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添加的额外功能似乎是更好的方法。

相关问题