summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-03-06 13:51:05 -0800
committerGiampaolo Rodola <g.rodola@gmail.com>2016-03-06 13:51:05 -0800
commita93bac9880a1d8eda49821998d74505d0480fc6a (patch)
treead3b9c9e6137605f7a0bc3a3956f16c0bdb5255d
parentbeca72daac4572b08dd431c002bcbb2202c7216f (diff)
downloadpsutil-a93bac9880a1d8eda49821998d74505d0480fc6a.tar.gz
#795 / win services: also return service PID
-rw-r--r--psutil/_pswindows.py16
-rw-r--r--psutil/arch/windows/services.c23
-rw-r--r--psutil/tests/test_windows.py2
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__':