From e8ca150c38478cfd4a762dccd3da1752ee19ab29 Mon Sep 17 00:00:00 2001 From: Victor Tran Date: Fri, 13 Jul 2018 14:55:07 +1000 Subject: Add/Remove Programs support --- installer/main.cpp | 17 ++++++++++++++- installer/maintainwindow.cpp | 19 +++++++++++++++- installer/maintainwindow.h | 1 + installer/mainwindow.cpp | 3 +++ installer/process/installworker.cpp | 42 ++++++++++++++++++++++++++++++++++++ installer/process/installworker.h | 4 +++- installer/process/removeworker.cpp | 24 +++++++++++++++++++-- installer/process/removeworker.h | 1 + installer/translations/vi_VN.qm | Bin 1522 -> 2914 bytes 9 files changed, 106 insertions(+), 5 deletions(-) (limited to 'installer') diff --git a/installer/main.cpp b/installer/main.cpp index b29c90d..ec07db9 100644 --- a/installer/main.cpp +++ b/installer/main.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include int main(int argc, char *argv[]) { @@ -36,12 +38,25 @@ int main(int argc, char *argv[]) a.setQuitOnLastWindowClosed(false); return a.exec(); - } else if (QFile(a.applicationDirPath() + "/uninstall.json").exists()) { + } else if (a.arguments().contains("--uninstallmetadata")) { //Modify UI mode MaintainWindow w; w.show(); return a.exec(); + } else if (QFile(a.applicationDirPath() + "/uninstall.json").exists()) { + //Prepare uninstall mode + QString tempInstallerPath = QDir::tempPath() + "/theinstaller.exe"; + if (QFile::exists(tempInstallerPath)) { + QFile::remove(tempInstallerPath); + } + if (QFile::copy(QApplication::applicationFilePath(), tempInstallerPath)) { + QProcess::startDetached(tempInstallerPath, QStringList() << "--uninstallmetadata" << a.applicationDirPath() + "/uninstall.json"); + return 0; + } else { + QMessageBox::warning(nullptr, "Error", "Failed to prepare uninstallation", QMessageBox::Ok, QMessageBox::Ok); + return 1; + } } //Install UI mode diff --git a/installer/maintainwindow.cpp b/installer/maintainwindow.cpp index e1d47a8..447d3f5 100644 --- a/installer/maintainwindow.cpp +++ b/installer/maintainwindow.cpp @@ -14,9 +14,25 @@ MaintainWindow::MaintainWindow(QWidget *parent) : ui->performUninstallButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_VistaShield)); - QFile metadataFile(QApplication::applicationDirPath() + "/uninstall.json"); + QString previousToken; + for (QString arg : QApplication::arguments()) { + if (previousToken != "") { + if (previousToken == "--uninstallmetadata") { + this->metadataFile = arg; + } + previousToken = ""; + } else { + if (arg == "--uninstallmetadata") { + previousToken = arg; + } + } + } + + QFile metadataFile(this->metadataFile); metadataFile.open(QFile::ReadOnly); metadata = QJsonDocument::fromJson(metadataFile.readAll()).object(); + + ui->areYouSureText->setText(tr("Are you sure you want to uninstall %1?").arg(metadata.value("name").toString())); } MaintainWindow::~MaintainWindow() @@ -107,6 +123,7 @@ void MaintainWindow::on_performUninstallButton_clicked() QStringList args; args.append("\"--remove\""); args.append("\"--socket " + socketServer->serverName() + "\""); + args.append("\"--uninstallmetadata \"\"" + metadataFile + "\"\"\""); QStringList psArgs; psArgs.append("-FilePath \"" + QApplication::applicationFilePath() + "\""); diff --git a/installer/maintainwindow.h b/installer/maintainwindow.h index 8f648c7..076460d 100644 --- a/installer/maintainwindow.h +++ b/installer/maintainwindow.h @@ -50,6 +50,7 @@ private: QPixmap backgroundImage; QWinTaskbarButton* taskbarButton; QJsonObject metadata; + QString metadataFile; bool modifyDone = false; }; diff --git a/installer/mainwindow.cpp b/installer/mainwindow.cpp index bf52e34..b02c45f 100644 --- a/installer/mainwindow.cpp +++ b/installer/mainwindow.cpp @@ -154,6 +154,9 @@ void MainWindow::on_installButton_clicked() ui->stack->setCurrentIndex(5); taskbarButton->progress()->setVisible(false); + } else if (parts.at(0) == "ALERT") { + parts.takeFirst(); + QMessageBox::warning(this, tr("Warning"), parts.join(" "), QMessageBox::Ok, QMessageBox::Ok); } } }); diff --git a/installer/process/installworker.cpp b/installer/process/installworker.cpp index 5b44ad1..e7708ad 100644 --- a/installer/process/installworker.cpp +++ b/installer/process/installworker.cpp @@ -102,6 +102,48 @@ bool InstallWorker::startWork() { 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()); diff --git a/installer/process/installworker.h b/installer/process/installworker.h index c98763b..ea0db48 100644 --- a/installer/process/installworker.h +++ b/installer/process/installworker.h @@ -15,10 +15,12 @@ #include #include #include +#include +#include #include -#include +#include class InstallWorker : public QObject { diff --git a/installer/process/removeworker.cpp b/installer/process/removeworker.cpp index bdc1f64..2bca275 100644 --- a/installer/process/removeworker.cpp +++ b/installer/process/removeworker.cpp @@ -7,16 +7,19 @@ 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") { + if (arg == "--socket" || arg == "--uninstallmetadata") { previousToken = arg; } } @@ -27,6 +30,11 @@ bool RemoveWorker::startWork() { return false; } + if (metadataFilePath == "") { + qDebug() << "Required argument --uninstallmetadata missing"; + return false; + } + qDebug() << "Connecting to socket server..."; sock->connectToServer(); if (!sock->waitForConnected()) { @@ -38,9 +46,10 @@ bool RemoveWorker::startWork() { QApplication::exit(1); }); - QFile metadataFile(QApplication::applicationDirPath() + "/uninstall.json"); + 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(); @@ -65,6 +74,17 @@ bool RemoveWorker::startWork() { 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(); diff --git a/installer/process/removeworker.h b/installer/process/removeworker.h index aaa344a..9a73316 100644 --- a/installer/process/removeworker.h +++ b/installer/process/removeworker.h @@ -10,6 +10,7 @@ #include #include #include +#include class RemoveWorker : public QObject { diff --git a/installer/translations/vi_VN.qm b/installer/translations/vi_VN.qm index 39207f8..5c888e1 100644 Binary files a/installer/translations/vi_VN.qm and b/installer/translations/vi_VN.qm differ -- cgit v1.2.3