1 #include "runinstaller.h"
2
3 #include <QDesktopServices>
4
5 #include "defaultupdater.h"
6
7 namespace updater {
8
RunInstaller()9 RunInstaller::RunInstaller() : Installer() {}
10
start(const QString & filename)11 void RunInstaller::start(const QString &filename) {
12 auto processedArguments = arguments;
13 processedArguments << autoRestartArguments;
14
15 if (command.isEmpty()) {
16 command = filename;
17 } else {
18 // replace markers
19 for (auto &arg : processedArguments)
20 arg.replace("%filename%", filename);
21 #ifdef Q_OS_LINUX
22 if (runAsAdmin) {
23 processedArguments.prepend(command);
24 command = "pkexec";
25 }
26 #endif
27 }
28
29 QProcess *process = new QProcess();
30 QObject::connect(process, &QProcess::errorOccurred, this, [this](auto error) {
31 this->emit error("Update error: " + QVariant::fromValue(error).toString());
32 });
33
34 if (autoRestart && updater->getRelaunchAfterInstall()) {
35 auto thread = new QThread;
36 process->moveToThread(thread);
37 connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this,
38 [this](int exitCode, QProcess::ExitStatus exitStatus) {
39 qDebug() << "finished" << exitCode << exitStatus;
40 if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
41 qDebug() << "Restarting" << qApp->applicationFilePath();
42 QProcess *restartProcess = new QProcess(this);
43 restartProcess->startDetached(qApp->applicationFilePath(), {});
44 }
45 });
46 qDebug() << "Executing" << command << processedArguments;
47 process->start(command, processedArguments);
48 process->waitForFinished(60000);
49 } else {
50 qDebug() << "Forking" << command << processedArguments;
51 if (!process->startDetached(command, processedArguments)) {
52 qWarning() << "Cannot execute" << command << processedArguments
53 << process->errorString();
54 // Fallback to opening the downloaded payload
55 QDesktopServices::openUrl(QUrl("file:///" + filename));
56 }
57 }
58 }
59
60 } // namespace updater
61