繁体   English   中英

QProcess将超过父进程进行更新

[英]QProcess that will outlive the parent for updating

关于此有好几篇文章,但我没有经历过。 我正在Windows下运行QT,并尝试启动将覆盖我的应用程序的安装程序。 我已经可以使用C#来做到这一点,但是对于QT来说,我还是找不到能够使启动过程比应用程序寿命更长的“秘密调味料”。

我尝试过更新该过程,因为有人提到如果他们这样做并且不删除QProcess,那么启动器应用程序消失后它就可以继续使用。 我试过了,但是一旦我的应用退出,一切都会消失,尽管有内存泄漏。 我无法继续运行该应用程序,因为与Linux不同,Windows不允许您在运行时覆盖该应用程序。 有谁知道如何做到这一点?
我需要做的非常简单:

QString filename = ""full/path/to/installer.exe";

QProcess * pProcess = new QProcess();

int result = pProcess->startDetached(filename);

if (result)
  QCoreApplication::quit();
else
  QMessageBox::warning(this,tr("Oh NO!!"),tr("Couldn't start the installer!!!"),QMessageBox::Ok);

实际上,它按OP所述工作。

这是我的MCVE演示。

1)子应用程序testQProcessChild.cc

#include <chrono>
#include <thread>
#include <iostream>

int main()
{
  std::cout << "testQProcessChild started.\n"
    << "Sleeping for three seconds...\n";
  std::this_thread::sleep_for(std::chrono::seconds(3));
  std::cout << "testQProcessChild exits.\n";
  return 0;
}

编译和测试:

$ g++ -std=c++11 -o testQProcessChild testQProcessChild.cc 

$ ./testQProcessChild 
testQProcessChild started.
Sleeping for three seconds...
testQProcessChild exits.

$

2)Qt应用程序testQProcessDetached.cc

#include <QtWidgets>

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QProcess qProcess;
  //qProcess.closeWriteChannel();
  //qProcess.closeReadChannel(QProcess::StandardOutput);
  //qProcess.closeReadChannel(QProcess::StandardError);
  if (qProcess.startDetached(QString::fromLatin1("./testQProcessChild"))) {
    qDebug() << "./testQProcessChild started.";
  } else {
    qDebug() << "Cannot start ./testQProcessChild!";
  }
  qDebug() << "testQProcessDetached exiting.";
  return 0;
}

与项目文件testQProcessDetached.pro

SOURCES = testQProcessDetached.cc

QT = widgets

编译和测试:

$ qmake-qt5 testQProcessDetached.pro

$ make

$ ./testQProcessDetached
testQProcessChild started.
Sleeping for three seconds...
./testQProcessChild started.
testQProcessDetached exiting.

$ testQProcessChild exits.

请注意, testQProcessDetached退出可以再次显示为提示$ 大约3秒钟后,输出testQProcessChild exits. 出现(以证明testQProcessChild超过testQProcessDetached )。

我怀疑通道连接可能是个问题。 因此,在第一次成功尝试之后,我注释了close???Channel()调用并重复了测试-结果与以前相同。

我已经在Windows 10上的cygwin64中进行了测试。


将示例testQProcessDetached.cc修改为一个GUI应用程序:

#include <QtWidgets>

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QPushButton qBtn(QString::fromUtf8("Start Child"));
  qBtn.show();
  QObject::connect(&qBtn, &QPushButton::clicked,
    [&](bool) {
      QProcess qProcess;
      //qProcess.closeWriteChannel();
      //qProcess.closeReadChannel(QProcess::StandardOutput);
      //qProcess.closeReadChannel(QProcess::StandardError);
      if (qProcess.startDetached(QString::fromLatin1("./testQProcessChild"))) {
        qDebug() << "./testQProcessChild started.";
        QApplication::quit();
      } else {
        qDebug() << "Cannot start ./testQProcessChild!";
      }
    });
  return app.exec();
}

编译和测试:

$ qmake-qt5 testQProcessDetached.pro

$ make

$ ./testQProcessDetached

testQProcessDetached的快照

请点击

testQProcessChild started.
Sleeping for three seconds...
./testQProcessChild started.
testQProcessDetached exiting.

$ testQProcessChild exits.

我使用Qt for Windows在VS2013上编译了第二个示例。 它也很好。

testQProcessDetached快照(与VS2013一起编译)

因此,我不得不用绝对路径替换相对路径./testQProcessChild (尽管两个二进制文件都位于同一目录中)。 正如OP所说的那样,我对此并不在意。

一种快速而肮脏的解决方案是在Windows命令脚本中运行安装程序可执行文件,然后QProcess命令脚本。 然后在脚本开始处放置3-5秒的“超时”命令,以确保原始可执行文件已完成。

事实证明,我发布的方法确实有效,但是如果您在调试器中运行应用程序,则该方法将无效。 显然,为了安全起见,调试器会在应用终止时关闭所有产生的线程/进程。 谢谢大家的答案!!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM