aboutsummaryrefslogtreecommitdiff
path: root/installer/process
diff options
context:
space:
mode:
Diffstat (limited to 'installer/process')
-rw-r--r--installer/process/installworker.cpp164
-rw-r--r--installer/process/installworker.h42
-rw-r--r--installer/process/removeworker.cpp95
-rw-r--r--installer/process/removeworker.h27
4 files changed, 328 insertions, 0 deletions
diff --git a/installer/process/installworker.cpp b/installer/process/installworker.cpp
new file mode 100644
index 0000000..e7708ad
--- /dev/null
+++ b/installer/process/installworker.cpp
@@ -0,0 +1,164 @@
+#include "installworker.h"
+
+InstallWorker::InstallWorker(QObject *parent) : QObject(parent)
+{
+}
+
+bool InstallWorker::startWork() {
+ QLocalSocket* sock = new QLocalSocket();
+ QString vendor, name, url, destPath, executable;
+ bool isStableStream = true, isGlobalInstall = true;
+
+ QString previousToken;
+ for (QString arg : QApplication::arguments()) {
+ if (previousToken != "") {
+ if (previousToken == "--socket") {
+ sock->setServerName(arg);
+ } else if (previousToken == "--vendor") {
+ vendor = arg;
+ } else if (previousToken == "--name") {
+ name = arg;
+ } else if (previousToken == "--url") {
+ 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" || arg == "--executable") {
+ previousToken = arg;
+ } else if (arg == "--blueprint") {
+ isStableStream = false;
+ } else if (arg == "--stable") {
+ isStableStream = true;
+ } else if (arg == "--local") {
+ isGlobalInstall = false;
+ } else if (arg == "--global") {
+ isGlobalInstall = true;
+ }
+ }
+ }
+
+ 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);
+ });
+
+ if (!packageFile.open() || !packageTemporaryDir.isValid()) {
+ return false;
+ }
+ sock->write(QString("STATUS ").append(tr("Downloading %1...").arg(name)).append("\n").toUtf8());
+ sock->write(QString("DEBUG %1").arg(packageFile.fileName()).toUtf8());
+
+ QNetworkRequest req(QUrl((QString) url));
+ req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
+ 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);
+
+ //Write uninstall information to registry
+ QUuid uuid = QUuid::createUuid();
+ dataRoot.insert("registryUuid", uuid.toString());
+ /*HKEY SoftwareEntry;
+ HKEY hive;
+ LPCWSTR keyPath = (LPCWSTR) QString("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + uuid.toString()).utf16();
+
+ if (isGlobalInstall) {
+ hive = HKEY_LOCAL_MACHINE;
+ } else {
+ hive = HKEY_CURRENT_USER;
+ }
+
+ LSTATUS createReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE, keyPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &SoftwareEntry, NULL);
+ if (createReturn == ERROR_SUCCESS) {
+ RegSetValueEx(SoftwareEntry, TEXT("DisplayName"), 0, REG_SZ, (const BYTE*) vendor.toStdString().data(), vendor.count() + 1);
+
+ RegCloseKey(SoftwareEntry);
+
+ sock->write(QString("DEBUG Uninstall GUID: " + uuid.toString()).toUtf8());
+ } else {
+ sock->write(QString("ALERT " + tr("Error writing uninstall information to the registry: Error 0x%1").arg(QString::number(createReturn, 16)) + "\n").toUtf8());
+ }*/
+
+ QSettings* settings;
+ if (isGlobalInstall) {
+ settings = new QSettings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + uuid.toString(), QSettings::NativeFormat);
+ } else {
+ settings = new QSettings("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + uuid.toString(), QSettings::NativeFormat);
+ }
+
+ settings->setValue("DisplayName", name);
+ settings->setValue("Publisher", vendor);
+ settings->setValue("Contact", vendor);
+ settings->setValue("ModifyPath", dest.absoluteFilePath("uninstall.exe"));
+ settings->setValue("UninstallString", dest.absoluteFilePath("uninstall.exe"));
+ settings->setValue("InstallDate", QDateTime::currentDateTime().toString("yyyymmdd"));
+ settings->setValue("InstallLocation", dest.path());
+ settings->setValue("DisplayIcon", executableFile.absoluteFilePath() + ",0");
+ settings->sync();
+ settings->deleteLater();
+
+ 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());
+ });
+
+ return true;
+}
diff --git a/installer/process/installworker.h b/installer/process/installworker.h
new file mode 100644
index 0000000..ea0db48
--- /dev/null
+++ b/installer/process/installworker.h
@@ -0,0 +1,42 @@
+#ifndef INSTALLWORKER_H
+#define INSTALLWORKER_H
+
+#include <QObject>
+#include <QTextStream>
+#include <QLocalSocket>
+#include <QDebug>
+#include <QApplication>
+#include <QThread>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QTemporaryFile>
+#include <QTemporaryDir>
+#include <QStandardPaths>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QUuid>
+#include <QSettings>
+
+#include <quazip/JlCompress.h>
+
+#include <winreg.h>
+
+class InstallWorker : public QObject
+{
+ Q_OBJECT
+public:
+ explicit InstallWorker(QObject *parent = nullptr);
+
+signals:
+
+public slots:
+ bool startWork();
+
+private:
+ QNetworkAccessManager mgr;
+ QTemporaryFile packageFile;
+ QTemporaryDir packageTemporaryDir;
+};
+
+#endif // INSTALLWORKER_H
diff --git a/installer/process/removeworker.cpp b/installer/process/removeworker.cpp
new file mode 100644
index 0000000..2bca275
--- /dev/null
+++ b/installer/process/removeworker.cpp
@@ -0,0 +1,95 @@
+#include "removeworker.h"
+
+RemoveWorker::RemoveWorker(QObject *parent) : QObject(parent)
+{
+
+}
+
+bool RemoveWorker::startWork() {
+ QLocalSocket* sock = new QLocalSocket();
+ QString metadataFilePath;
+
+ QString previousToken;
+ for (QString arg : QApplication::arguments()) {
+ if (previousToken != "") {
+ if (previousToken == "--socket") {
+ sock->setServerName(arg);
+ } else if (previousToken == "--uninstallmetadata") {
+ metadataFilePath = arg;
+ }
+ previousToken = "";
+ } else {
+ if (arg == "--socket" || arg == "--uninstallmetadata") {
+ previousToken = arg;
+ }
+ }
+ }
+
+ if (sock->serverName() == "") {
+ qDebug() << "Required argument --socket missing";
+ return false;
+ }
+
+ if (metadataFilePath == "") {
+ qDebug() << "Required argument --uninstallmetadata 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(metadataFilePath);
+ metadataFile.open(QFile::ReadOnly);
+ QJsonObject metadata = QJsonDocument::fromJson(metadataFile.readAll()).object();
+ metadataFile.close();
+
+ 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();
+
+ //Remove registry entry
+
+ QSettings* settings;
+ if (metadata.value("global").toBool()) {
+ settings = new QSettings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", QSettings::NativeFormat);
+ } else {
+ settings = new QSettings("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", QSettings::NativeFormat);
+ }
+ settings->remove(metadata.value("registryUuid").toString());
+ settings->sync();
+
+ 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..9a73316
--- /dev/null
+++ b/installer/process/removeworker.h
@@ -0,0 +1,27 @@
+#ifndef REMOVEWORKER_H
+#define REMOVEWORKER_H
+
+#include <QObject>
+#include <QLocalSocket>
+#include <QApplication>
+#include <QFile>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QDir>
+#include <QTimer>
+#include <QStandardPaths>
+#include <QSettings>
+
+class RemoveWorker : public QObject
+{
+ Q_OBJECT
+public:
+ explicit RemoveWorker(QObject *parent = nullptr);
+
+signals:
+
+public slots:
+ bool startWork();
+};
+
+#endif // REMOVEWORKER_H