summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@nokia.com>2012-05-07 14:00:36 +0200
committerTim Jenssen <tim.jenssen@nokia.com>2012-05-07 15:32:29 +0200
commitf1f4d8e043b17d4c5e25bffce53134293d968aed (patch)
treefd300c1affd9bc172b1e3a45b9e50db34c347cf7 /src
parent856d3bb01ae91e41770c4e5a1ae74ffcfdfed594 (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>
Diffstat (limited to 'src')
-rw-r--r--src/libs/installer/packagemanagercore.cpp40
-rw-r--r--src/libs/installer/packagemanagercore.h1
-rw-r--r--src/libs/kdtools/kdsysinfo.h1
-rw-r--r--src/libs/kdtools/kdsysinfo_mac.cpp8
-rw-r--r--src/libs/kdtools/kdsysinfo_win.cpp39
-rw-r--r--src/libs/kdtools/kdsysinfo_x11.cpp8
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