Skip to content

Commit

Permalink
#795 / win services: also return service PID
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Mar 6, 2016
1 parent beca72d commit a93bac9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 11 deletions.
16 changes: 12 additions & 4 deletions psutil/_pswindows.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,18 +324,26 @@ def users():
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
Expand All @@ -351,8 +359,8 @@ def status(self):

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
Expand Down
23 changes: 16 additions & 7 deletions psutil/arch/windows/services.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions psutil/tests/test_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,8 @@ def test_win_service_iter(self):
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__':
Expand Down

0 comments on commit a93bac9

Please sign in to comment.