[英]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
請點擊
testQProcessChild started.
Sleeping for three seconds...
./testQProcessChild started.
testQProcessDetached exiting.
$ testQProcessChild exits.
我使用Qt for Windows在VS2013上編譯了第二個示例。 它也很好。
因此,我不得不用絕對路徑替換相對路徑./testQProcessChild
(盡管兩個二進制文件都位於同一目錄中)。 正如OP所說的那樣,我對此並不在意。
一種快速而骯臟的解決方案是在Windows命令腳本中運行安裝程序可執行文件,然后QProcess命令腳本。 然后在腳本開始處放置3-5秒的“超時”命令,以確保原始可執行文件已完成。
事實證明,我發布的方法確實有效,但是如果您在調試器中運行應用程序,則該方法將無效。 顯然,為了安全起見,調試器會在應用終止時關閉所有產生的線程/進程。 謝謝大家的答案!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.