summaryrefslogtreecommitdiff
path: root/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
diff options
context:
space:
mode:
authorThomas Hartmann <Thomas.Hartmann@nokia.com>2012-08-06 13:31:28 +0200
committerhjk <qthjk@ovi.com>2012-08-06 13:46:58 +0200
commita6600a2db268f9dec2b05bea7f0b15520dce81c2 (patch)
tree3de23587c1d5c7e84547a9314966c4457fe0bb23 /src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
parent33f37b43562a3a11a467bb1ebf3ce903d2be0352 (diff)
downloadqt-creator-a6600a2db268f9dec2b05bea7f0b15520dce81c2.tar.gz
Add support for Windows in LocalProcessList
The call to handleWindowsUpdate is asynchronous to keep a unified behaivour. Change-Id: I2e422a203955aa84317f29531f6c259dc3ab823c Reviewed-by: hjk <qthjk@ovi.com>
Diffstat (limited to 'src/plugins/projectexplorer/devicesupport/localprocesslist.cpp')
-rw-r--r--src/plugins/projectexplorer/devicesupport/localprocesslist.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
index 8b7e1c844d..2661727278 100644
--- a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
+++ b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
@@ -29,6 +29,7 @@
#include "localprocesslist.h"
+#include <QLibrary>
#include <QProcess>
#include <QTimer>
@@ -40,24 +41,79 @@
#include <signal.h>
#endif
+#ifdef Q_OS_WIN
+
+// Enable Win API of XP SP1 and later
+#define _WIN32_WINNT 0x0502
+#include <windows.h>
+#include <utils/winutils.h>
+#include <tlhelp32.h>
+#include <psapi.h>
+
+#endif // Q_OS_WIN
+
namespace ProjectExplorer {
namespace Internal {
const int PsFieldWidth = 50;
+#ifdef Q_OS_WIN
+
+// Resolve QueryFullProcessImageNameW out of kernel32.dll due
+// to incomplete MinGW import libs and it not being present
+// on Windows XP.
+static BOOL queryFullProcessImageName(HANDLE h, DWORD flags, LPWSTR buffer, DWORD *size)
+{
+ // Resolve required symbols from the kernel32.dll
+ typedef BOOL (WINAPI *QueryFullProcessImageNameWProtoType)
+ (HANDLE, DWORD, LPWSTR, PDWORD);
+ static QueryFullProcessImageNameWProtoType queryFullProcessImageNameW = 0;
+ if (!queryFullProcessImageNameW) {
+ QLibrary kernel32Lib(QLatin1String("kernel32.dll"), 0);
+ if (kernel32Lib.isLoaded() || kernel32Lib.load())
+ queryFullProcessImageNameW = (QueryFullProcessImageNameWProtoType)kernel32Lib.resolve("QueryFullProcessImageNameW");
+ }
+ if (!queryFullProcessImageNameW)
+ return FALSE;
+ // Read out process
+ return (*queryFullProcessImageNameW)(h, flags, buffer, size);
+}
+
+static QString imageName(DWORD processId)
+{
+ QString rc;
+ HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION , FALSE, processId);
+ if (handle == INVALID_HANDLE_VALUE)
+ return rc;
+ WCHAR buffer[MAX_PATH];
+ DWORD bufSize = MAX_PATH;
+ if (queryFullProcessImageName(handle, 0, buffer, &bufSize))
+ rc = QString::fromUtf16(reinterpret_cast<const ushort*>(buffer));
+ CloseHandle(handle);
+ return rc;
+}
+#endif //Q_OS_WIN
+
LocalProcessList::LocalProcessList(const IDevice::ConstPtr &device, QObject *parent)
: DeviceProcessList(device, parent),
m_psProcess(new QProcess(this))
{
+#ifdef Q_OS_UNIX
connect(m_psProcess, SIGNAL(error(QProcess::ProcessError)), SLOT(handlePsError()));
connect(m_psProcess, SIGNAL(finished(int)), SLOT(handlePsFinished()));
+#endif //Q_OS_UNIX
}
void LocalProcessList::doUpdate()
{
+#ifdef Q_OS_UNIX
// We assume Desktop Unix systems to have a POSIX-compliant ps.
// We need the padding because the command field can contain spaces, so we cannot split on those.
m_psProcess->start(QString::fromLocal8Bit("ps -e -o pid=%1 -o comm=%1 -o args=%1")
.arg(QString(PsFieldWidth, QChar('x'))));
+#endif
+#ifdef Q_OS_WIN
+ QTimer::singleShot(0, this, SLOT(handleWindowsUpdate()));
+#endif
}
void LocalProcessList::handlePsFinished()
@@ -95,6 +151,30 @@ void LocalProcessList::handlePsFinished()
reportError(errorString);
}
+void LocalProcessList::handleWindowsUpdate()
+{
+ QList<DeviceProcess> processes;
+
+ PROCESSENTRY32 pe;
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (snapshot == INVALID_HANDLE_VALUE)
+ return;
+
+ for (bool hasNext = Process32First(snapshot, &pe); hasNext; hasNext = Process32Next(snapshot, &pe)) {
+ DeviceProcess p;
+ p.pid = pe.th32ProcessID;
+ p.exe = QString::fromUtf16(reinterpret_cast<ushort*>(pe.szExeFile));
+ p.cmdLine = imageName(pe.th32ProcessID);
+ if (p.cmdLine.isEmpty())
+ p.cmdLine = p.exe;
+ processes << p;
+ }
+ CloseHandle(snapshot);
+
+ reportProcessListUpdated(processes);
+}
+
void LocalProcessList::handlePsError()
{
// Other errors are handled in the finished() handler.