diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2016-03-06 13:51:05 -0800 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2016-03-06 13:51:05 -0800 |
commit | a93bac9880a1d8eda49821998d74505d0480fc6a (patch) | |
tree | ad3b9c9e6137605f7a0bc3a3956f16c0bdb5255d | |
parent | beca72daac4572b08dd431c002bcbb2202c7216f (diff) | |
download | psutil-a93bac9880a1d8eda49821998d74505d0480fc6a.tar.gz |
#795 / win services: also return service PID
-rw-r--r-- | psutil/_pswindows.py | 16 | ||||
-rw-r--r-- | psutil/arch/windows/services.c | 23 | ||||
-rw-r--r-- | psutil/tests/test_windows.py | 2 |
3 files changed, 30 insertions, 11 deletions
diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index e437e33c..b49d3697 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -324,19 +324,27 @@ ppid_map = cext.ppid_map # not meant to be public class WindowsService(object): """Represents an installed Windows service.""" - def __init__(self, name, display_name, status): + def __init__(self, name, display_name, status, pid): self._name = name self._display_name = display_name self._status = status + if pid == 0: + pid = None + self._pid = pid def __str__(self): - details = "(name=%s, status=%s)" % (self.name, self.status) + details = "(name=%s, status=%s, pid=%s)" % ( + self.name, self.status, self.pid) return "%s%s" % (self.__class__.__name__, details) def __repr__(self): return "<%s at %s>" % (self.__str__(), id(self)) @property + def pid(self): + return self._pid + + @property def name(self): return self._name @@ -351,8 +359,8 @@ class WindowsService(object): def win_service_iter(): """Return a list of WindowsService instances.""" - for name, display_name, status in cext.winservice_enumerate(): - yield WindowsService(name, display_name, status) + for name, display_name, status, pid in cext.winservice_enumerate(): + yield WindowsService(name, display_name, status, pid) # --- decorators diff --git a/psutil/arch/windows/services.c b/psutil/arch/windows/services.c index 61e0b217..e8bdb3b5 100644 --- a/psutil/arch/windows/services.c +++ b/psutil/arch/windows/services.c @@ -16,7 +16,7 @@ */ PyObject * psutil_winservice_enumerate(PyObject *self, PyObject *args) { - ENUM_SERVICE_STATUS *lpService = NULL; + ENUM_SERVICE_STATUS_PROCESS *lpService = NULL; SC_HANDLE sc = NULL; BOOL ok; DWORD bytesNeeded = 0; @@ -37,23 +37,32 @@ psutil_winservice_enumerate(PyObject *self, PyObject *args) { } for (;;) { - ok = EnumServicesStatus( - sc, SERVICE_WIN32, SERVICE_STATE_ALL, lpService, dwBytes, - &bytesNeeded, &srvCount, &resumeHandle); + ok = EnumServicesStatusEx( + sc, + SC_ENUM_PROCESS_INFO, + SERVICE_WIN32, + SERVICE_STATE_ALL, + (LPBYTE)lpService, + dwBytes, + &bytesNeeded, + &srvCount, + &resumeHandle, + NULL); if (ok || (GetLastError() != ERROR_MORE_DATA)) break; if (lpService) free(lpService); dwBytes = bytesNeeded; - lpService = (ENUM_SERVICE_STATUS*)malloc(dwBytes); + lpService = (ENUM_SERVICE_STATUS_PROCESS*)malloc(dwBytes); } for (i = 0; i < srvCount; i++) { py_tuple = Py_BuildValue( - "(ssi)", + "(ssik)", lpService[i].lpServiceName, // name lpService[i].lpDisplayName, // display name - lpService[i].ServiceStatus.dwCurrentState // status + lpService[i].ServiceStatusProcess.dwCurrentState, // status + lpService[i].ServiceStatusProcess.dwProcessId // pid ); if (py_tuple == NULL) goto error; diff --git a/psutil/tests/test_windows.py b/psutil/tests/test_windows.py index 6972e237..4a9d0997 100644 --- a/psutil/tests/test_windows.py +++ b/psutil/tests/test_windows.py @@ -593,6 +593,8 @@ class TestServices(unittest.TestCase): self.assertTrue(serv.name) self.assertTrue(serv.display_name) self.assertIn(serv.status, statuses) + if serv.pid is not None: + psutil.Process(serv.pid) if __name__ == '__main__': |