diff options
author | Thomas Hartmann <Thomas.Hartmann@nokia.com> | 2012-08-06 13:31:28 +0200 |
---|---|---|
committer | hjk <qthjk@ovi.com> | 2012-08-06 13:46:58 +0200 |
commit | a6600a2db268f9dec2b05bea7f0b15520dce81c2 (patch) | |
tree | 3de23587c1d5c7e84547a9314966c4457fe0bb23 /src/plugins/projectexplorer/devicesupport/localprocesslist.cpp | |
parent | 33f37b43562a3a11a467bb1ebf3ce903d2be0352 (diff) | |
download | qt-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.cpp | 80 |
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. |