diff options
author | Tim Jenssen <tim.jenssen@nokia.com> | 2012-05-07 14:00:36 +0200 |
---|---|---|
committer | Tim Jenssen <tim.jenssen@nokia.com> | 2012-05-07 15:32:29 +0200 |
commit | f1f4d8e043b17d4c5e25bffce53134293d968aed (patch) | |
tree | fd300c1affd9bc172b1e3a45b9e50db34c347cf7 | |
parent | 856d3bb01ae91e41770c4e5a1ae74ffcfdfed594 (diff) |
add killProcess method
- only implemented under windows where it could be needed for update
- even the delete file method moves files to temp which can not be removed, it is much safer to kill the process
Change-Id: Ide043657d5f74186da02cb18a87072b18910c964
Reviewed-by: Oliver Wolff <oliver.wolff@nokia.com>
Reviewed-by: Karsten Heimrich <karsten.heimrich@nokia.com>
-rw-r--r-- | src/libs/installer/packagemanagercore.cpp | 40 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.h | 1 | ||||
-rw-r--r-- | src/libs/kdtools/kdsysinfo.h | 1 | ||||
-rw-r--r-- | src/libs/kdtools/kdsysinfo_mac.cpp | 8 | ||||
-rw-r--r-- | src/libs/kdtools/kdsysinfo_win.cpp | 39 | ||||
-rw-r--r-- | src/libs/kdtools/kdsysinfo_x11.cpp | 8 |
6 files changed, 97 insertions, 0 deletions
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 09cfcac9f..81537814c 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -49,6 +49,10 @@ #include "settings.h" #include "utils.h" +#include <QFuture> +#include <QFutureWatcher> +#include <QtConcurrentRun> + #include <QtCore/QMutex> #include <QtCore/QSettings> #include <QtCore/QTemporaryFile> @@ -1103,6 +1107,42 @@ bool PackageManagerCore::isProcessRunning(const QString &name) const return PackageManagerCorePrivate::isProcessRunning(name, runningProcesses()); } +/*! + Return true, if a process with \a absoluteFilePath could be killed or isn't running + Note: this is implemented in a semi blocking way (to keep the main thread to paint the UI) +*/ +bool PackageManagerCore::killProcess(const QString &absoluteFilePath) const +{ + QString normalizedPath = replaceVariables(absoluteFilePath); + normalizedPath = QDir::cleanPath(normalizedPath.replace(QLatin1Char('\\'), QLatin1Char('/'))); + + QList<ProcessInfo> allProcesses = runningProcesses(); + foreach (const ProcessInfo &process, allProcesses) { + QString processPath = process.name; + processPath = QDir::cleanPath(processPath.replace(QLatin1Char('\\'), QLatin1Char('/'))); + + if (processPath == normalizedPath) { + qDebug() << QString::fromLatin1("try to kill process: %1(%2)").arg(process.name).arg(process.id); + + //to keep the ui responsible use QtConcurrent::run + QFutureWatcher<bool> futureWatcher; + const QFuture<bool> future = QtConcurrent::run(KDUpdater::killProcess, process, 30000); + + QEventLoop loop; + loop.connect(&futureWatcher, SIGNAL(finished()), SLOT(quit()), Qt::QueuedConnection); + futureWatcher.setFuture(future); + + if (!future.isFinished()) + loop.exec(); + + qDebug() << QString::fromLatin1("\"%1\" killed!").arg(process.name); + return future.result(); + } + } + return true; +} + + void PackageManagerCore::setDependsOnLocalInstallerBinary() { d->m_dependsOnLocalInstallerBinary = true; diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h index 3ecf067cd..b7dd7585e 100644 --- a/src/libs/installer/packagemanagercore.h +++ b/src/libs/installer/packagemanagercore.h @@ -213,6 +213,7 @@ public: Q_INVOKABLE quint64 requiredTemporaryDiskSpace() const; Q_INVOKABLE bool isProcessRunning(const QString &name) const; + Q_INVOKABLE bool killProcess(const QString &absoluteFilePath) const; Settings &settings() const; diff --git a/src/libs/kdtools/kdsysinfo.h b/src/libs/kdtools/kdsysinfo.h index be1b76fca..bab32979a 100644 --- a/src/libs/kdtools/kdsysinfo.h +++ b/src/libs/kdtools/kdsysinfo.h @@ -70,6 +70,7 @@ struct ProcessInfo quint64 installedMemory(); QList<VolumeInfo> mountedVolumes(); QList<ProcessInfo> runningProcesses(); +bool killProcess(const ProcessInfo &process, int msecs = 30000); bool pathIsOnLocalDevice(const QString &path); } // namespace KDUpdater diff --git a/src/libs/kdtools/kdsysinfo_mac.cpp b/src/libs/kdtools/kdsysinfo_mac.cpp index 6ec6b6760..e81b88495 100644 --- a/src/libs/kdtools/kdsysinfo_mac.cpp +++ b/src/libs/kdtools/kdsysinfo_mac.cpp @@ -138,4 +138,12 @@ bool pathIsOnLocalDevice(const QString &path) return true; } +bool killProcess(const ProcessInfo &process, int msecs) +{ + Q_UNUSED(process); + Q_UNUSED(msecs); + + return true; +} + } // namespace KDUpdater diff --git a/src/libs/kdtools/kdsysinfo_win.cpp b/src/libs/kdtools/kdsysinfo_win.cpp index 92d87d680..3e99e3925 100644 --- a/src/libs/kdtools/kdsysinfo_win.cpp +++ b/src/libs/kdtools/kdsysinfo_win.cpp @@ -210,6 +210,45 @@ QList<ProcessInfo> runningProcesses() return param.processes; } +bool CALLBACK TerminateAppEnum(HWND hwnd, LPARAM lParam) +{ + DWORD dwID; + GetWindowThreadProcessId(hwnd, &dwID); + + if (dwID == (DWORD)lParam) + PostMessage(hwnd, WM_CLOSE, 0, 0); + + return true; +} + +bool killProcess(const ProcessInfo &process, int msecs) +{ + DWORD dwTimeout = msecs; + if (msecs == -1) + dwTimeout = INFINITE; + + // If we can't open the process with PROCESS_TERMINATE rights, + // then we give up immediately. + HANDLE hProc = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE, process.id); + + if (hProc == 0) + return false; + + // TerminateAppEnum() posts WM_CLOSE to all windows whose PID + // matches your process's. + EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM)process.id); + + // Wait on the handle. If it signals, great. If it times out, + // then you kill it. + bool returnValue = false; + if (WaitForSingleObject(hProc, dwTimeout) != WAIT_OBJECT_0) + returnValue = TerminateProcess(hProc, 0); + + CloseHandle(hProc) ; + + return returnValue; +} + // REPARSE_DATA_BUFFER structure from msdn help: http://msdn.microsoft.com/en-us/library/ff552012.aspx typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; diff --git a/src/libs/kdtools/kdsysinfo_x11.cpp b/src/libs/kdtools/kdsysinfo_x11.cpp index 1a93afb15..5a816dc18 100644 --- a/src/libs/kdtools/kdsysinfo_x11.cpp +++ b/src/libs/kdtools/kdsysinfo_x11.cpp @@ -122,4 +122,12 @@ bool pathIsOnLocalDevice(const QString &path) return true; } +bool killProcess(const ProcessInfo &process, int msecs) +{ + Q_UNUSED(process); + Q_UNUSED(msecs); + + return true; +} + } // namespace KDUpdater |