diff options
author | Arttu Tarkiainen <arttu.tarkiainen@qt.io> | 2022-08-18 12:51:36 +0300 |
---|---|---|
committer | Arttu Tarkiainen <arttu.tarkiainen@qt.io> | 2022-09-07 14:09:46 +0300 |
commit | 86c68384cbf197dae3c6583c7b752eb21c75e34c (patch) | |
tree | 416a6ab40627a192631fe004a50f1d3261ad65e4 /src/sdk | |
parent | 1b702ac2801de72c67224c42e6456db235ee6b8c (diff) |
Replace .vbs hack to update maintenance tool binary on Windows
Do the replacing of the executable instead by:
- The original MT renames itself to a temporary name
- The new MT is renamed to the destination file name
- The new MT is started as a detached process, it polls to delete the
temporary MT (requires that the parent process exited)
Introduce hidden options, cleanup-update and cleanup-update-only to
start the maintenance tool in a mode for deleting the old binary.
Also fix missing verbose messages on hard restart of maintenance tool
after update. Due to QProcessWrapper::startDetached using a modified
implementation of the wrapped class (QProcess) method, the detached
process was started with a new console instead of inheriting the
console of the parent process. Fix by adding a second variant of the
QProcessWrapper::startDetached functions using the QProcess
implementation.
Task-number: QTIFW-2625
Change-Id: Iebc5b04befa1e79765217f93723f977556e03d90
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src/sdk')
-rw-r--r-- | src/sdk/main.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/sdk/main.cpp b/src/sdk/main.cpp index a1e330299..4ab9348c8 100644 --- a/src/sdk/main.cpp +++ b/src/sdk/main.cpp @@ -48,6 +48,8 @@ #include <QCommandLineParser> #include <QDateTime> #include <QNetworkProxyFactory> +#include <QThread> +#include <QDeadlineTimer> #include <iostream> @@ -63,6 +65,44 @@ #define SHA "Installer Framework SHA1: " QUOTE(_GIT_SHA1_) static const char PLACEHOLDER[32] = "MY_InstallerCreateDateTime_MY"; +#ifdef Q_OS_WIN +static void cleanupUpdate(const CommandLineParser &parser, bool *exit) +{ + QString cleanupPath; + QString cleanupOption; + *exit = false; + + if (parser.isSet(CommandLineOptions::scCleanupUpdate)) { + cleanupPath = parser.value(CommandLineOptions::scCleanupUpdate); + cleanupOption = CommandLineOptions::scCleanupUpdate; + } else if (parser.isSet(CommandLineOptions::scCleanupUpdateOnly)) { + cleanupPath = parser.value(CommandLineOptions::scCleanupUpdateOnly); + cleanupOption = CommandLineOptions::scCleanupUpdateOnly; + *exit = true; + } + + if (cleanupOption.isEmpty()) + return; + + // Since Windows does not support that the maintenance tool deletes itself we + // remove the old executable here after update (as the new maintenance tool). + if (!cleanupPath.isEmpty()) { + QFile fileToRemove(cleanupPath); + // Give up after 120 seconds if the old process has not exited and released the file + QDeadlineTimer deadline(120000); + while (fileToRemove.exists() && !deadline.hasExpired()) { + if (fileToRemove.remove()) { + std::cout << "Removed leftover file: " << qPrintable(cleanupPath) + << " after update." << std::endl; + } + QThread::msleep(1000); + } + } else { + std::cout << "Invalid value for option " << qPrintable(cleanupOption); + } +} +#endif + int main(int argc, char *argv[]) { if (!qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") @@ -159,6 +199,15 @@ int main(int argc, char *argv[]) return help ? EXIT_SUCCESS : EXIT_FAILURE; } +#ifdef Q_OS_WIN + { + bool exit = false; + cleanupUpdate(parser, &exit); + if (exit) + return EXIT_SUCCESS; + } +#endif + if (parser.isSet(CommandLineOptions::scStartServerLong)) { const QStringList arguments = parser.value(CommandLineOptions::scStartServerLong) .split(QLatin1Char(','), Qt::SkipEmptyParts); |