簡體   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