From 14f04e63ebf45d5896effe36b55470d86f735dfb Mon Sep 17 00:00:00 2001 From: Victor Tran Date: Fri, 13 Jul 2018 22:47:55 +1000 Subject: Download progress and process checking for uninstall --- installer/installer.pro | 6 +++- installer/main.cpp | 15 ++++++++++ installer/maintainwindow.cpp | 43 ++++++++++++++++++++++++++++ installer/maintainwindow.h | 5 ++++ installer/maintainwindow.ui | 6 ++-- installer/process/installworker.cpp | 57 ++++++++++++++++++++++++++++++++++++- installer/process/installworker.h | 5 ++++ 7 files changed, 132 insertions(+), 5 deletions(-) diff --git a/installer/installer.pro b/installer/installer.pro index 396b087..b7cd4bc 100644 --- a/installer/installer.pro +++ b/installer/installer.pro @@ -189,7 +189,11 @@ FORMS += \ TRANSLATIONS += \ translations/vi_VN.ts \ - translations/pt_BR.ts + translations/pt_BR.ts \ + translations/en_US.ts \ + translations/en_GB.ts \ + translations/en_AU.ts \ + translations/en_NZ.ts win32 { #CONFIG += embed_manifest_exe diff --git a/installer/main.cpp b/installer/main.cpp index ec07db9..8059acf 100644 --- a/installer/main.cpp +++ b/installer/main.cpp @@ -65,3 +65,18 @@ int main(int argc, char *argv[]) return a.exec(); } + +QString calculateSize(quint64 size) { + QString ret; + if (size > 1073741824) { + ret = QString::number(((float) size / 1024 / 1024 / 1024), 'f', 2).append(" GiB"); + } else if (size > 1048576) { + ret = QString::number(((float) size / 1024 / 1024), 'f', 2).append(" MiB"); + } else if (size > 1024) { + ret = QString::number(((float) size / 1024), 'f', 2).append(" KiB"); + } else { + ret = QString::number((float) size, 'f', 2).append(" B"); + } + + return ret; +} diff --git a/installer/maintainwindow.cpp b/installer/maintainwindow.cpp index 8f8eb5b..f5b8414 100644 --- a/installer/maintainwindow.cpp +++ b/installer/maintainwindow.cpp @@ -48,6 +48,49 @@ void MaintainWindow::paintEvent(QPaintEvent *event) { void MaintainWindow::on_uninstallButton_clicked() { + //Check for executables inside destination directory + QDir destdir(metadata.value("installPath").toString()); + QStringList executableNames; + QDirIterator iterator(destdir, QDirIterator::Subdirectories); + while (iterator.hasNext()) { + iterator.next(); + QFileInfo executable = iterator.fileInfo(); + if (executable.suffix() == "exe") { + executableNames.append(executable.filePath()); + } + } + + //Check app isn't running + bool isOpen = false; + + DWORD processes[1024], needed; + EnumProcesses(processes, sizeof(processes), &needed); + DWORD count = needed / sizeof(DWORD); + for (uint i = 0; i < count; i++) { + if (processes[i] != 0) { + DWORD pid = processes[i]; + HANDLE proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); + if (proc != NULL) { + HMODULE mod; + DWORD needed; + if (EnumProcessModules(proc, &mod, sizeof(mod), &needed)) { + TCHAR processName[MAX_PATH] = TEXT(""); + //GetModuleBaseName(proc, mod, processName, sizeof(processName) / sizeof(TCHAR)); + GetModuleFileNameEx(proc, mod, processName, sizeof(processName) / sizeof(TCHAR)); + QString name = QString::fromWCharArray(processName).replace("\\", "/"); + for (QString executable : executableNames) { + if (name == executable) isOpen = true; + } + } + } + } + } + + if (isOpen) { + QMessageBox::warning(this, tr("%1 currently running").arg(metadata.value("name").toString()), tr("Before we continue, you'll need to close %1.").arg(metadata.value("name").toString()), QMessageBox::Ok, QMessageBox::Ok); + return; + } + ui->stack->setCurrentIndex(1); } diff --git a/installer/maintainwindow.h b/installer/maintainwindow.h index 076460d..383bc3e 100644 --- a/installer/maintainwindow.h +++ b/installer/maintainwindow.h @@ -15,6 +15,11 @@ #include #include #include +#include +#include + +#include +#include namespace Ui { class MaintainWindow; diff --git a/installer/maintainwindow.ui b/installer/maintainwindow.ui index 7bb57fa..12b4259 100644 --- a/installer/maintainwindow.ui +++ b/installer/maintainwindow.ui @@ -282,7 +282,7 @@ 20 - 270 + 260 @@ -362,7 +362,7 @@ 20 - 250 + 260 @@ -429,7 +429,7 @@ 20 - 92 + 82 diff --git a/installer/process/installworker.cpp b/installer/process/installworker.cpp index 581deb3..714bc2e 100644 --- a/installer/process/installworker.cpp +++ b/installer/process/installworker.cpp @@ -1,5 +1,7 @@ #include "installworker.h" +extern QString calculateSize(quint64 size); + InstallWorker::InstallWorker(QObject *parent) : QObject(parent) { } @@ -63,14 +65,26 @@ bool InstallWorker::startWork() { sock->write(QString("STATUS ").append(tr("Downloading %1...").arg(name)).append("\n").toUtf8()); sock->write(QString("DEBUG %1").arg(packageFile.fileName()).toUtf8()); + QTimer* flipper = new QTimer(); + flipper->setInterval(5000); + connect(flipper, &QTimer::timeout, [=] { + emitStatus = !emitStatus; + }); + flipper->start(); + QNetworkRequest req(QUrl((QString) url)); req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); req.setHeader(QNetworkRequest::UserAgentHeader, "theInstaller/1.0"); QNetworkReply* reply = mgr.get(req); + + lastBytesReceived = 0; + lastTimeUpdate = QDateTime::fromMSecsSinceEpoch(0); connect(reply, &QNetworkReply::finished, [=] { packageFile.flush(); packageFile.seek(0); + flipper->stop(); + 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()); @@ -78,7 +92,12 @@ bool InstallWorker::startWork() { QDir::root().mkpath(destPath); QDir dest(destPath); - JlCompress::extractDir(packageFile.fileName(), destPath); + QStringList extracted = JlCompress::extractDir(packageFile.fileName(), destPath); + if (extracted.length() == 0) { + //Error occurred + QApplication::exit(1); + return; + } sock->write(QString("STATUS ").append(tr("Configuring %1...").arg(name)).append("\n").toUtf8()); @@ -158,6 +177,42 @@ bool InstallWorker::startWork() { }); connect(reply, &QNetworkReply::downloadProgress, [=](qint64 bytesReceived, qint64 bytesTotal) { sock->write(QString("PROGRESS %1 %2\n").arg(QString::number(bytesReceived), QString::number(bytesTotal)).toUtf8()); + + if (lastTimeUpdate.toMSecsSinceEpoch() == 0) lastTimeUpdate = QDateTime::currentDateTimeUtc(); + + if (emitStatus) { + sock->write(QString("STATUS ").append(tr("Downloading %1...").arg(name)).append("\n").toUtf8()); + } else { + QDateTime current = QDateTime::currentDateTimeUtc(); + + float speed = (float) bytesReceived / (float) (current.toSecsSinceEpoch() - lastTimeUpdate.toSecsSinceEpoch()); //bytes per second + + qint64 bytesToGo = bytesTotal - bytesReceived; + int secondsToGo = bytesToGo / speed; + + QString downloaded = tr("%1 of %2").arg(calculateSize(bytesReceived), calculateSize(bytesTotal)); + QString currentSpeed = calculateSize(speed) + "/s"; + QString remainingTime; + + int minutes = secondsToGo / 60; + int seconds = secondsToGo % 60; + int hours = minutes / 60; + minutes = minutes % 60; + int days = hours / 24; + hours = hours % 24; + + if (days > 0) { + remainingTime = tr("%n days remaining", nullptr, days); + } else if (hours > 0) { + remainingTime = tr("%n hours remaining", nullptr, hours); + } else if (minutes > 0) { + remainingTime = tr("%n minutes remaining", nullptr, minutes); + } else { + remainingTime = tr("%n seconds remaining", nullptr, seconds); + } + + sock->write(QString("STATUS ").append(downloaded + " - " + currentSpeed + " - " + remainingTime).append("\n").toUtf8()); + } }); return true; diff --git a/installer/process/installworker.h b/installer/process/installworker.h index ea0db48..e32a147 100644 --- a/installer/process/installworker.h +++ b/installer/process/installworker.h @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -37,6 +38,10 @@ private: QNetworkAccessManager mgr; QTemporaryFile packageFile; QTemporaryDir packageTemporaryDir; + + int lastBytesReceived; + QDateTime lastTimeUpdate; + bool emitStatus = true; }; #endif // INSTALLWORKER_H -- cgit v1.2.3