【问题标题】:How to force my application to open one exe only? qt, linux如何强制我的应用程序只打开一个 exe? qt, linux
【发布时间】:2011-05-04 11:41:46
【问题描述】:

我希望我的应用程序只打开一个进程,即如果一个进程已经打开并且用户想要再次打开 exe - 它不会打开另一个进程。

如何在 Qt - linux 中做到这一点?

10 倍!

【问题讨论】:

  • 你真的应该接受你的问题的答案,除非你不想让别人再回答了。

标签: c++ linux qt process mutex


【解决方案1】:

您的应用程序可以检查用户主目录中的某个文件是否存在。如果存在,则应用程序退出。如果它不存在,应用程序将创建它并继续。当然,如果用户一次启动应用程序多次,您可能会遇到竞争条件。但在大多数情况下,这个简单的解决方案就足够了。

【讨论】:

  • 我不知道谁赞成这个,为什么。但这是危险且不可移植的。 Qt 对这个特性有原生支持,所以使用它是明智的。
  • 我同意“非便携式”并且 QtSingleApplication 是更好的选择。但为什么危险?因为比赛条件? open() 中的 open O_CREATE 标志应该处理这个问题..
  • 危险,因为任何手动创建此文件的人都可能阻止您的程序运行。
  • 如果我正确阅读了 QtSingleApplication /QtLocalPeer 的源代码,Qt 会做几乎与我建议相同的事情。 Qt 在 /tmp 中创建一个锁定文件,用户 ID 编码在文件名中。使用 QtSingleApplication 您的攻击应该更简单,因为所有用户都可以在 /tmp 中创建文件。
【解决方案2】:

你要找的是QtSingleApplication

如果您启动应用程序的另一个实例,第一个实例甚至会收到通知(您可以传递任何您想要的数据结构)。

每当启动另一个实例时,我都会使用它来将现有应用程序置于最前面。

【讨论】:

  • 投反对票,因为 QtSingleApplication 仅适用于当前用户的进程。如果其他用户在其他用户会话中启动相同的进程,它将不起作用。
  • @JimInTexas:无意冒犯,但 OP 只是想要一种方法来防止同一用户启动他自己的应用程序的多个进程。为此,QtSingleApplication 正是他所需要的。现在也许它不适合 您的 特定用例,但这与问题无关。通常,答案会因为错误而被否决,而就这个问题而言,情况并非如此。是吗?
【解决方案3】:

在 main.cpp 中使用以下代码来防止运行多个应用程序实例。我在 Linux 下(在 QtCreator 中)测试了这段代码,它可以工作(也适用于 Windows)。我发现这个解决方案简单易行。该示例适用于控制台应用程序。 GUI 应用程序的代码保持不变,请检查代码中的 cmets。

//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();
}

【讨论】:

  • 如果应用程序已经启动,如何打开应用程序的主窗口?
  • 如果您启动应用程序并且它是唯一的实例,则执行将到达 Qt 事件循环 (app.exec) 并且您的主窗口将正常显示。如果它不是唯一运行的实例,则新实例将在显示主窗口之前到达 exit()。您现有的窗口将保持打开状态。我在上面的示例中添加了更多的 cmets。
  • 我认为太脆弱了 - 如果应用程序崩溃,它会留下 sharedmem 段,您无法重新启动进程。 “但如果最后一个线程或进程在没有运行 QSharedMemory 析构函数的情况下崩溃,则共享内存段会在崩溃中幸存下来。” (QSharedMemory 文档)
【解决方案4】:

这可能与您无关,但我认为提出它会很有用。我自己在使用QtSingleApplication,几天前经历了一些奇怪的行为。 QtSingleApplication 似乎并非在所有情况下都有效。我在 windows 中进行了这种体验,但根据这是 windows 特定的错误还是 QtSingleApplication 的设计意图,它也可能适用于 linux。

根据您启动应用程序的方式,可能有多个实例。当我使用我的安装程序测试我的应用程序时,我获得了这种体验。安装程序在完成后自动启动应用程序。然后当我使用桌面链接启动我的应用程序时,我运行了两个实例。所以QtSingleApplication 的功能似乎取决于应用程序的启动方式(以及由哪个用户启动?)。文档对此尚不清楚。但我认为通常人们会期望这在所有情况下都有效,除非另有说明。

因此,如果您不需要 QtSingleApplicationQSystemSemaphoreQSharedMemory 添加的额外功能,似乎是更好的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 2022-01-12
    • 2018-10-19
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    相关资源
    最近更新 更多