From 1944f77457ebab52e72c1a7a35d63d357c2077e6 Mon Sep 17 00:00:00 2001 From: skyjake Date: Tue, 17 Jul 2012 11:57:54 +0300 Subject: [PATCH] Updater|Win32: Ask to stop Snowberry if it is running As Windows cannot update files that are in use, we must ask the user to quit Snowberry before the installer is started. --- doomsday/engine/engine.pro | 2 + doomsday/engine/portable/src/updater.cpp | 5 ++ .../src/updater/processcheckdialog.cpp | 61 +++++++++++++++++++ .../portable/src/updater/processcheckdialog.h | 56 +++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 doomsday/engine/portable/src/updater/processcheckdialog.cpp create mode 100644 doomsday/engine/portable/src/updater/processcheckdialog.h diff --git a/doomsday/engine/engine.pro b/doomsday/engine/engine.pro index 2da632d8a5..5e701a182f 100644 --- a/doomsday/engine/engine.pro +++ b/doomsday/engine/engine.pro @@ -365,6 +365,7 @@ DENG_HEADERS += \ portable/include/zipfile.h \ portable/include/zonedebug.h \ portable/src/updater/downloaddialog.h \ + portable/src/updater/processcheckdialog.h \ portable/src/updater/updateavailabledialog.h \ portable/src/updater/updaterdialog.h \ portable/src/updater/updatersettings.h \ @@ -645,6 +646,7 @@ SOURCES += \ portable/src/ui_panel.c \ portable/src/updater.cpp \ portable/src/updater/downloaddialog.cpp \ + portable/src/updater/processcheckdialog.cpp \ portable/src/updater/updateavailabledialog.cpp \ portable/src/updater/updaterdialog.cpp \ portable/src/updater/updatersettings.cpp \ diff --git a/doomsday/engine/portable/src/updater.cpp b/doomsday/engine/portable/src/updater.cpp index a99b4f9b71..68a3625a78 100644 --- a/doomsday/engine/portable/src/updater.cpp +++ b/doomsday/engine/portable/src/updater.cpp @@ -53,6 +53,7 @@ #include "json.h" #include "updater.h" #include "updater/downloaddialog.h" +#include "updater/processcheckdialog.h" #include "updater/updateavailabledialog.h" #include "updater/updatersettings.h" #include "updater/updatersettingsdialog.h" @@ -403,6 +404,10 @@ struct Updater::Instance atexit(runInstallerCommand); #elif defined(WIN32) + Updater_AskToStopProcess("snowberry.exe", "Please quit the Doomsday Engine Frontend " + "before starting the update. Windows cannot update " + "files that are currently in use."); + // The distribution package is an installer executable, we can just run it. installerCommand = new de::CommandLine; installerCommand->append(distribPackagePath); diff --git a/doomsday/engine/portable/src/updater/processcheckdialog.cpp b/doomsday/engine/portable/src/updater/processcheckdialog.cpp new file mode 100644 index 0000000000..6bef2ba95c --- /dev/null +++ b/doomsday/engine/portable/src/updater/processcheckdialog.cpp @@ -0,0 +1,61 @@ +/** + * @file processcheckdialog.cpp + * Dialog for checking running processes on Windows. @ingroup updater + * + * @authors Copyright © 2012 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "processcheckdialog.h" +#include +#include +#include + +#ifdef WIN32 + +static bool isProcessRunning(const char* name) +{ + QProcess wmic; + wmic.start("wmic.exe", QStringList() << "PROCESS" << "get" << "Caption"); + if(!wmic.waitForStarted()) return false; + if(!wmic.waitForFinished()) return false; + + QByteArray result = wmic.readAll(); + foreach(QString p, QString(result).split("\n", QString::SkipEmptyParts)) + { + if(!p.trimmed().compare(QLatin1String(name), Qt::CaseInsensitive)) + return true; + } + return false; +} + +boolean Updater_AskToStopProcess(const char* processName, const char* message) +{ + while(isProcessRunning(processName)) + { + // Show a notification dialog. + QMessageBox msg(QMessageBox::Warning, "Files In Use", message, + QMessageBox::Retry | QMessageBox::Ignore); + msg.setInformativeText(QString("(There is a running process called %1.)").arg(processName)); + if(msg.exec() == QMessageBox::Ignore) + { + return !isProcessRunning(processName); + } + } + return true; +} + +#endif // WIN32 diff --git a/doomsday/engine/portable/src/updater/processcheckdialog.h b/doomsday/engine/portable/src/updater/processcheckdialog.h new file mode 100644 index 0000000000..789c9fa989 --- /dev/null +++ b/doomsday/engine/portable/src/updater/processcheckdialog.h @@ -0,0 +1,56 @@ +/** + * @file processcheckdialog.h + * Dialog for checking running processes on Windows. @ingroup updater + * + * Windows cannot overwrite files that are in use. Thus the updater needs + * to ensure that all Snowberry is shut down before starting an update. + * + * @authors Copyright © 2012 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LIBDENG_PROCESSCHECKDIALOG_H +#define LIBDENG_PROCESSCHECKDIALOG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// This is only for Windows. +#ifdef WIN32 + +/** + * Asks the user to stop a process if it is found to be running. + * + * @param processName Name of the process to check for (e.g., "snowberry.exe"). + * @param message Message to display to the user if the process is + * running. Should describe why the process needs to be + * stopped. + * + * @return @c true, if the process has been stopped. Otherwise @c false, + * the process is still running. + */ +boolean Updater_AskToStopProcess(const char* processName, const char* message); + +#endif // WIN32 + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // LIBDENG_PROCESSCHECKDIALOG_H