C++ QProcess,它将比父进程更适合更新

C++ QProcess,它将比父进程更适合更新,c++,qt,qprocess,C++,Qt,Qprocess,有好几篇关于这个的帖子,但我没有经历过同样的事情。我正在Windows下运行QT,并试图启动一个将覆盖我的应用程序的安装程序。我已经能够在C#中做到这一点,但作为QT的新手,我还没有找到让启动过程比应用程序更持久的“秘密酱汁” 我尝试过更新流程,因为有人提到,如果他们这么做了,并且没有删除QProcess,那么在launcher应用程序消失后,QProcess仍然存在。我尝试过这个,但一旦我的应用程序退出,一切都会消失,尽管内存泄漏。我无法让应用程序继续运行,因为与Linux不同,Windows

有好几篇关于这个的帖子,但我没有经历过同样的事情。我正在Windows下运行QT,并试图启动一个将覆盖我的应用程序的安装程序。我已经能够在C#中做到这一点,但作为QT的新手,我还没有找到让启动过程比应用程序更持久的“秘密酱汁”

我尝试过更新流程,因为有人提到,如果他们这么做了,并且没有删除QProcess,那么在launcher应用程序消失后,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所描述的一样

这是我要展示的

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;
}
#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;
}
2) Qt应用程序
testQProcessDetached.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;
}
#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;
}
编译和测试:

$qmake-qt5 testqprocess.pro
$make
$./testqprocess
testQProcessChild已启动。
睡三秒钟。。。
./testQProcessChild已启动。
TestQProcess正在退出。
$testQProcessChild退出。
请注意,
testQProcessDetached
退出,提示
$
再次出现。大约3秒钟后,输出
testQProcessChild退出。
出现(以证明
testQProcessChild
testQProcessChild
更长寿)

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

我已经在Windows10上进行了测试


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

点击

testQProcessChild已启动。
睡三秒钟。。。
./testQProcessChild已启动。
TestQProcess正在退出。
$testQProcessChild退出。

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


因此,我不得不将相对路径
/testQProcessChild
替换为绝对路径(尽管两个二进制文件位于同一目录中)。正如OP所述,我并不关心这一点。

实际上,它的工作原理与OP所描述的一样

这是我要展示的

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;
}
#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;
}
2) Qt应用程序
testQProcessDetached.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;
}
#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;
}
编译和测试:

$qmake-qt5 testqprocess.pro
$make
$./testqprocess
testQProcessChild已启动。
睡三秒钟。。。
./testQProcessChild已启动。
TestQProcess正在退出。
$testQProcessChild退出。
请注意,
testQProcessDetached
退出,提示
$
再次出现。大约3秒钟后,输出
testQProcessChild退出。
出现(以证明
testQProcessChild
testQProcessChild
更长寿)

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

我已经在Windows10上进行了测试


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

点击

testQProcessChild已启动。
睡三秒钟。。。
./testQProcessChild已启动。
TestQProcess正在退出。
$testQProcessChild退出。

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


因此,我不得不将相对路径
/testQProcessChild
替换为绝对路径(尽管两个二进制文件位于同一目录中)。正如OP所说的那样,我并不关心这一点。

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

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

结果表明,我发布的方法确实有效,但如果在调试器中运行应用程序,它将不起作用。显然,作为安全预防措施,当应用程序终止时,调试器会关闭所有生成的线程/进程。谢谢大家的回答

事实证明,我发布的方法确实有效,但如果在调试器中运行应用程序,它将不起作用。显然,作为安全预防措施,当应用程序终止时,调试器会关闭所有生成的线程/进程。谢谢大家的回答

您确定找到了“full/path/to/installer.exe”吗?您确定找到了“full/path/to/installer.exe”吗?