Skip to content

Commit

Permalink
Merge pull request #803 from giampaolo/795-win-services
Browse files Browse the repository at this point in the history
795 win services
  • Loading branch information
giampaolo committed Apr 11, 2016
2 parents 12c7a20 + 229fcd9 commit 1fa17b6
Show file tree
Hide file tree
Showing 14 changed files with 951 additions and 8 deletions.
2 changes: 2 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Bug tracker at https://github.com/giampaolo/psutil/issues

**Enhancements**

- #795: [Windows] new APIs to deal with Windows services: win_service_iter()
and win_service_get().
- #800: [Linux] psutil.virtual_memory() returns a new "shared" memory field.

**Bug fixes**
Expand Down
25 changes: 24 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Quick links
Summary
=======

psutil (python system and process utilities) is a cross-platform library for
psutil (process and system utilities) is a cross-platform library for
retrieving information on **running processes** and **system utilization**
(CPU, memory, disks, network) in Python. It is useful mainly for **system
monitoring**, **profiling and limiting process resources** and **management of
Expand Down Expand Up @@ -332,6 +332,29 @@ Further process APIs
>>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
>>>
Windows services
================
.. code-block:: python
>>> list(psutil.win_service_iter())
[<WindowsService(name=AeLookupSvc, display_name=Application Experience) at 38850096>,
<WindowsService(name=ALG, display_name=Application Layer Gateway Service) at 38850128>,
<WindowsService(name=APNMCP, display_name=Ask Update Service) at 38850160>,
<WindowsService(name=AppIDSvc, display_name=Application Identity) at 38850192>,
...
]
>>> s = psutil.win_service_get('alg')
>>> s.as_dict()
{'binpath': 'C:\\Windows\\System32\\alg.exe',
'description': 'Provides support for 3rd party protocol plug-ins for Internet Connection Sharing',
'display_name': 'Application Layer Gateway Service',
'name': 'alg',
'pid': None,
'start_type': 'manual',
'status': 'stopped',
'username': 'NT AUTHORITY\\LocalService'}
======
Donate
======
Expand Down
71 changes: 71 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,77 @@ Popen class
0
>>>

Windows services
================

.. function:: win_service_iter()

Return an iterator yielding a :class:`WindowsService` class instance for all
Windows services installed.

.. versionadded:: 4.2.0
Availability: Windows

.. function:: win_service_get(name)

Get a Windows service by name, returning a :class:`WindowsService` instance.
Raise :class:`psutil.NoSuchProcess` if no service with such name exists.

.. versionadded:: 4.2.0
Availability: Windows

.. class:: WindowsService

Represents a Windows service with the given *name*. This class is returned
by :func:`win_service_iter` and :func:`win_service_get` functions and it is
not supposed to be instantiated directly.

.. method:: name()

The service name. This string is how a service is referenced and can be
passed to :func:`win_service_get` to get a new :class:`WindowsService`
instance. The return value is cached on instantiation.

.. method:: display_name()

The service display name. The return value is cached on instantiation.

.. method:: binpath()

The fully qualified path to the service binary/exe file as a string,
including command line arguments.

.. method:: username()

The name of the user that owns the service.

.. method:: start_type()

A string which can either be `"automatic"`, `"manual"` or `"disabled"`.

.. method:: pid()

The process PID, if any, else `None`. This can be passed to
:class:`Process` class to control the service's process.

.. method:: status()

Service status as a string, which may be either `"running"`, `"paused"`,
`"start_pending"`, `"pause_pending"`, `"continue_pending"`,
`"stop_pending"` or `"stopped"`.

.. method:: description()

Service long description.

.. method:: as_dict()

Utility method retrieving all the information above as a dictionary.

.. versionadded:: 4.2.0
Availability: Windows


Constants
=========

Expand Down
7 changes: 7 additions & 0 deletions make.bat
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ if "%1" == "help" (
echo test-memleaks run memory leak tests
echo test-process run process related tests
echo test-system run system APIs related tests
echo test-platform platform-specific Windows tests
echo uninstall uninstall
echo upload-all upload exes + wheels
goto :eof
Expand Down Expand Up @@ -126,6 +127,12 @@ if "%1" == "test-system" (
goto :eof
)

f "%1" == "test-platform" (
call :install
%PYTHON% psutil\tests\test_windows.py
goto :eof
)

if "%1" == "test-by-name" (
call :install
%PYTHON% -m nose psutil\tests\test_process.py psutil\tests\test_system.py psutil\tests\test_windows.py psutil\tests\test_misc.py --nocapture -v -m %2
Expand Down
23 changes: 23 additions & 0 deletions psutil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,29 @@ def users():
return _psplatform.users()


# =====================================================================
# --- Windows services
# =====================================================================


if WINDOWS:

def win_service_iter():
"""Return a generator yielding a WindowsService instance for all
Windows services installed.
"""
return _psplatform.win_service_iter()

def win_service_get(name):
"""Get a Windows service by name.
Raise NoSuchProcess if no service with such name exists.
"""
return _psplatform.win_service_get(name)


# =====================================================================


def test(): # pragma: no cover
"""List info of all currently running processes emulating ps aux
output.
Expand Down
41 changes: 40 additions & 1 deletion psutil/_psutil_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <iphlpapi.h>
#include <wtsapi32.h>
#include <ws2tcpip.h>
#include <Winsvc.h>

// Link with Iphlpapi.lib
#pragma comment(lib, "IPHLPAPI.lib")
Expand All @@ -32,6 +33,7 @@
#include "arch/windows/process_handles.h"
#include "arch/windows/ntextapi.h"
#include "arch/windows/inet_ntop.h"
#include "arch/windows/services.h"

#ifdef __MINGW32__
#include "arch/windows/glpi.h"
Expand Down Expand Up @@ -3241,7 +3243,6 @@ psutil_cpu_stats(PyObject *self, PyObject *args) {
}



// ------------------------ Python init ---------------------------

static PyMethodDef
Expand Down Expand Up @@ -3349,6 +3350,20 @@ PsutilMethods[] = {
{"cpu_stats", psutil_cpu_stats, METH_VARARGS,
"Return NICs stats."},

// --- windows services
{"winservice_enumerate", psutil_winservice_enumerate, METH_VARARGS,
"List all services"},
{"winservice_query_config", psutil_winservice_query_config, METH_VARARGS,
"Return service config"},
{"winservice_query_status", psutil_winservice_query_status, METH_VARARGS,
"Return service config"},
{"winservice_query_descr", psutil_winservice_query_descr, METH_VARARGS,
"Return the description of a service"},
{"winservice_start", psutil_winservice_start, METH_VARARGS,
"Start a service"},
{"winservice_stop", psutil_winservice_stop, METH_VARARGS,
"Stop a service"},

// --- windows API bindings
{"win32_QueryDosDevice", psutil_win32_QueryDosDevice, METH_VARARGS,
"QueryDosDevice binding"},
Expand Down Expand Up @@ -3435,6 +3450,7 @@ void init_psutil_windows(void)
module, "NORMAL_PRIORITY_CLASS", NORMAL_PRIORITY_CLASS);
PyModule_AddIntConstant(
module, "REALTIME_PRIORITY_CLASS", REALTIME_PRIORITY_CLASS);

// connection status constants
// http://msdn.microsoft.com/en-us/library/cc669305.aspx
PyModule_AddIntConstant(
Expand Down Expand Up @@ -3465,11 +3481,34 @@ void init_psutil_windows(void)
module, "MIB_TCP_STATE_DELETE_TCB", MIB_TCP_STATE_DELETE_TCB);
PyModule_AddIntConstant(
module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);

// service status constants
/*
PyModule_AddIntConstant(
module, "SERVICE_CONTINUE_PENDING", SERVICE_CONTINUE_PENDING);
PyModule_AddIntConstant(
module, "SERVICE_PAUSE_PENDING", SERVICE_PAUSE_PENDING);
PyModule_AddIntConstant(
module, "SERVICE_PAUSED", SERVICE_PAUSED);
PyModule_AddIntConstant(
module, "SERVICE_RUNNING", SERVICE_RUNNING);
PyModule_AddIntConstant(
module, "SERVICE_START_PENDING", SERVICE_START_PENDING);
PyModule_AddIntConstant(
module, "SERVICE_STOP_PENDING", SERVICE_STOP_PENDING);
PyModule_AddIntConstant(
module, "SERVICE_STOPPED", SERVICE_STOPPED);
*/

// ...for internal use in _psutil_windows.py
PyModule_AddIntConstant(
module, "INFINITE", INFINITE);
PyModule_AddIntConstant(
module, "ERROR_ACCESS_DENIED", ERROR_ACCESS_DENIED);
PyModule_AddIntConstant(
module, "ERROR_INVALID_NAME", ERROR_INVALID_NAME);
PyModule_AddIntConstant(
module, "ERROR_SERVICE_DOES_NOT_EXIST", ERROR_SERVICE_DOES_NOT_EXIST);

// set SeDebug for the current process
psutil_set_se_debug();
Expand Down
Loading

0 comments on commit 1fa17b6

Please sign in to comment.