From abc4021919f406ee25e101122144879f8770d51d Mon Sep 17 00:00:00 2001 From: Victor Tran Date: Fri, 13 Jul 2018 00:39:24 +1000 Subject: Uninstall support --- installer/process/installworker.cpp | 48 +++++++++++++++++++++++- installer/process/installworker.h | 5 +++ installer/process/removeworker.cpp | 75 +++++++++++++++++++++++++++++++++++++ installer/process/removeworker.h | 26 +++++++++++++ 4 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 installer/process/removeworker.cpp create mode 100644 installer/process/removeworker.h (limited to 'installer/process') diff --git a/installer/process/installworker.cpp b/installer/process/installworker.cpp index 48c7c10..5b44ad1 100644 --- a/installer/process/installworker.cpp +++ b/installer/process/installworker.cpp @@ -6,7 +6,7 @@ InstallWorker::InstallWorker(QObject *parent) : QObject(parent) bool InstallWorker::startWork() { QLocalSocket* sock = new QLocalSocket(); - QString vendor, name, url, destPath; + QString vendor, name, url, destPath, executable; bool isStableStream = true, isGlobalInstall = true; QString previousToken; @@ -22,10 +22,12 @@ bool InstallWorker::startWork() { url = arg; } else if (previousToken == "--destdir") { destPath = arg; + } else if (previousToken == "--executable") { + executable = arg; } previousToken = ""; } else { - if (arg == "--socket" || arg == "--vendor" || arg == "--name" || arg == "--url" || arg == "--destdir") { + if (arg == "--socket" || arg == "--vendor" || arg == "--name" || arg == "--url" || arg == "--destdir" || arg == "--executable") { previousToken = arg; } else if (arg == "--blueprint") { isStableStream = false; @@ -66,9 +68,51 @@ bool InstallWorker::startWork() { req.setHeader(QNetworkRequest::UserAgentHeader, "theInstaller/1.0"); QNetworkReply* reply = mgr.get(req); connect(reply, &QNetworkReply::finished, [=] { + packageFile.flush(); + packageFile.seek(0); + sock->write(QString("STATUS ").append(tr("Unpacking %1...").arg(name)).append("\n").toUtf8()); sock->write("PROGRESS 0 0\n"); sock->write(QString("DEBUG %1").arg(packageTemporaryDir.path()).toUtf8()); + + QDir::root().mkpath(destPath); + QDir dest(destPath); + + JlCompress::extractDir(packageFile.fileName(), destPath); + + sock->write(QString("STATUS ").append(tr("Configuring %1...").arg(name)).append("\n").toUtf8()); + + QDir startMenu; + if (isGlobalInstall) { + startMenu = QDir("C:/ProgramData/Microsoft/Windows/Start Menu/Programs"); + } else { + startMenu = QDir(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); + } + startMenu.mkpath(vendor + "/" + name); + startMenu.cd(vendor + "/" + name); + + QFileInfo executableFile(destPath + "/" + executable); + QFile::link(executableFile.absoluteFilePath(), startMenu.absoluteFilePath(executableFile.completeBaseName() + ".lnk")); + QFile::copy(QApplication::applicationFilePath(), dest.absoluteFilePath("uninstall.exe")); + + QJsonObject dataRoot; + dataRoot.insert("vendor", vendor); + dataRoot.insert("name", name); + dataRoot.insert("installPath", destPath); + dataRoot.insert("global", isGlobalInstall); + dataRoot.insert("appurl", url); + + QFile uninstallDataFile(dest.absoluteFilePath("uninstall.json")); + uninstallDataFile.open(QFile::WriteOnly); + uninstallDataFile.write(QJsonDocument(dataRoot).toJson()); + + sock->write("COMPLETE\n"); + sock->flush(); + sock->waitForBytesWritten(); + QApplication::exit(0); + }); + connect(reply, &QNetworkReply::readyRead, [=] { + packageFile.write(reply->readAll()); }); connect(reply, &QNetworkReply::downloadProgress, [=](qint64 bytesReceived, qint64 bytesTotal) { sock->write(QString("PROGRESS %1 %2\n").arg(QString::number(bytesReceived), QString::number(bytesTotal)).toUtf8()); diff --git a/installer/process/installworker.h b/installer/process/installworker.h index 84cbc48..c98763b 100644 --- a/installer/process/installworker.h +++ b/installer/process/installworker.h @@ -12,6 +12,11 @@ #include #include #include +#include +#include +#include + +#include #include diff --git a/installer/process/removeworker.cpp b/installer/process/removeworker.cpp new file mode 100644 index 0000000..bdc1f64 --- /dev/null +++ b/installer/process/removeworker.cpp @@ -0,0 +1,75 @@ +#include "removeworker.h" + +RemoveWorker::RemoveWorker(QObject *parent) : QObject(parent) +{ + +} + +bool RemoveWorker::startWork() { + QLocalSocket* sock = new QLocalSocket(); + + QString previousToken; + for (QString arg : QApplication::arguments()) { + if (previousToken != "") { + if (previousToken == "--socket") { + sock->setServerName(arg); + } + previousToken = ""; + } else { + if (arg == "--socket") { + previousToken = arg; + } + } + } + + if (sock->serverName() == "") { + qDebug() << "Required argument --socket missing"; + return false; + } + + qDebug() << "Connecting to socket server..."; + sock->connectToServer(); + if (!sock->waitForConnected()) { + qDebug() << "Failed to connect to socket server"; + return false; + } + connect(sock, &QLocalSocket::disconnected, [=] { + qDebug() << "Socket closed"; + QApplication::exit(1); + }); + + QFile metadataFile(QApplication::applicationDirPath() + "/uninstall.json"); + metadataFile.open(QFile::ReadOnly); + QJsonObject metadata = QJsonDocument::fromJson(metadataFile.readAll()).object(); + + QString name = metadata.value("name").toString(); + QString vendor = metadata.value("vendor").toString(); + + sock->write(QString("STATUS ").append(tr("Removing %1...").arg(name)).append("\n").toUtf8()); + + //Remove Start menu entry + QDir startMenu; + if (metadata.value("global").toBool()) { + startMenu = QDir("C:/ProgramData/Microsoft/Windows/Start Menu/Programs"); + } else { + startMenu = QDir(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); + } + startMenu.cd(vendor + "/" + name); + startMenu.removeRecursively(); + startMenu.cdUp(); + if (startMenu.entryList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs).count() == 0) { + startMenu.removeRecursively(); + } + + //Remove items in installation directory + QDir dest(metadata.value("installPath").toString()); + dest.removeRecursively(); + + sock->write("COMPLETE\n"); + sock->flush(); + sock->waitForBytesWritten(); + QTimer::singleShot(0, [=] { + QApplication::exit(0); + }); + return 0; +} diff --git a/installer/process/removeworker.h b/installer/process/removeworker.h new file mode 100644 index 0000000..aaa344a --- /dev/null +++ b/installer/process/removeworker.h @@ -0,0 +1,26 @@ +#ifndef REMOVEWORKER_H +#define REMOVEWORKER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RemoveWorker : public QObject +{ + Q_OBJECT +public: + explicit RemoveWorker(QObject *parent = nullptr); + +signals: + +public slots: + bool startWork(); +}; + +#endif // REMOVEWORKER_H -- cgit v1.2.3