Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

795 win services #803

Merged
merged 21 commits into from
Apr 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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