Было несколько сообщений об этом, но я не испытал того же. Я запускаю QT под Windows и пытаюсь запустить установщик, который перезапишет мое приложение. Мне удалось сделать это на 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()
и повторил тест - с тем же результатом, что и раньше.
Я тестировал cygwin64 в Windows 10.
Образец testQProcessDetached.cc
, измененный, чтобы стать приложением с графическим интерфейсом пользователя:
#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
Click
testQProcessChild started.
Sleeping for three seconds...
./testQProcessChild started.
testQProcessDetached exiting.
$ testQProcessChild exits.
Второй пример я скомпилировал на VS2013 с Qt для Windows. Это тоже сработало.
Таким образом, мне пришлось заменить относительный путь ./testQProcessChild
на абсолютный путь (хотя оба двоичных файла находились в одном каталоге). Поскольку об этом также заявляет OP, меня это не заботило.
Быстрое и грязное решение - запустить исполняемый файл установщика внутри командного сценария Windows и обработать командный сценарий QProcess. Затем введите команду «тайм-аут» 3-5 секунд в начале сценария, чтобы убедиться, что исходный исполняемый файл завершен.
Оказывается, метод, который я опубликовал, работает, но он не будет работать, если вы запустите свое приложение в отладчике. По-видимому, в качестве меры предосторожности отладчик закрывает все порожденные потоки / процессы при завершении работы приложения. Всем спасибо за ответы !!
Вы уверены, что "полный / путь / к / installer.exe" найден?