summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY186
-rw-r--r--LICENSE54
-rw-r--r--MANIFEST.in2
-rw-r--r--README246
-rwxr-xr-xdocs/class_diagram.pngbin20780 -> 20778 bytes
-rw-r--r--docs/documentation.html282
-rw-r--r--docs/index.html52
-rw-r--r--docs/milestones.lnk.html24
-rw-r--r--psutil/arch/mswindows/process_handles.c590
-rw-r--r--psutil/arch/mswindows/process_handles.h8
-rw-r--r--psutil/wmi.py2836
-rw-r--r--test/_bsd.py282
-rw-r--r--test/_linux.py48
-rw-r--r--test/_osx.py128
-rwxr-xr-xtest/_posix.py272
-rw-r--r--test/_windows.py288
-rw-r--r--test/test_psutil.py8
17 files changed, 2653 insertions, 2653 deletions
diff --git a/HISTORY b/HISTORY
index e3b4fbe0..cb362f53 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,93 +1,93 @@
-Bug tracker at http://code.google.com/p/psutil/issues
-
-0.1.4 - XXXX-XX-XX
-------------------
-NEW FEATURES
- * Issue 91: per-process send_signal() and terminate() methods.
- * Issue 95: NoSuchProcess and AccessDenied exception classes now provide a
- "pid" and a "msg" attribute.
-
-BUGFIXES
- * Issue 94: suspend() raises OSError instead of AccessDenied.
-
-
-0.1.3 - 2010-03-02
-------------------
-NEW FEATURES
- * Issue 14: per-process username
- * Issue 51: per-process current working directory (Windows and Linux only)
- * Issue 59: Process.is_running() is now 10 times faster
- * Issue 61: added supoprt for FreeBSD 64 bit
- * Issue 71: implemented suspend/resume process
- * Issue 75: python 3 support
-
-BUGFIXES
- * Issue 36: process cpu_times() and memory_info() functions succeeded also for
- dead processes while a NoSuchProcess exception is supposed to be raised.
- * Issue 48: incorrect size for mib array defined in getcmdargs for BSD
- * Issue 49: possible memory leak due to missing free() on error condition on
- * Issue 50: fixed getcmdargs() memory fragmentation on BSD
- * Issue 55: test_pid_4 was failing on Windows Vista
- * Issue 57: some unit tests were failing on systems where no swap memory is
- available
- * Issue 58: is_running() is now called before kill() to make sure we are going
- to kill the correct process.
- * Issue 73: virtual memory size reported on OS X includes shared library size
- * Issue 77: NoSuchProcess wasn't raised on Process.create_time if kill() was
- used first.
-
-
-0.1.2 - 2009-05-06
-------------------
-NEW FEATURES
- * Issue 32: Per-process CPU user/kernel times
- * Issue 33: Process create time
- * Issue 34: Per-process CPU utilization percentage
- * Issue 38: Per-process memory usage (bytes)
- * Issue 41: Per-process memory utilization (percent)
- * Issue 39: System uptime
- * Issue 43: Total system virtual memory
- * Issue 46: Total system physical memory
- * Issue 44: Total system used/free virtual and physical memory
-
-BUGFIXES
- * Issue 36: NoSuchProcess not raised on Windows when accessing timing methods
- * Issue 40: test_get_cpu_times() failing on FreeBSD and OS X
- * Issue 42: get_memory_percent() raises AccessDenied on Windows
-
-
-0.1.1 - 2009-03-06
-------------------
-NEW FEATURES
- * Issue 4: FreeBSD support for all functions of psutil
- * Issue 9: Process.uid and Process.gid now retrieve process UID and GID.
- * Issue 11: Support for parent/ppid - Process.parent property returns a
- Process object representing the parent process, and Process.ppid returns
- the parent PID.
- * Issue 12 & 15: NoSuchProcess exception now raised when creating an object
- for a nonexistent process, or when retrieving information about a process
- that has gone away.
- * Issue 21: AccessDenied exception created for raising access denied errors
- from OSError or WindowsError on individual platforms.
- * Issue 26: psutil.process_iter() function to iterate over processes as
- Process objects with a generator.
- * Process objects can now also be compared with == operator for equality
- (PID, name, command line are compared).
-
-BUGFIXES
- * Issue 16: Special case for Windows' "System Idle Process" (PID 0) which
- otherwise would return an "invalid parameter" exception.
- * Issue 17: get_process_list() ignores NoSuchProcess and AccessDenied
- exceptions during building of the list.
- * Issue 22: Process(0).kill() was failing on Windows with an unset exception
- * Issue 23: Special case for pid_exists(0)
- * Issue 24: Process(0).kill() now raises AccessDenied exception instead of
- WindowsError.
- * Issue 30: psutil.get_pid_list() was returning two instances of PID 0 on OS
- X and FreeBSD platforms.
-
-
-0.1.0 - 2009-01-27
-------------------
-
- * Initial release.
+Bug tracker at http://code.google.com/p/psutil/issues
+
+0.1.4 - XXXX-XX-XX
+------------------
+NEW FEATURES
+ * Issue 91: per-process send_signal() and terminate() methods.
+ * Issue 95: NoSuchProcess and AccessDenied exception classes now provide a
+ "pid" and a "msg" attribute.
+
+BUGFIXES
+ * Issue 94: suspend() raises OSError instead of AccessDenied.
+
+
+0.1.3 - 2010-03-02
+------------------
+NEW FEATURES
+ * Issue 14: per-process username
+ * Issue 51: per-process current working directory (Windows and Linux only)
+ * Issue 59: Process.is_running() is now 10 times faster
+ * Issue 61: added supoprt for FreeBSD 64 bit
+ * Issue 71: implemented suspend/resume process
+ * Issue 75: python 3 support
+
+BUGFIXES
+ * Issue 36: process cpu_times() and memory_info() functions succeeded also for
+ dead processes while a NoSuchProcess exception is supposed to be raised.
+ * Issue 48: incorrect size for mib array defined in getcmdargs for BSD
+ * Issue 49: possible memory leak due to missing free() on error condition on
+ * Issue 50: fixed getcmdargs() memory fragmentation on BSD
+ * Issue 55: test_pid_4 was failing on Windows Vista
+ * Issue 57: some unit tests were failing on systems where no swap memory is
+ available
+ * Issue 58: is_running() is now called before kill() to make sure we are going
+ to kill the correct process.
+ * Issue 73: virtual memory size reported on OS X includes shared library size
+ * Issue 77: NoSuchProcess wasn't raised on Process.create_time if kill() was
+ used first.
+
+
+0.1.2 - 2009-05-06
+------------------
+NEW FEATURES
+ * Issue 32: Per-process CPU user/kernel times
+ * Issue 33: Process create time
+ * Issue 34: Per-process CPU utilization percentage
+ * Issue 38: Per-process memory usage (bytes)
+ * Issue 41: Per-process memory utilization (percent)
+ * Issue 39: System uptime
+ * Issue 43: Total system virtual memory
+ * Issue 46: Total system physical memory
+ * Issue 44: Total system used/free virtual and physical memory
+
+BUGFIXES
+ * Issue 36: NoSuchProcess not raised on Windows when accessing timing methods
+ * Issue 40: test_get_cpu_times() failing on FreeBSD and OS X
+ * Issue 42: get_memory_percent() raises AccessDenied on Windows
+
+
+0.1.1 - 2009-03-06
+------------------
+NEW FEATURES
+ * Issue 4: FreeBSD support for all functions of psutil
+ * Issue 9: Process.uid and Process.gid now retrieve process UID and GID.
+ * Issue 11: Support for parent/ppid - Process.parent property returns a
+ Process object representing the parent process, and Process.ppid returns
+ the parent PID.
+ * Issue 12 & 15: NoSuchProcess exception now raised when creating an object
+ for a nonexistent process, or when retrieving information about a process
+ that has gone away.
+ * Issue 21: AccessDenied exception created for raising access denied errors
+ from OSError or WindowsError on individual platforms.
+ * Issue 26: psutil.process_iter() function to iterate over processes as
+ Process objects with a generator.
+ * Process objects can now also be compared with == operator for equality
+ (PID, name, command line are compared).
+
+BUGFIXES
+ * Issue 16: Special case for Windows' "System Idle Process" (PID 0) which
+ otherwise would return an "invalid parameter" exception.
+ * Issue 17: get_process_list() ignores NoSuchProcess and AccessDenied
+ exceptions during building of the list.
+ * Issue 22: Process(0).kill() was failing on Windows with an unset exception
+ * Issue 23: Special case for pid_exists(0)
+ * Issue 24: Process(0).kill() now raises AccessDenied exception instead of
+ WindowsError.
+ * Issue 30: psutil.get_pid_list() was returning two instances of PID 0 on OS
+ X and FreeBSD platforms.
+
+
+0.1.0 - 2009-01-27
+------------------
+
+ * Initial release.
diff --git a/LICENSE b/LICENSE
index 1e60f941..e91b1359 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,27 +1,27 @@
-psutil is distributed under BSD license reproduced below.
-
-Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola'
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the psutil authors nor the names of its contributors
- may be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
+psutil is distributed under BSD license reproduced below.
+
+Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola'
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the psutil authors nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/MANIFEST.in b/MANIFEST.in
index 513372bb..240e84d6 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -2,4 +2,4 @@ include HISTORY LICENSE MANIFEST MANIFEST.in
recursive-include docs *
recursive-include psutil *
recursive-include test *
-global-exclude *.pyc *.pyo *.exe
+global-exclude *.pyc *.pyo *.exe
diff --git a/README b/README
index dd08a115..74e52217 100644
--- a/README
+++ b/README
@@ -1,123 +1,123 @@
-
-Introduction
-============
-
-psutil is a module providing an interface for retrieving information on running
-processes in a portable way by using Python.
-It currently supports Linux, OS X, FreeBSD and Windows.
-
-psutil website is at http://code.google.com/p/psutil/
-
-The following document describes how to compile and install psutil from sources
-on different platforms.
-
-
-Using easy_install
-==================
-
-The easiest way to install psutil from sources is using easy_install.
-Get the latest easy_install version from http://pypi.python.org/pypi/setuptools
-and just run:
-
- > python easy_install psutil
-
-This should get the most updated psutil version from the Python pypi repository,
-unpack it, compile it and install it automatically.
-
-
-Installing on Windows using mingw32
-===================================
-
-After the mingw [1] environment is properly set up on your system you can
-compile Windows sources by entering:
-
- > setup.py build -c mingw32
-
-To compile and install just append the "install" keyword at the end of the
-command line above, like this:
-
- > setup.py build -c mingw32 install
-
-It might be possible that distutils will complain about missing gcc executable.
-That means you have to add mingw bin PATH variable first.
-Entering this line in the command prompt should do the work:
-
- > SET PATH=C:\MinGW\bin;%PATH%
-
-NOTE: this assumes MinGW is installed in C:\MinGW, if not simply replace the
-path in the command above with an appropriate location.
-
-[1] http://www.mingw.org/
-
-NOTE #2: as of right now all Windows functionnalities are written in pure C
-and no third party modules are required to be installed with the exception of
-the "username" functionnality which requires pywin32 extension to be installed
-separately.
-
-
-Installing on Windows using Visual Studio
-=========================================
-
-To use Visual Studio to install psutil, you must have the same version of
-Visual Studio used to compile your installation of Python. For older versions
-of Python that will be Visual Studio 2003. For 2.6 and later it should be
-Visual Studio 2008. If you do not have the requisite version of Visual Studio
-available then it is recommended to use MinGW to compile psutil instead.
-
-If you do have Visual Studio installed, you can use the basic distutils
-commands:
-
- > setup.py build
-
-or to install and build:
-
- > setup.py install
-
-distutils should take care of any necessary magic to compile from there.
-
-
-Installing on OS X
-==================
-
-OS X installation from source will require gcc which you can obtain as part of
-the 'XcodeTools' installer from Apple. Then you can run the standard distutils
-commands:
-
-to build only:
-
- > ./setup.py build
-
-to install and build:
-
- > ./setup.py install
-
-NOTE: due to developer's hardware limitations psutil has only been compiled and
-tested on OS X 10.4.11 so may or may not work on other versions.
-
-
-Installing on FreeBSD
-=====================
-
-The same compiler used to install Python must be present on the system in order
-to build modules using distutils. Assuming it is installed, you can build using
-the standard distutils commands:
-
-build only:
-
- > ./setup.py build
-
-install and build:
-
- > ./setup.py install
-
-
-Installing on Linux
-===================
-
-Standard distutils installation steps should apply here. At the current time
-the Linux port of psutil does not require any C modules, so can be installed
-without need for a compiler using disutils:
-
-install/build:
-
- > ./setup.py install
+
+Introduction
+============
+
+psutil is a module providing an interface for retrieving information on running
+processes in a portable way by using Python.
+It currently supports Linux, OS X, FreeBSD and Windows.
+
+psutil website is at http://code.google.com/p/psutil/
+
+The following document describes how to compile and install psutil from sources
+on different platforms.
+
+
+Using easy_install
+==================
+
+The easiest way to install psutil from sources is using easy_install.
+Get the latest easy_install version from http://pypi.python.org/pypi/setuptools
+and just run:
+
+ > python easy_install psutil
+
+This should get the most updated psutil version from the Python pypi repository,
+unpack it, compile it and install it automatically.
+
+
+Installing on Windows using mingw32
+===================================
+
+After the mingw [1] environment is properly set up on your system you can
+compile Windows sources by entering:
+
+ > setup.py build -c mingw32
+
+To compile and install just append the "install" keyword at the end of the
+command line above, like this:
+
+ > setup.py build -c mingw32 install
+
+It might be possible that distutils will complain about missing gcc executable.
+That means you have to add mingw bin PATH variable first.
+Entering this line in the command prompt should do the work:
+
+ > SET PATH=C:\MinGW\bin;%PATH%
+
+NOTE: this assumes MinGW is installed in C:\MinGW, if not simply replace the
+path in the command above with an appropriate location.
+
+[1] http://www.mingw.org/
+
+NOTE #2: as of right now all Windows functionnalities are written in pure C
+and no third party modules are required to be installed with the exception of
+the "username" functionnality which requires pywin32 extension to be installed
+separately.
+
+
+Installing on Windows using Visual Studio
+=========================================
+
+To use Visual Studio to install psutil, you must have the same version of
+Visual Studio used to compile your installation of Python. For older versions
+of Python that will be Visual Studio 2003. For 2.6 and later it should be
+Visual Studio 2008. If you do not have the requisite version of Visual Studio
+available then it is recommended to use MinGW to compile psutil instead.
+
+If you do have Visual Studio installed, you can use the basic distutils
+commands:
+
+ > setup.py build
+
+or to install and build:
+
+ > setup.py install
+
+distutils should take care of any necessary magic to compile from there.
+
+
+Installing on OS X
+==================
+
+OS X installation from source will require gcc which you can obtain as part of
+the 'XcodeTools' installer from Apple. Then you can run the standard distutils
+commands:
+
+to build only:
+
+ > ./setup.py build
+
+to install and build:
+
+ > ./setup.py install
+
+NOTE: due to developer's hardware limitations psutil has only been compiled and
+tested on OS X 10.4.11 so may or may not work on other versions.
+
+
+Installing on FreeBSD
+=====================
+
+The same compiler used to install Python must be present on the system in order
+to build modules using distutils. Assuming it is installed, you can build using
+the standard distutils commands:
+
+build only:
+
+ > ./setup.py build
+
+install and build:
+
+ > ./setup.py install
+
+
+Installing on Linux
+===================
+
+Standard distutils installation steps should apply here. At the current time
+the Linux port of psutil does not require any C modules, so can be installed
+without need for a compiler using disutils:
+
+install/build:
+
+ > ./setup.py install
diff --git a/docs/class_diagram.png b/docs/class_diagram.png
index 7c64d3f2..2dc22a72 100755
--- a/docs/class_diagram.png
+++ b/docs/class_diagram.png
Binary files differ
diff --git a/docs/documentation.html b/docs/documentation.html
index e2c80b2a..f3d9d8d3 100644
--- a/docs/documentation.html
+++ b/docs/documentation.html
@@ -1,141 +1,141 @@
-<html><head>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-
-
-
-
-
- <title>psutil - Documentation</title>
- </head><body>
-
-
-
-
- <div id="wikicontent">
- <table border="0" cellpadding="0" cellspacing="0" width="100%">
- <tbody><tr>
-
- <td class="vt" id="wikimaincol" width="100%">
-
- <div id="wikiheader" style="margin-bottom: 1em;">
-
- <span style="font-size: 120%; font-weight: bold;">Documentation</span>
- &nbsp;
-
-
- <div style="font-style: italic; margin-top: 3px;">API reference</div>
-
- </div>
- <h1><a name="API_Reference">API Reference</a></h1><h2><a
-name="Exceptions">Exceptions</a></h2><p><a name="Exceptions">psutil.<strong>NoSuchProcess</strong></a><strong></strong><br>
- </p><blockquote>Raised when no process with the given PID/parameter was
- found in the current process list.
-</blockquote><p></p><p>psutil.<strong>AccessDenied</strong><br>
- </p><blockquote>Exception raised when permission to perform an action
-is denied.
-</blockquote><p></p><hr><h2><a name="Classes">Classes</a></h2><p><a
-name="Classes">psutil.<strong>Process(</strong><i>pid</i><strong>)</strong>
- </a></p><blockquote><a name="Classes">A class which represents an OS
-process.
-</a></blockquote><ul><li><a name="Classes"><strong>pid</strong><br>The
-process pid. </a></li></ul><ul><li><a name="Classes"><strong>ppid</strong><br>The
- process parent pid. </a></li></ul><ul><li><a name="Classes"><strong>parent</strong><br>Return
- the parent process as a <tt>Process</tt> object. If no ppid is known
-then return <tt>None</tt>. </a></li></ul><ul><li><a name="Classes"><strong>name</strong><br>The
- process name. </a></li></ul><ul><li><a name="Classes"><strong>path</strong><br>The
- process path. </a></li></ul><ul><li><a name="Classes"><strong>cmdline</strong><br>The
- command line process has been called with. </a></li></ul><ul><li><a
-name="Classes"><strong>create_time</strong><br> The process creation
-time as a floating point number expressed in seconds since the epoch, in
- UTC. </a></li></ul><ul><li><a name="Classes"><strong>uid</strong><br>The
- real user id of the current process. Where uid doesn't make sense (<i>Windows</i>)
- always return <tt>-1</tt>. </a></li></ul><ul><li><a name="Classes"><strong>gid</strong><br>The
- real group id of the current process. Where gid doesn't make sense (<i>Windows</i>)
- always return <tt>-1</tt>. </a></li></ul><ul><li><a name="Classes"><strong>username</strong><br>The
- name of the user that owns the process. </a></li></ul><blockquote><a
-name="Classes"><i>New in 0.1.3</i>
-</a></blockquote><ul><li><a name="Classes"><strong>getcwd()</strong><br>Return
- a string representing the process current working directory. </a></li></ul><blockquote><a
- name="Classes"><i>New in 0.1.3 - Availability <strong>Windows, Linux</strong></i>
-
-</a></blockquote><ul><li><a name="Classes"><strong>get_cpu_times()</strong><br>Return
- a tuple whose values are process CPU user and system times which means
-the amount of time expressed in seconds that a process has spent in
-user/system mode. </a></li></ul><ul><li><a name="Classes"><strong>get_cpu_percent()</strong><br>Compare
- process times to system time elapsed since last call and calculate CPU
-utilization as a percentage. It is recommended for accuracy that this
-function be called with at least 1 second between calls. The initial
-delta is calculated from the instantiation of the Process object. </a></li></ul><ul><li><a
- name="Classes"><strong>get_memory_info()</strong><br>Return a tuple
-representing RSS (Resident Set Size) and VMS (Virtual Memory Size) in
-bytes.<br>On UNIX RSS and VMS are the same values shown by ps. On
-Windows RSS and VMS refer to "Mem Usage" and "VM Size" columns of
-taskmgr.exe. </a></li></ul><ul><li><a name="Classes"><strong>get_memory_percent()</strong><br>Compare
- physical system memory to process resident memory and calculate process
- memory utilization as a percentage. </a></li></ul><ul><li><a
-name="Classes"><strong>is_running()</strong><br>Return whether the
-current process is running in the current process list. </a></li></ul><ul><li><a
- name="Classes"><strong>suspend()</strong><br>Suspend process execution.
- </a></li></ul><blockquote><a name="Classes"><i>New in 0.1.3</i>
-</a></blockquote><ul><li><a name="Classes"><strong>resume()</strong><br>Resume
- process execution. </a></li></ul><blockquote><a name="Classes"><i>New
-in 0.1.3</i>
-</a></blockquote><ul><li><a name="Classes"><strong>kill([</strong><i><tt>sig</tt></i><strong>])</strong><br>Kill
- the current process by using signal <i>sig</i> (defaults to SIGKILL). </a></li></ul><hr><h2><a
- name="Functions">Functions</a></h2><p><a name="Functions">psutil.<strong>get_pid_list()</strong><br>
- </a></p><blockquote><a name="Functions">Return a list of current
-running PIDs.
-</a></blockquote><p></p><p><a name="Functions">psutil.<strong>pid_exists(</strong><i>pid</i><strong>)</strong><br>
- </a></p><blockquote><a name="Functions">Check whether the given PID
-exists in the current process list.
-</a></blockquote><p></p><p><a name="Functions">psutil.<strong>process_iter()</strong><br>
- </a></p><blockquote><a name="Functions">Return an iterator yielding a
-Process class instances for all running processes on the local machine.
-</a></blockquote><p></p><hr><h2><a name="System_related_objects">System
-related objects</a></h2><p><a name="System_related_objects">psutil.<strong>cpu_percent()</strong>
- </a></p><blockquote><a name="System_related_objects">Return the current
- system-wide CPU utilization as a percentage. For highest accuracy, it
-is recommended that this be called at least 1/10th of a second after
-importing the module or calling cpu_percent() in a previous call, to
-allow for a larger time delta from which to calculate the percentage
-value.
-</a></blockquote><p></p><p><a name="System_related_objects">psutil.<strong>cpu_times()</strong>
- </a></p><blockquote><a name="System_related_objects">Return system CPU
-times as a <tt>CPUTimes</tt> class object. Every CPU time is accessible
-in form of a <tt>CPUTimes</tt> attribute and represents the time CPU has
- spent in the given mode.<br>The attributes availability varies
-depending on the platform. Here follows a list of all available
-attributes:
-</a></blockquote><p></p><blockquote><a name="System_related_objects">- <strong>user</strong><br>
-
-- <strong>system</strong><br>
-- <strong>idle</strong><br>
-- <strong>nice</strong> <i>(UNIX)</i><br>
-- <strong>iowait</strong> <i>(Linux)</i><br>
-- <strong>irq</strong> <i>(Linux, FreeBSD)</i><br>
-- <strong>softirq</strong> <i>(Linux)</i><br>
-</a></blockquote><p><a name="System_related_objects">psutil.<strong>TOTAL_PHYMEM</strong><br>
- psutil.<strong>avail_phymem()</strong><br> psutil.<strong>used_phymem()</strong><br>
- </a></p><blockquote><a name="System_related_objects">Return the amount
-of total, available and used physical memory on the system, in bytes.
-</a></blockquote><p></p><p><a name="System_related_objects">psutil.<strong>total_virtmem()</strong><br>
- psutil.<strong>avail_virtmem()</strong><br> psutil.<strong>used_virtmem()</strong><br>
- </a></p><blockquote><a name="System_related_objects">Return the amount
-of total, available and used virtual memory on the system, in bytes.<br>On
- Linux they match the values returned by <tt>free</tt> command line
-utility. On OS X and FreeBSD they represent the same values as returned
-by <tt>sysctl vm.vmtotal</tt>. On Windows they are determined by reading
- the <tt>*PageFile</tt> values of </a><a
-href="http://msdn.microsoft.com/en-us/library/aa366770%28VS.85%29.aspx"
-rel="nofollow">MEMORYSTATUSEX</a> structure.
-</blockquote><p></p>
- </td>
- </tr>
- </tbody></table>
- </div>
-
-
-
-
-
- </body></html> \ No newline at end of file
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+
+
+
+
+
+ <title>psutil - Documentation</title>
+ </head><body>
+
+
+
+
+ <div id="wikicontent">
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
+ <tbody><tr>
+
+ <td class="vt" id="wikimaincol" width="100%">
+
+ <div id="wikiheader" style="margin-bottom: 1em;">
+
+ <span style="font-size: 120%; font-weight: bold;">Documentation</span>
+ &nbsp;
+
+
+ <div style="font-style: italic; margin-top: 3px;">API reference</div>
+
+ </div>
+ <h1><a name="API_Reference">API Reference</a></h1><h2><a
+name="Exceptions">Exceptions</a></h2><p><a name="Exceptions">psutil.<strong>NoSuchProcess</strong></a><strong></strong><br>
+ </p><blockquote>Raised when no process with the given PID/parameter was
+ found in the current process list.
+</blockquote><p></p><p>psutil.<strong>AccessDenied</strong><br>
+ </p><blockquote>Exception raised when permission to perform an action
+is denied.
+</blockquote><p></p><hr><h2><a name="Classes">Classes</a></h2><p><a
+name="Classes">psutil.<strong>Process(</strong><i>pid</i><strong>)</strong>
+ </a></p><blockquote><a name="Classes">A class which represents an OS
+process.
+</a></blockquote><ul><li><a name="Classes"><strong>pid</strong><br>The
+process pid. </a></li></ul><ul><li><a name="Classes"><strong>ppid</strong><br>The
+ process parent pid. </a></li></ul><ul><li><a name="Classes"><strong>parent</strong><br>Return
+ the parent process as a <tt>Process</tt> object. If no ppid is known
+then return <tt>None</tt>. </a></li></ul><ul><li><a name="Classes"><strong>name</strong><br>The
+ process name. </a></li></ul><ul><li><a name="Classes"><strong>path</strong><br>The
+ process path. </a></li></ul><ul><li><a name="Classes"><strong>cmdline</strong><br>The
+ command line process has been called with. </a></li></ul><ul><li><a
+name="Classes"><strong>create_time</strong><br> The process creation
+time as a floating point number expressed in seconds since the epoch, in
+ UTC. </a></li></ul><ul><li><a name="Classes"><strong>uid</strong><br>The
+ real user id of the current process. Where uid doesn't make sense (<i>Windows</i>)
+ always return <tt>-1</tt>. </a></li></ul><ul><li><a name="Classes"><strong>gid</strong><br>The
+ real group id of the current process. Where gid doesn't make sense (<i>Windows</i>)
+ always return <tt>-1</tt>. </a></li></ul><ul><li><a name="Classes"><strong>username</strong><br>The
+ name of the user that owns the process. </a></li></ul><blockquote><a
+name="Classes"><i>New in 0.1.3</i>
+</a></blockquote><ul><li><a name="Classes"><strong>getcwd()</strong><br>Return
+ a string representing the process current working directory. </a></li></ul><blockquote><a
+ name="Classes"><i>New in 0.1.3 - Availability <strong>Windows, Linux</strong></i>
+
+</a></blockquote><ul><li><a name="Classes"><strong>get_cpu_times()</strong><br>Return
+ a tuple whose values are process CPU user and system times which means
+the amount of time expressed in seconds that a process has spent in
+user/system mode. </a></li></ul><ul><li><a name="Classes"><strong>get_cpu_percent()</strong><br>Compare
+ process times to system time elapsed since last call and calculate CPU
+utilization as a percentage. It is recommended for accuracy that this
+function be called with at least 1 second between calls. The initial
+delta is calculated from the instantiation of the Process object. </a></li></ul><ul><li><a
+ name="Classes"><strong>get_memory_info()</strong><br>Return a tuple
+representing RSS (Resident Set Size) and VMS (Virtual Memory Size) in
+bytes.<br>On UNIX RSS and VMS are the same values shown by ps. On
+Windows RSS and VMS refer to "Mem Usage" and "VM Size" columns of
+taskmgr.exe. </a></li></ul><ul><li><a name="Classes"><strong>get_memory_percent()</strong><br>Compare
+ physical system memory to process resident memory and calculate process
+ memory utilization as a percentage. </a></li></ul><ul><li><a
+name="Classes"><strong>is_running()</strong><br>Return whether the
+current process is running in the current process list. </a></li></ul><ul><li><a
+ name="Classes"><strong>suspend()</strong><br>Suspend process execution.
+ </a></li></ul><blockquote><a name="Classes"><i>New in 0.1.3</i>
+</a></blockquote><ul><li><a name="Classes"><strong>resume()</strong><br>Resume
+ process execution. </a></li></ul><blockquote><a name="Classes"><i>New
+in 0.1.3</i>
+</a></blockquote><ul><li><a name="Classes"><strong>kill([</strong><i><tt>sig</tt></i><strong>])</strong><br>Kill
+ the current process by using signal <i>sig</i> (defaults to SIGKILL). </a></li></ul><hr><h2><a
+ name="Functions">Functions</a></h2><p><a name="Functions">psutil.<strong>get_pid_list()</strong><br>
+ </a></p><blockquote><a name="Functions">Return a list of current
+running PIDs.
+</a></blockquote><p></p><p><a name="Functions">psutil.<strong>pid_exists(</strong><i>pid</i><strong>)</strong><br>
+ </a></p><blockquote><a name="Functions">Check whether the given PID
+exists in the current process list.
+</a></blockquote><p></p><p><a name="Functions">psutil.<strong>process_iter()</strong><br>
+ </a></p><blockquote><a name="Functions">Return an iterator yielding a
+Process class instances for all running processes on the local machine.
+</a></blockquote><p></p><hr><h2><a name="System_related_objects">System
+related objects</a></h2><p><a name="System_related_objects">psutil.<strong>cpu_percent()</strong>
+ </a></p><blockquote><a name="System_related_objects">Return the current
+ system-wide CPU utilization as a percentage. For highest accuracy, it
+is recommended that this be called at least 1/10th of a second after
+importing the module or calling cpu_percent() in a previous call, to
+allow for a larger time delta from which to calculate the percentage
+value.
+</a></blockquote><p></p><p><a name="System_related_objects">psutil.<strong>cpu_times()</strong>
+ </a></p><blockquote><a name="System_related_objects">Return system CPU
+times as a <tt>CPUTimes</tt> class object. Every CPU time is accessible
+in form of a <tt>CPUTimes</tt> attribute and represents the time CPU has
+ spent in the given mode.<br>The attributes availability varies
+depending on the platform. Here follows a list of all available
+attributes:
+</a></blockquote><p></p><blockquote><a name="System_related_objects">- <strong>user</strong><br>
+
+- <strong>system</strong><br>
+- <strong>idle</strong><br>
+- <strong>nice</strong> <i>(UNIX)</i><br>
+- <strong>iowait</strong> <i>(Linux)</i><br>
+- <strong>irq</strong> <i>(Linux, FreeBSD)</i><br>
+- <strong>softirq</strong> <i>(Linux)</i><br>
+</a></blockquote><p><a name="System_related_objects">psutil.<strong>TOTAL_PHYMEM</strong><br>
+ psutil.<strong>avail_phymem()</strong><br> psutil.<strong>used_phymem()</strong><br>
+ </a></p><blockquote><a name="System_related_objects">Return the amount
+of total, available and used physical memory on the system, in bytes.
+</a></blockquote><p></p><p><a name="System_related_objects">psutil.<strong>total_virtmem()</strong><br>
+ psutil.<strong>avail_virtmem()</strong><br> psutil.<strong>used_virtmem()</strong><br>
+ </a></p><blockquote><a name="System_related_objects">Return the amount
+of total, available and used virtual memory on the system, in bytes.<br>On
+ Linux they match the values returned by <tt>free</tt> command line
+utility. On OS X and FreeBSD they represent the same values as returned
+by <tt>sysctl vm.vmtotal</tt>. On Windows they are determined by reading
+ the <tt>*PageFile</tt> values of </a><a
+href="http://msdn.microsoft.com/en-us/library/aa366770%28VS.85%29.aspx"
+rel="nofollow">MEMORYSTATUSEX</a> structure.
+</blockquote><p></p>
+ </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+
+
+
+ </body></html>
diff --git a/docs/index.html b/docs/index.html
index 10a716e5..1742d9c9 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,26 +1,26 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
-<title>psutil - Home</title>
-</head>
-
-<body>
-<div id="wikicontent">
- <h1>Python process utilities (psutil)</h1>
- <h1><a name="Summary" id="Summary">Summary</a></h1>
- <p><a name="Summary" id="Summary">psutil is a module providing an interface for retrieving information on running processes and system utilization (CPU, memory) in a portable way by using Python. </a></p>
- <p><a name="Summary" id="Summary">It currently supports Linux, OS X, FreeBSD and Windows. </a></p>
- <h1><a name="Example_usage" id="Example_usage">Example usage</a></h1>
- <pre><a name="Example_usage" id="Example_usage">&gt;&gt;&gt; import psutil<br />&gt;&gt;&gt; psutil.get_pid_list()<br />[1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224,<br />268, 1215, 1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355,<br />2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, <br />4263, 4282, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358, <br />4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446, 5167, 5234, 5235, <br />5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]<br />&gt;&gt;&gt; p = psutil.Process(7055)<br />&gt;&gt;&gt; p.name<br />'python'<br />&gt;&gt;&gt; p.path<br />'/usr/bin'<br />&gt;&gt;&gt; p.cmdline<br />['/usr/bin/python', '-O']<br />&gt;&gt;&gt; p.uid<br />1000<br />&gt;&gt;&gt; p.gid<br />1000<br />&gt;&gt;&gt; rss, vms = &nbsp;p.get_memory_info()<br />&gt;&gt;&gt; print &quot;Resident memory: %s KB&quot; %(rss / 1024)<br />Resident memory: 3768 KB<br />&gt;&gt;&gt; print &quot;Virtual memory: %s KB&quot; %(vms / 1024)<br />Virtual memory: 6176 KB<br />&gt;&gt;&gt; <br />&gt;&gt;&gt; psutil.test()<br />UID &nbsp; &nbsp; &nbsp; PID %CPU %MEM &nbsp; &nbsp; VSZ &nbsp; &nbsp; RSS START &nbsp; &nbsp; TIME COMMAND<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [sched]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1740 &nbsp; &nbsp; 600 Mar20 &nbsp; &nbsp;00:04 /sbin/init<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kthreadd]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [migration/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:05 [ksoftirqd/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [watchdog/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:03 [events/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [khelper]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;46 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kintegrityd/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;48 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:01 [kblockd/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;50 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kacpid]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;51 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kacpi_notify]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 179 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [cqueue]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 183 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kseriod]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 223 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [pdflush]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 224 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:04 [pdflush]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 225 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:01 [kswapd0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 269 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [aio/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1221 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [ksuspend_usbd]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1222 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [khubd]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1226 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [ata/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1227 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [ata_aux]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1245 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:04 [mpt_poll_0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1402 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [scsi_eh_0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1843 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [scsi_eh_1]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1844 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [scsi_eh_2]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;2241 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:06 [kjournald]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;2359 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;2312 &nbsp; &nbsp; 740 Mar20 &nbsp; &nbsp;00:02 /sbin/udevd --daemon<br />0 &nbsp; &nbsp; &nbsp; &nbsp;2678 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kgameportd]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;2796 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kpsmoused]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4209 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 536 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty4<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4210 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 536 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty5<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4215 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 540 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty2<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4216 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 540 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty3<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4217 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 540 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty6<br />101 &nbsp; &nbsp; &nbsp;4258 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;2012 &nbsp; &nbsp; 712 Mar20 &nbsp; &nbsp;00:01 /sbin/syslogd -u syslog<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4276 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;1936 &nbsp; &nbsp; 544 Mar20 &nbsp; &nbsp;00:00 /bin/dd bs 1 if /proc/kmsg of /var/run/klogd/kmsg<br />102 &nbsp; &nbsp; &nbsp;4278 &nbsp;0.0 &nbsp;0.7 &nbsp; &nbsp;3508 &nbsp; &nbsp;2248 Mar20 &nbsp; &nbsp;00:00 /sbin/klogd -P /var/run/klogd/kmsg<br />104 &nbsp; &nbsp; &nbsp;4296 &nbsp;0.0 &nbsp;0.5 &nbsp; &nbsp;2640 &nbsp; &nbsp; 844 Mar20 &nbsp; &nbsp;00:02 /bin/dbus-daemon --system<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4315 &nbsp;0.0 &nbsp;1.0 &nbsp; &nbsp;5392 &nbsp; &nbsp;1060 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/sshd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4349 &nbsp;0.0 &nbsp;1.8 &nbsp; &nbsp;9216 &nbsp; &nbsp;1464 Mar20 &nbsp; &nbsp;00:01 /usr/sbin/winbindd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4363 &nbsp;0.0 &nbsp;1.8 &nbsp; &nbsp;9472 &nbsp; &nbsp;2000 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/winbindd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4364 &nbsp;0.0 &nbsp;1.8 &nbsp; &nbsp;9216 &nbsp; &nbsp;1012 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/winbindd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4365 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;2064 &nbsp; &nbsp; 452 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/atd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4390 &nbsp;0.0 &nbsp;0.7 &nbsp; &nbsp;3408 &nbsp; &nbsp;1016 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/cron<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4400 &nbsp;0.0 &nbsp;1.6 &nbsp; &nbsp;8128 &nbsp; &nbsp;3212 Mar20 &nbsp; &nbsp;00:00 /bin/login --<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4402 &nbsp;0.0 &nbsp;1.8 &nbsp; &nbsp;9216 &nbsp; &nbsp;1108 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/winbindd<br />1000 &nbsp; &nbsp; 5213 &nbsp;0.0 &nbsp;1.1 &nbsp; &nbsp;5656 &nbsp; &nbsp;3032 Mar20 &nbsp; &nbsp;00:00 -bash<br />0 &nbsp; &nbsp; &nbsp; &nbsp;5232 &nbsp;0.0 &nbsp;1.6 &nbsp; &nbsp;8144 &nbsp; &nbsp;2316 Mar20 &nbsp; &nbsp;00:00 su -<br />0 &nbsp; &nbsp; &nbsp; &nbsp;5298 &nbsp;0.0 &nbsp;0.8 &nbsp; &nbsp;4220 &nbsp; &nbsp;1832 Mar20 &nbsp; &nbsp;00:00 -su<br />0 &nbsp; &nbsp; &nbsp; &nbsp;5342 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;2252 &nbsp; &nbsp; 644 Mar20 &nbsp; &nbsp;00:00 dhclient<br />0 &nbsp; &nbsp; &nbsp; 13234 &nbsp;0.0 &nbsp;1.6 &nbsp; &nbsp;8120 &nbsp; &nbsp;1580 00:38 &nbsp; &nbsp;00:02 /usr/sbin/nmbd -D<br />0 &nbsp; &nbsp; &nbsp; 13236 &nbsp;0.0 &nbsp;2.6 &nbsp; 13604 &nbsp; &nbsp;2816 00:38 &nbsp; &nbsp;00:00 /usr/sbin/smbd -D<br />0 &nbsp; &nbsp; &nbsp; 13239 &nbsp;0.0 &nbsp;2.6 &nbsp; 13604 &nbsp; &nbsp;1044 00:38 &nbsp; &nbsp;00:00 /usr/sbin/smbd -D<br />0 &nbsp; &nbsp; &nbsp; 23643 &nbsp;0.0 &nbsp;2.4 &nbsp; 12376 &nbsp; &nbsp;4280 14:43 &nbsp; &nbsp;00:00 sshd: user [priv]<br />1000 &nbsp; &nbsp;23648 &nbsp;0.0 &nbsp;2.4 &nbsp; 12512 &nbsp; &nbsp;2008 14:43 &nbsp; &nbsp;00:06 sshd: user@pts/2<br />1000 &nbsp; &nbsp;23649 &nbsp;0.0 &nbsp;1.2 &nbsp; &nbsp;5944 &nbsp; &nbsp;3340 14:43 &nbsp; &nbsp;00:00 -bash<br />0 &nbsp; &nbsp; &nbsp; 25860 &nbsp;0.0 &nbsp;1.6 &nbsp; &nbsp;8144 &nbsp; &nbsp;2300 17:55 &nbsp; &nbsp;00:00 su -<br />0 &nbsp; &nbsp; &nbsp; 25926 &nbsp;0.0 &nbsp;1.1 &nbsp; &nbsp;5432 &nbsp; &nbsp;3072 17:55 &nbsp; &nbsp;00:00 -su<br />1000 &nbsp; &nbsp;28464 &nbsp;0.0 &nbsp;2.7 &nbsp; 13968 &nbsp; &nbsp;4076 21:45 &nbsp; &nbsp;00:00 /usr/sbin/smbd -D<br />0 &nbsp; &nbsp; &nbsp; 28655 &nbsp;0.0 &nbsp;1.0 &nbsp; &nbsp;4932 &nbsp; &nbsp;3204 21:58 &nbsp; &nbsp;00:00 python _psutil.py<br />&gt;&gt;&gt;<br /></a></pre>
- <h1><a name="Mailing_lists" id="Mailing_lists">Mailing lists</a></h1>
- <p><a name="Mailing_lists" id="Mailing_lists"><strong>Users</strong><br />
- </a><a href="http://groups.google.com/group/psutil/topics" rel="nofollow">http://groups.google.com/group/psutil/topics</a></p>
- <p><strong>Developers</strong><br />
- <a href="http://groups.google.com/group/psutil-dev/topics" rel="nofollow">http://groups.google.com/group/psutil-dev/topics</a></p>
- <p><strong>SVN commits and issue tracker changes</strong><br />
- <a href="http://groups.google.com/group/psutil-commits/topics" rel="nofollow">http://groups.google.com/group/psutil-commits/topics</a></p>
- <p>&nbsp;</p>
-</div>
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title>psutil - Home</title>
+</head>
+
+<body>
+<div id="wikicontent">
+ <h1>Python process utilities (psutil)</h1>
+ <h1><a name="Summary" id="Summary">Summary</a></h1>
+ <p><a name="Summary" id="Summary">psutil is a module providing an interface for retrieving information on running processes and system utilization (CPU, memory) in a portable way by using Python. </a></p>
+ <p><a name="Summary" id="Summary">It currently supports Linux, OS X, FreeBSD and Windows. </a></p>
+ <h1><a name="Example_usage" id="Example_usage">Example usage</a></h1>
+ <pre><a name="Example_usage" id="Example_usage">&gt;&gt;&gt; import psutil<br />&gt;&gt;&gt; psutil.get_pid_list()<br />[1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224,<br />268, 1215, 1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355,<br />2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, <br />4263, 4282, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358, <br />4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446, 5167, 5234, 5235, <br />5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]<br />&gt;&gt;&gt; p = psutil.Process(7055)<br />&gt;&gt;&gt; p.name<br />'python'<br />&gt;&gt;&gt; p.path<br />'/usr/bin'<br />&gt;&gt;&gt; p.cmdline<br />['/usr/bin/python', '-O']<br />&gt;&gt;&gt; p.uid<br />1000<br />&gt;&gt;&gt; p.gid<br />1000<br />&gt;&gt;&gt; rss, vms = &nbsp;p.get_memory_info()<br />&gt;&gt;&gt; print &quot;Resident memory: %s KB&quot; %(rss / 1024)<br />Resident memory: 3768 KB<br />&gt;&gt;&gt; print &quot;Virtual memory: %s KB&quot; %(vms / 1024)<br />Virtual memory: 6176 KB<br />&gt;&gt;&gt; <br />&gt;&gt;&gt; psutil.test()<br />UID &nbsp; &nbsp; &nbsp; PID %CPU %MEM &nbsp; &nbsp; VSZ &nbsp; &nbsp; RSS START &nbsp; &nbsp; TIME COMMAND<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [sched]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1740 &nbsp; &nbsp; 600 Mar20 &nbsp; &nbsp;00:04 /sbin/init<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kthreadd]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [migration/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:05 [ksoftirqd/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [watchdog/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:03 [events/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [khelper]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;46 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kintegrityd/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;48 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:01 [kblockd/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;50 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kacpid]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;51 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kacpi_notify]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 179 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [cqueue]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 183 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kseriod]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 223 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [pdflush]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 224 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:04 [pdflush]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 225 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:01 [kswapd0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp; 269 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [aio/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1221 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [ksuspend_usbd]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1222 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [khubd]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1226 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [ata/0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1227 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [ata_aux]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1245 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:04 [mpt_poll_0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1402 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [scsi_eh_0]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1843 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [scsi_eh_1]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;1844 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [scsi_eh_2]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;2241 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:06 [kjournald]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;2359 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;2312 &nbsp; &nbsp; 740 Mar20 &nbsp; &nbsp;00:02 /sbin/udevd --daemon<br />0 &nbsp; &nbsp; &nbsp; &nbsp;2678 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kgameportd]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;2796 &nbsp;0.0 &nbsp;0.0 &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; 0 Mar20 &nbsp; &nbsp;00:00 [kpsmoused]<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4209 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 536 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty4<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4210 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 536 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty5<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4215 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 540 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty2<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4216 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 540 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty3<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4217 &nbsp;0.0 &nbsp;0.3 &nbsp; &nbsp;1780 &nbsp; &nbsp; 540 Mar20 &nbsp; &nbsp;00:00 /sbin/getty 38400 tty6<br />101 &nbsp; &nbsp; &nbsp;4258 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;2012 &nbsp; &nbsp; 712 Mar20 &nbsp; &nbsp;00:01 /sbin/syslogd -u syslog<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4276 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;1936 &nbsp; &nbsp; 544 Mar20 &nbsp; &nbsp;00:00 /bin/dd bs 1 if /proc/kmsg of /var/run/klogd/kmsg<br />102 &nbsp; &nbsp; &nbsp;4278 &nbsp;0.0 &nbsp;0.7 &nbsp; &nbsp;3508 &nbsp; &nbsp;2248 Mar20 &nbsp; &nbsp;00:00 /sbin/klogd -P /var/run/klogd/kmsg<br />104 &nbsp; &nbsp; &nbsp;4296 &nbsp;0.0 &nbsp;0.5 &nbsp; &nbsp;2640 &nbsp; &nbsp; 844 Mar20 &nbsp; &nbsp;00:02 /bin/dbus-daemon --system<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4315 &nbsp;0.0 &nbsp;1.0 &nbsp; &nbsp;5392 &nbsp; &nbsp;1060 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/sshd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4349 &nbsp;0.0 &nbsp;1.8 &nbsp; &nbsp;9216 &nbsp; &nbsp;1464 Mar20 &nbsp; &nbsp;00:01 /usr/sbin/winbindd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4363 &nbsp;0.0 &nbsp;1.8 &nbsp; &nbsp;9472 &nbsp; &nbsp;2000 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/winbindd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4364 &nbsp;0.0 &nbsp;1.8 &nbsp; &nbsp;9216 &nbsp; &nbsp;1012 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/winbindd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4365 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;2064 &nbsp; &nbsp; 452 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/atd<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4390 &nbsp;0.0 &nbsp;0.7 &nbsp; &nbsp;3408 &nbsp; &nbsp;1016 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/cron<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4400 &nbsp;0.0 &nbsp;1.6 &nbsp; &nbsp;8128 &nbsp; &nbsp;3212 Mar20 &nbsp; &nbsp;00:00 /bin/login --<br />0 &nbsp; &nbsp; &nbsp; &nbsp;4402 &nbsp;0.0 &nbsp;1.8 &nbsp; &nbsp;9216 &nbsp; &nbsp;1108 Mar20 &nbsp; &nbsp;00:00 /usr/sbin/winbindd<br />1000 &nbsp; &nbsp; 5213 &nbsp;0.0 &nbsp;1.1 &nbsp; &nbsp;5656 &nbsp; &nbsp;3032 Mar20 &nbsp; &nbsp;00:00 -bash<br />0 &nbsp; &nbsp; &nbsp; &nbsp;5232 &nbsp;0.0 &nbsp;1.6 &nbsp; &nbsp;8144 &nbsp; &nbsp;2316 Mar20 &nbsp; &nbsp;00:00 su -<br />0 &nbsp; &nbsp; &nbsp; &nbsp;5298 &nbsp;0.0 &nbsp;0.8 &nbsp; &nbsp;4220 &nbsp; &nbsp;1832 Mar20 &nbsp; &nbsp;00:00 -su<br />0 &nbsp; &nbsp; &nbsp; &nbsp;5342 &nbsp;0.0 &nbsp;0.4 &nbsp; &nbsp;2252 &nbsp; &nbsp; 644 Mar20 &nbsp; &nbsp;00:00 dhclient<br />0 &nbsp; &nbsp; &nbsp; 13234 &nbsp;0.0 &nbsp;1.6 &nbsp; &nbsp;8120 &nbsp; &nbsp;1580 00:38 &nbsp; &nbsp;00:02 /usr/sbin/nmbd -D<br />0 &nbsp; &nbsp; &nbsp; 13236 &nbsp;0.0 &nbsp;2.6 &nbsp; 13604 &nbsp; &nbsp;2816 00:38 &nbsp; &nbsp;00:00 /usr/sbin/smbd -D<br />0 &nbsp; &nbsp; &nbsp; 13239 &nbsp;0.0 &nbsp;2.6 &nbsp; 13604 &nbsp; &nbsp;1044 00:38 &nbsp; &nbsp;00:00 /usr/sbin/smbd -D<br />0 &nbsp; &nbsp; &nbsp; 23643 &nbsp;0.0 &nbsp;2.4 &nbsp; 12376 &nbsp; &nbsp;4280 14:43 &nbsp; &nbsp;00:00 sshd: user [priv]<br />1000 &nbsp; &nbsp;23648 &nbsp;0.0 &nbsp;2.4 &nbsp; 12512 &nbsp; &nbsp;2008 14:43 &nbsp; &nbsp;00:06 sshd: user@pts/2<br />1000 &nbsp; &nbsp;23649 &nbsp;0.0 &nbsp;1.2 &nbsp; &nbsp;5944 &nbsp; &nbsp;3340 14:43 &nbsp; &nbsp;00:00 -bash<br />0 &nbsp; &nbsp; &nbsp; 25860 &nbsp;0.0 &nbsp;1.6 &nbsp; &nbsp;8144 &nbsp; &nbsp;2300 17:55 &nbsp; &nbsp;00:00 su -<br />0 &nbsp; &nbsp; &nbsp; 25926 &nbsp;0.0 &nbsp;1.1 &nbsp; &nbsp;5432 &nbsp; &nbsp;3072 17:55 &nbsp; &nbsp;00:00 -su<br />1000 &nbsp; &nbsp;28464 &nbsp;0.0 &nbsp;2.7 &nbsp; 13968 &nbsp; &nbsp;4076 21:45 &nbsp; &nbsp;00:00 /usr/sbin/smbd -D<br />0 &nbsp; &nbsp; &nbsp; 28655 &nbsp;0.0 &nbsp;1.0 &nbsp; &nbsp;4932 &nbsp; &nbsp;3204 21:58 &nbsp; &nbsp;00:00 python _psutil.py<br />&gt;&gt;&gt;<br /></a></pre>
+ <h1><a name="Mailing_lists" id="Mailing_lists">Mailing lists</a></h1>
+ <p><a name="Mailing_lists" id="Mailing_lists"><strong>Users</strong><br />
+ </a><a href="http://groups.google.com/group/psutil/topics" rel="nofollow">http://groups.google.com/group/psutil/topics</a></p>
+ <p><strong>Developers</strong><br />
+ <a href="http://groups.google.com/group/psutil-dev/topics" rel="nofollow">http://groups.google.com/group/psutil-dev/topics</a></p>
+ <p><strong>SVN commits and issue tracker changes</strong><br />
+ <a href="http://groups.google.com/group/psutil-commits/topics" rel="nofollow">http://groups.google.com/group/psutil-commits/topics</a></p>
+ <p>&nbsp;</p>
+</div>
+</body>
+</html>
diff --git a/docs/milestones.lnk.html b/docs/milestones.lnk.html
index b8cbffa3..83904c8e 100644
--- a/docs/milestones.lnk.html
+++ b/docs/milestones.lnk.html
@@ -1,12 +1,12 @@
-<html>
-<head>
- <meta http-equiv="refresh" content="2; http://code.google.com/p/psutil/wiki/Milestones">
- <title>Redirecting to Milestones...</title>
-</head>
-
-<body>
-<p>Redirecting to: <a href="http://code.google.com/p/psutil/wiki/Milestones">http://code.google.com/p/psutil/wiki/Milestones</a><br></p>
-<p>You'll be redirected in 2 seconds...</p>
-
-</body>
-</html>
+<html>
+<head>
+ <meta http-equiv="refresh" content="2; http://code.google.com/p/psutil/wiki/Milestones">
+ <title>Redirecting to Milestones...</title>
+</head>
+
+<body>
+<p>Redirecting to: <a href="http://code.google.com/p/psutil/wiki/Milestones">http://code.google.com/p/psutil/wiki/Milestones</a><br></p>
+<p>You'll be redirected in 2 seconds...</p>
+
+</body>
+</html>
diff --git a/psutil/arch/mswindows/process_handles.c b/psutil/arch/mswindows/process_handles.c
index f5a50a93..ec9c6337 100644
--- a/psutil/arch/mswindows/process_handles.c
+++ b/psutil/arch/mswindows/process_handles.c
@@ -1,295 +1,295 @@
-#ifndef UNICODE
-#define UNICODE
-#endif
-
-#include <Python.h>
-#include <windows.h>
-#include <stdio.h>
-#include <Ntdef.h>
-#include "process_handles.h"
-
-#ifndef NT_SUCCESS
- #define NT_SUCCESS(x) ((x) >= 0)
-#endif
-#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
-
-#define SystemHandleInformation 16
-#define ObjectBasicInformation 0
-#define ObjectNameInformation 1
-#define ObjectTypeInformation 2
-
-typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
- ULONG SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength
- );
-
-typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
- HANDLE SourceProcessHandle,
- HANDLE SourceHandle,
- HANDLE TargetProcessHandle,
- PHANDLE TargetHandle,
- ACCESS_MASK DesiredAccess,
- ULONG Attributes,
- ULONG Options
- );
-
-typedef NTSTATUS (NTAPI *_NtQueryObject)(
- HANDLE ObjectHandle,
- ULONG ObjectInformationClass,
- PVOID ObjectInformation,
- ULONG ObjectInformationLength,
- PULONG ReturnLength
- );
-
-typedef struct _SYSTEM_HANDLE
-{
- ULONG ProcessId;
- BYTE ObjectTypeNumber;
- BYTE Flags;
- USHORT Handle;
- PVOID Object;
- ACCESS_MASK GrantedAccess;
-} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
-
-typedef struct _SYSTEM_HANDLE_INFORMATION
-{
- ULONG HandleCount;
- SYSTEM_HANDLE Handles[1];
-} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
-
-typedef enum _POOL_TYPE
-{
- NonPagedPool,
- PagedPool,
- NonPagedPoolMustSucceed,
- DontUseThisType,
- NonPagedPoolCacheAligned,
- PagedPoolCacheAligned,
- NonPagedPoolCacheAlignedMustS
-} POOL_TYPE, *PPOOL_TYPE;
-
-typedef struct _OBJECT_TYPE_INFORMATION
-{
- UNICODE_STRING Name;
- ULONG TotalNumberOfObjects;
- ULONG TotalNumberOfHandles;
- ULONG TotalPagedPoolUsage;
- ULONG TotalNonPagedPoolUsage;
- ULONG TotalNamePoolUsage;
- ULONG TotalHandleTableUsage;
- ULONG HighWaterNumberOfObjects;
- ULONG HighWaterNumberOfHandles;
- ULONG HighWaterPagedPoolUsage;
- ULONG HighWaterNonPagedPoolUsage;
- ULONG HighWaterNamePoolUsage;
- ULONG HighWaterHandleTableUsage;
- ULONG InvalidAttributes;
- GENERIC_MAPPING GenericMapping;
- ULONG ValidAccess;
- BOOLEAN SecurityRequired;
- BOOLEAN MaintainHandleCount;
- USHORT MaintainTypeList;
- POOL_TYPE PoolType;
- ULONG PagedPoolUsage;
- ULONG NonPagedPoolUsage;
-} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
-
-PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
-{
- return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
-}
-
-
-PyObject* get_open_files(long pid, HANDLE processHandle)
-{
- _NtQuerySystemInformation NtQuerySystemInformation =
- GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
- _NtDuplicateObject NtDuplicateObject =
- GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
- _NtQueryObject NtQueryObject =
- GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
-
- NTSTATUS status;
- PSYSTEM_HANDLE_INFORMATION handleInfo;
- ULONG handleInfoSize = 0x10000;
-
- ULONG i;
- ULONG fileNameLength;
- PyObject *filesList = Py_BuildValue("[]");
- PyObject *arg = NULL;
- PyObject *fileFromWchar = NULL;
-
-
-
- handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
-
- /* NtQuerySystemInformation won't give us the correct buffer size,
- so we guess by doubling the buffer size. */
- while ((status = NtQuerySystemInformation(
- SystemHandleInformation,
- handleInfo,
- handleInfoSize,
- NULL
- )) == STATUS_INFO_LENGTH_MISMATCH)
- handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
-
- /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
- if (!NT_SUCCESS(status)) {
- //printf("NtQuerySystemInformation failed!\n");
- return NULL;
- }
-
- for (i = 0; i < handleInfo->HandleCount; i++)
- {
- SYSTEM_HANDLE handle = handleInfo->Handles[i];
- HANDLE dupHandle = NULL;
- POBJECT_TYPE_INFORMATION objectTypeInfo;
- PVOID objectNameInfo;
- UNICODE_STRING objectName;
- ULONG returnLength;
-
- /* Check if this handle belongs to the PID the user specified. */
- if (handle.ProcessId != pid)
- continue;
-
- /* Duplicate the handle so we can query it. */
- if (!NT_SUCCESS(NtDuplicateObject(
- processHandle,
- handle.Handle,
- GetCurrentProcess(),
- &dupHandle,
- 0,
- 0,
- 0
- )))
- {
- //printf("[%#x] Error!\n", handle.Handle);
- continue;
- }
-
- /* Query the object type. */
- objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
- if (!NT_SUCCESS(NtQueryObject(
- dupHandle,
- ObjectTypeInformation,
- objectTypeInfo,
- 0x1000,
- NULL
- )))
- {
- //printf("[%#x] Error!\n", handle.Handle);
- CloseHandle(dupHandle);
- continue;
- }
-
- /* Query the object name (unless it has an access of
- 0x0012019f, on which NtQueryObject could hang. */
- if (handle.GrantedAccess == 0x0012019f)
- {
- /* We have the type, so display that. */
- /*
- printf(
- "[%#x] %.*S: (did not get name)\n",
- handle.Handle,
- objectTypeInfo->Name.Length / 2,
- objectTypeInfo->Name.Buffer
- );
- */
- free(objectTypeInfo);
- CloseHandle(dupHandle);
- continue;
- }
-
- objectNameInfo = malloc(0x1000);
- if (!NT_SUCCESS(NtQueryObject(
- dupHandle,
- ObjectNameInformation,
- objectNameInfo,
- 0x1000,
- &returnLength
- )))
- {
- /* Reallocate the buffer and try again. */
- objectNameInfo = realloc(objectNameInfo, returnLength);
- if (!NT_SUCCESS(NtQueryObject(
- dupHandle,
- ObjectNameInformation,
- objectNameInfo,
- returnLength,
- NULL
- )))
- {
- /* We have the type name, so just display that.*/
- /*
- printf(
- "[%#x] %.*S: (could not get name)\n",
- handle.Handle,
- objectTypeInfo->Name.Length / 2,
- objectTypeInfo->Name.Buffer
- );
- */
- free(objectTypeInfo);
- free(objectNameInfo);
- CloseHandle(dupHandle);
- continue;
-
- }
- }
-
- /* Cast our buffer into an UNICODE_STRING. */
- objectName = *(PUNICODE_STRING)objectNameInfo;
-
- /* Print the information! */
- if (objectName.Length)
- {
- /* The object has a name. Make sure it is a file otherwise
- ignore it */
- fileNameLength = objectName.Length / 2;
- if (wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) {
- //printf("%.*S\n", objectName.Length / 2, objectName.Buffer);
- fileFromWchar = PyUnicode_FromWideChar(objectName.Buffer,
- fileNameLength);
- #if PY_MAJOR_VERSION >= 3
- arg = Py_BuildValue("N", PyUnicode_AsUTF8String(fileFromWchar));
- #else
- arg = Py_BuildValue("N", PyUnicode_FromObject(fileFromWchar));
- #endif
- Py_XDECREF(fileFromWchar);
- PyList_Append(filesList, arg);
- Py_XDECREF(arg);
- }
- /*
- printf(
- "[%#x] %.*S: %.*S\n",
- handle.Handle,
- objectTypeInfo->Name.Length / 2,
- objectTypeInfo->Name.Buffer,
- objectName.Length / 2,
- objectName.Buffer
- );
- */
- }
- else
- {
- /* Print something else. */
- /*
- printf(
- "[%#x] %.*S: (unnamed)\n",
- handle.Handle,
- objectTypeInfo->Name.Length / 2,
- objectTypeInfo->Name.Buffer
- );
- */
- ;;
- }
- free(objectTypeInfo);
- free(objectNameInfo);
- CloseHandle(dupHandle);
- }
- free(handleInfo);
- CloseHandle(processHandle);
- return filesList;
-}
-
+#ifndef UNICODE
+#define UNICODE
+#endif
+
+#include <Python.h>
+#include <windows.h>
+#include <stdio.h>
+#include <Ntdef.h>
+#include "process_handles.h"
+
+#ifndef NT_SUCCESS
+ #define NT_SUCCESS(x) ((x) >= 0)
+#endif
+#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
+
+#define SystemHandleInformation 16
+#define ObjectBasicInformation 0
+#define ObjectNameInformation 1
+#define ObjectTypeInformation 2
+
+typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
+ ULONG SystemInformationClass,
+ PVOID SystemInformation,
+ ULONG SystemInformationLength,
+ PULONG ReturnLength
+ );
+
+typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
+ HANDLE SourceProcessHandle,
+ HANDLE SourceHandle,
+ HANDLE TargetProcessHandle,
+ PHANDLE TargetHandle,
+ ACCESS_MASK DesiredAccess,
+ ULONG Attributes,
+ ULONG Options
+ );
+
+typedef NTSTATUS (NTAPI *_NtQueryObject)(
+ HANDLE ObjectHandle,
+ ULONG ObjectInformationClass,
+ PVOID ObjectInformation,
+ ULONG ObjectInformationLength,
+ PULONG ReturnLength
+ );
+
+typedef struct _SYSTEM_HANDLE
+{
+ ULONG ProcessId;
+ BYTE ObjectTypeNumber;
+ BYTE Flags;
+ USHORT Handle;
+ PVOID Object;
+ ACCESS_MASK GrantedAccess;
+} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
+
+typedef struct _SYSTEM_HANDLE_INFORMATION
+{
+ ULONG HandleCount;
+ SYSTEM_HANDLE Handles[1];
+} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
+
+typedef enum _POOL_TYPE
+{
+ NonPagedPool,
+ PagedPool,
+ NonPagedPoolMustSucceed,
+ DontUseThisType,
+ NonPagedPoolCacheAligned,
+ PagedPoolCacheAligned,
+ NonPagedPoolCacheAlignedMustS
+} POOL_TYPE, *PPOOL_TYPE;
+
+typedef struct _OBJECT_TYPE_INFORMATION
+{
+ UNICODE_STRING Name;
+ ULONG TotalNumberOfObjects;
+ ULONG TotalNumberOfHandles;
+ ULONG TotalPagedPoolUsage;
+ ULONG TotalNonPagedPoolUsage;
+ ULONG TotalNamePoolUsage;
+ ULONG TotalHandleTableUsage;
+ ULONG HighWaterNumberOfObjects;
+ ULONG HighWaterNumberOfHandles;
+ ULONG HighWaterPagedPoolUsage;
+ ULONG HighWaterNonPagedPoolUsage;
+ ULONG HighWaterNamePoolUsage;
+ ULONG HighWaterHandleTableUsage;
+ ULONG InvalidAttributes;
+ GENERIC_MAPPING GenericMapping;
+ ULONG ValidAccess;
+ BOOLEAN SecurityRequired;
+ BOOLEAN MaintainHandleCount;
+ USHORT MaintainTypeList;
+ POOL_TYPE PoolType;
+ ULONG PagedPoolUsage;
+ ULONG NonPagedPoolUsage;
+} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
+
+PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
+{
+ return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
+}
+
+
+PyObject* get_open_files(long pid, HANDLE processHandle)
+{
+ _NtQuerySystemInformation NtQuerySystemInformation =
+ GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
+ _NtDuplicateObject NtDuplicateObject =
+ GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
+ _NtQueryObject NtQueryObject =
+ GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
+
+ NTSTATUS status;
+ PSYSTEM_HANDLE_INFORMATION handleInfo;
+ ULONG handleInfoSize = 0x10000;
+
+ ULONG i;
+ ULONG fileNameLength;
+ PyObject *filesList = Py_BuildValue("[]");
+ PyObject *arg = NULL;
+ PyObject *fileFromWchar = NULL;
+
+
+
+ handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
+
+ /* NtQuerySystemInformation won't give us the correct buffer size,
+ so we guess by doubling the buffer size. */
+ while ((status = NtQuerySystemInformation(
+ SystemHandleInformation,
+ handleInfo,
+ handleInfoSize,
+ NULL
+ )) == STATUS_INFO_LENGTH_MISMATCH)
+ handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
+
+ /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
+ if (!NT_SUCCESS(status)) {
+ //printf("NtQuerySystemInformation failed!\n");
+ return NULL;
+ }
+
+ for (i = 0; i < handleInfo->HandleCount; i++)
+ {
+ SYSTEM_HANDLE handle = handleInfo->Handles[i];
+ HANDLE dupHandle = NULL;
+ POBJECT_TYPE_INFORMATION objectTypeInfo;
+ PVOID objectNameInfo;
+ UNICODE_STRING objectName;
+ ULONG returnLength;
+
+ /* Check if this handle belongs to the PID the user specified. */
+ if (handle.ProcessId != pid)
+ continue;
+
+ /* Duplicate the handle so we can query it. */
+ if (!NT_SUCCESS(NtDuplicateObject(
+ processHandle,
+ handle.Handle,
+ GetCurrentProcess(),
+ &dupHandle,
+ 0,
+ 0,
+ 0
+ )))
+ {
+ //printf("[%#x] Error!\n", handle.Handle);
+ continue;
+ }
+
+ /* Query the object type. */
+ objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
+ if (!NT_SUCCESS(NtQueryObject(
+ dupHandle,
+ ObjectTypeInformation,
+ objectTypeInfo,
+ 0x1000,
+ NULL
+ )))
+ {
+ //printf("[%#x] Error!\n", handle.Handle);
+ CloseHandle(dupHandle);
+ continue;
+ }
+
+ /* Query the object name (unless it has an access of
+ 0x0012019f, on which NtQueryObject could hang. */
+ if (handle.GrantedAccess == 0x0012019f)
+ {
+ /* We have the type, so display that. */
+ /*
+ printf(
+ "[%#x] %.*S: (did not get name)\n",
+ handle.Handle,
+ objectTypeInfo->Name.Length / 2,
+ objectTypeInfo->Name.Buffer
+ );
+ */
+ free(objectTypeInfo);
+ CloseHandle(dupHandle);
+ continue;
+ }
+
+ objectNameInfo = malloc(0x1000);
+ if (!NT_SUCCESS(NtQueryObject(
+ dupHandle,
+ ObjectNameInformation,
+ objectNameInfo,
+ 0x1000,
+ &returnLength
+ )))
+ {
+ /* Reallocate the buffer and try again. */
+ objectNameInfo = realloc(objectNameInfo, returnLength);
+ if (!NT_SUCCESS(NtQueryObject(
+ dupHandle,
+ ObjectNameInformation,
+ objectNameInfo,
+ returnLength,
+ NULL
+ )))
+ {
+ /* We have the type name, so just display that.*/
+ /*
+ printf(
+ "[%#x] %.*S: (could not get name)\n",
+ handle.Handle,
+ objectTypeInfo->Name.Length / 2,
+ objectTypeInfo->Name.Buffer
+ );
+ */
+ free(objectTypeInfo);
+ free(objectNameInfo);
+ CloseHandle(dupHandle);
+ continue;
+
+ }
+ }
+
+ /* Cast our buffer into an UNICODE_STRING. */
+ objectName = *(PUNICODE_STRING)objectNameInfo;
+
+ /* Print the information! */
+ if (objectName.Length)
+ {
+ /* The object has a name. Make sure it is a file otherwise
+ ignore it */
+ fileNameLength = objectName.Length / 2;
+ if (wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) {
+ //printf("%.*S\n", objectName.Length / 2, objectName.Buffer);
+ fileFromWchar = PyUnicode_FromWideChar(objectName.Buffer,
+ fileNameLength);
+ #if PY_MAJOR_VERSION >= 3
+ arg = Py_BuildValue("N", PyUnicode_AsUTF8String(fileFromWchar));
+ #else
+ arg = Py_BuildValue("N", PyUnicode_FromObject(fileFromWchar));
+ #endif
+ Py_XDECREF(fileFromWchar);
+ PyList_Append(filesList, arg);
+ Py_XDECREF(arg);
+ }
+ /*
+ printf(
+ "[%#x] %.*S: %.*S\n",
+ handle.Handle,
+ objectTypeInfo->Name.Length / 2,
+ objectTypeInfo->Name.Buffer,
+ objectName.Length / 2,
+ objectName.Buffer
+ );
+ */
+ }
+ else
+ {
+ /* Print something else. */
+ /*
+ printf(
+ "[%#x] %.*S: (unnamed)\n",
+ handle.Handle,
+ objectTypeInfo->Name.Length / 2,
+ objectTypeInfo->Name.Buffer
+ );
+ */
+ ;;
+ }
+ free(objectTypeInfo);
+ free(objectNameInfo);
+ CloseHandle(dupHandle);
+ }
+ free(handleInfo);
+ CloseHandle(processHandle);
+ return filesList;
+}
+
diff --git a/psutil/arch/mswindows/process_handles.h b/psutil/arch/mswindows/process_handles.h
index cbbb2ba8..bd9d39b8 100644
--- a/psutil/arch/mswindows/process_handles.h
+++ b/psutil/arch/mswindows/process_handles.h
@@ -1,4 +1,4 @@
-#include <Python.h>
-#include <windows.h>
-
-PyObject* get_open_files(long pid, HANDLE processHandle);
+#include <Python.h>
+#include <windows.h>
+
+PyObject* get_open_files(long pid, HANDLE processHandle);
diff --git a/psutil/wmi.py b/psutil/wmi.py
index 74d4a024..70324dca 100644
--- a/psutil/wmi.py
+++ b/psutil/wmi.py
@@ -1,1418 +1,1418 @@
-"""
-Windows Management Instrumentation (WMI) is Microsoft's answer to
-the DMTF's Common Information Model. It allows you to query just
-about any conceivable piece of information from any computer which
-is running the necessary agent and over which have you the
-necessary authority.
-
-Since the COM implementation doesn't give much away to Python
-programmers, I've wrapped it in some lightweight classes with
-some getattr / setattr magic to ease the way. In particular:
-
-* The :class:`_wmi_namespace` object itself will determine its classes
- and allow you to return all instances of any of them by
- using its name as an attribute::
-
- disks = wmi.WMI ().Win32_LogicalDisk ()
-
-* In addition, you can specify what would become the WHERE clause
- as keyword parameters::
-
- fixed_disks = wmi.WMI ().Win32_LogicalDisk (DriveType=3)
-
-* The objects returned by a WMI lookup are wrapped in a Python
- class which determines their methods and classes and allows
- you to access them as though they were Python classes. The
- methods only allow named parameters::
-
- for p in wmi.WMI ().Win32_Process (Name="notepad.exe"):
- p.Terminate (Result=1)
-
-* Doing a print on one of the WMI objects will result in its
- `GetObjectText\_` method being called, which usually produces
- a meaningful printout of current values.
- The repr of the object will include its full WMI path,
- which lets you get directly to it if you need to.
-
-* You can get the associators and references of an object as
- a list of python objects by calling the associators () and
- references () methods on a WMI Python object::
-
- for p in wmi.WMI ().Win32_Process (Name="notepad.exe"):
- for r in p.references ():
- print r
-
- .. note::
- Don't do this on a Win32_ComputerSystem object; it will
- take all day and kill your machine!
-
-
-* WMI classes (as opposed to instances) are first-class
- objects, so you can get hold of a class, and call
- its methods or set up a watch against it::
-
- process = wmi.WMI ().Win32_Process
- process.Create (CommandLine="notepad.exe")
-
-* To make it easier to use in embedded systems and py2exe-style
- executable wrappers, the module will not force early Dispatch.
- To do this, it uses a handy hack by Thomas Heller for easy access
- to constants.
-
-Typical usage will be::
-
- import wmi
-
- vodev1 = wmi.WMI ("vodev1")
- for disk in vodev1.Win32_LogicalDisk ():
- if disk.DriveType == 3:
- space = 100 * long (disk.FreeSpace) / long (disk.Size)
- print "%s has %d%% free" % (disk.Name, space)
-
-Many thanks, obviously to Mark Hammond for creating the win32all
-extensions, but also to Alex Martelli and Roger Upole, whose
-c.l.py postings pointed me in the right direction.
-Thanks especially in release 1.2 to Paul Tiemann for his code
-contributions and robust testing.
-"""
-__VERSION__ = __version__ = "1.4.6"
-
-_DEBUG = False
-
-import sys
-import datetime
-import re
-import struct
-import warnings
-
-from win32com.client import GetObject, Dispatch
-import pywintypes
-
-def signed_to_unsigned (signed):
- """Convert a (possibly signed) long to unsigned hex. Useful
- when converting a COM error code to the more conventional
- 8-digit hex::
-
- print "%08X" % signed_to_unsigned (-2147023174)
- """
- unsigned, = struct.unpack ("L", struct.pack ("l", signed))
- return unsigned
-
-class SelfDeprecatingDict (object):
- """Provides for graceful degradation of objects which
- are currently dictionaries (and therefore accessed via
- `.keys`, `.items`, etc.) into lists. Wraps an existing
- `dict` and allows it to be addressed as a `dict` or as a
- `list` during an interregnum, issuing a `DeprecationWarning`
- if accessed as a `dict`.
- """
-
- dict_only = set (dir (dict)).difference (dir (list))
-
- def __init__ (self, dictlike):
- self.dict = dict (dictlike)
- self.list = list (self.dict)
-
- def __getattr__ (self, attribute):
- if attribute in self.dict_only:
- warnings.warn ("In future this will be a list and not a dictionary", DeprecationWarning)
- return getattr (self.dict, attribute)
- else:
- return getattr (self.list, attribute)
-
- def __iter__ (self):
- return iter (self.list)
-
- def __str__ (self):
- return str (self.list)
-
- def __repr__ (self):
- return repr (self.list)
-
- def __getitem__ (self, item):
- try:
- return self.list[item]
- except TypeError:
- return self.dict[item]
-
-class ProvideConstants (object):
- """When called on a ``win32com.client.Dispatch`` object,
- provides lazy access to constants defined in the typelib.
- They can then be accessed as attributes of the :attr:`_constants`
- property. (From Thomas Heller on c.l.py).
- """
- def __init__(self, comobj):
- comobj.__dict__["_constants"] = self
- self.__typecomp = \
- comobj._oleobj_.GetTypeInfo().GetContainingTypeLib()[0].GetTypeComp()
-
- def __getattr__(self, name):
- if name.startswith("__") and name.endswith("__"):
- raise AttributeError (name)
- result = self.__typecomp.Bind(name)
- if not result[0]:
- raise AttributeError (name)
- return result[1].value
-
-obj = GetObject ("winmgmts:")
-ProvideConstants (obj)
-
-wbemErrInvalidQuery = obj._constants.wbemErrInvalidQuery
-wbemErrTimedout = obj._constants.wbemErrTimedout
-wbemFlagReturnImmediately = obj._constants.wbemFlagReturnImmediately
-wbemFlagForwardOnly = obj._constants.wbemFlagForwardOnly
-
-#
-# Exceptions
-#
-class x_wmi (Exception):
- """Ancestor of all wmi-related exceptions. Keeps track of
- an info message and the underlying COM error if any, exposed
- as the :attr:`com_error` attribute.
- """
- def __init__ (self, info="", com_error=None):
- self.info = info
- self.com_error = com_error
-
- def __str__ (self):
- return "<x_wmi: %s %s>" % (
- self.info or "Unexpected COM Error",
- self.com_error or "(no underlying exception)"
- )
-
-class x_wmi_invalid_query (x_wmi):
- "Raised when a WMI returns `wbemErrInvalidQuery`"
- pass
-
-class x_wmi_timed_out (x_wmi):
- "Raised when a watcher times out"
- pass
-
-class x_wmi_no_namespace (x_wmi):
- """Raised when an attempt is made to query or watch
- from a class without a namespace.
- """
- pass
-
-class x_access_denied (x_wmi):
- "Raised when WMI raises 80070005"
- pass
-
-class x_wmi_authentication (x_wmi):
- "Raised when an invalid combination of authentication properties is attempted when connecting"
- pass
-
-class x_wmi_uninitialised_thread (x_wmi):
- """Raised when WMI returns 800401E4 on connection, usually
- indicating that no COM threading model has been initialised
- """
- pass
-
-WMI_EXCEPTIONS = {
- signed_to_unsigned (wbemErrInvalidQuery) : x_wmi_invalid_query,
- signed_to_unsigned (wbemErrTimedout) : x_wmi_timed_out,
- 0x80070005 : x_access_denied,
- 0x80041003 : x_access_denied,
- 0x800401E4 : x_wmi_uninitialised_thread,
-}
-
-def handle_com_error (err=None):
- """Convenience wrapper for displaying all manner of COM errors.
- Raises a :exc:`x_wmi` exception with more useful information attached
-
- :param err: The structure attached to a `pywintypes.com_error`
- """
- if err is None:
- _, err, _ = sys.exc_info ()
- hresult_code, hresult_name, additional_info, parameter_in_error = err.args
- hresult_code = signed_to_unsigned (hresult_code)
- exception_string = ["%s - %s" % (hex (hresult_code), hresult_name)]
- scode = None
- if additional_info:
- wcode, source_of_error, error_description, whlp_file, whlp_context, scode = additional_info
- scode = signed_to_unsigned (scode)
- exception_string.append (" Error in: %s" % source_of_error)
- exception_string.append (" %s - %s" % (hex (scode), (error_description or "").strip ()))
- for error_code, klass in WMI_EXCEPTIONS.items ():
- if error_code in (hresult_code, scode):
- break
- else:
- klass = x_wmi
- raise klass (com_error=err)
-
-
-BASE = datetime.datetime (1601, 1, 1)
-def from_1601 (ns100):
- return BASE + datetime.timedelta (microseconds=int (ns100) / 10)
-
-def from_time (year=None, month=None, day=None, hours=None, minutes=None, seconds=None, microseconds=None, timezone=None):
- """Convenience wrapper to take a series of date/time elements and return a WMI time
- of the form `yyyymmddHHMMSS.mmmmmm+UUU`. All elements may be int, string or
- omitted altogether. If omitted, they will be replaced in the output string
- by a series of stars of the appropriate length.
-
- :param year: The year element of the date/time
- :param month: The month element of the date/time
- :param day: The day element of the date/time
- :param hours: The hours element of the date/time
- :param minutes: The minutes element of the date/time
- :param seconds: The seconds element of the date/time
- :param microseconds: The microseconds element of the date/time
- :param timezone: The timeezone element of the date/time
-
- :returns: A WMI datetime string of the form: `yyyymmddHHMMSS.mmmmmm+UUU`
- """
- def str_or_stars (i, length):
- if i is None:
- return "*" * length
- else:
- return str (i).rjust (length, "0")
-
- wmi_time = ""
- wmi_time += str_or_stars (year, 4)
- wmi_time += str_or_stars (month, 2)
- wmi_time += str_or_stars (day, 2)
- wmi_time += str_or_stars (hours, 2)
- wmi_time += str_or_stars (minutes, 2)
- wmi_time += str_or_stars (seconds, 2)
- wmi_time += "."
- wmi_time += str_or_stars (microseconds, 6)
- wmi_time += "+"
- wmi_time += str_or_stars (timezone, 3)
-
- return wmi_time
-
-def to_time (wmi_time):
- """Convenience wrapper to take a WMI datetime string of the form
- yyyymmddHHMMSS.mmmmmm+UUU and return a 9-tuple containing the
- individual elements, or None where string contains placeholder
- stars.
-
- :param wmi_time: The WMI datetime string in `yyyymmddHHMMSS.mmmmmm+UUU` format
-
- :returns: A 9-tuple of (year, month, day, hours, minutes, seconds, microseconds, timezone)
- """
- def int_or_none (s, start, end):
- try:
- return int (s[start:end])
- except ValueError:
- return None
-
- year = int_or_none (wmi_time, 0, 4)
- month = int_or_none (wmi_time, 4, 6)
- day = int_or_none (wmi_time, 6, 8)
- hours = int_or_none (wmi_time, 8, 10)
- minutes = int_or_none (wmi_time, 10, 12)
- seconds = int_or_none (wmi_time, 12, 14)
- microseconds = int_or_none (wmi_time, 15, 21)
- timezone = wmi_time[22:]
- if timezone == "***":
- timezone = None
-
- return year, month, day, hours, minutes, seconds, microseconds, timezone
-
-def _set (obj, attribute, value):
- """Helper function to add an attribute directly into the instance
- dictionary, bypassing possible `__getattr__` calls
-
- :param obj: Any python object
- :param attribute: String containing attribute name
- :param value: Any python object
- """
- obj.__dict__[attribute] = value
-
-class _wmi_method:
- """A currying sort of wrapper around a WMI method name. It
- abstract's the method's parameters and can be called like
- a normal Python object passing in the parameter values.
-
- Output parameters are returned from the call as a tuple.
- In addition, the docstring is set up as the method's
- signature, including an indication as to whether any
- given parameter is expecting an array, and what
- special privileges are required to call the method.
- """
-
- def __init__ (self, ole_object, method_name):
- """
- :param ole_object: The WMI class/instance whose method is to be called
- :param method_name: The name of the method to be called
- """
- try:
- self.ole_object = Dispatch (ole_object)
- self.method = ole_object.Methods_ (method_name)
- self.qualifiers = {}
- for q in self.method.Qualifiers_:
- self.qualifiers[q.Name] = q.Value
- self.provenance = "\n".join (self.qualifiers.get ("MappingStrings", []))
-
- self.in_parameters = self.method.InParameters
- self.out_parameters = self.method.OutParameters
- if self.in_parameters is None:
- self.in_parameter_names = []
- else:
- self.in_parameter_names = [(i.Name, i.IsArray) for i in self.in_parameters.Properties_]
- if self.out_parameters is None:
- self.out_parameter_names = []
- else:
- self.out_parameter_names = [(i.Name, i.IsArray) for i in self.out_parameters.Properties_]
-
- doc = "%s (%s) => (%s)" % (
- method_name,
- ", ".join ([name + ("", "[]")[is_array] for (name, is_array) in self.in_parameter_names]),
- ", ".join ([name + ("", "[]")[is_array] for (name, is_array) in self.out_parameter_names])
- )
- privileges = self.qualifiers.get ("Privileges", [])
- if privileges:
- doc += " | Needs: " + ", ".join (privileges)
- self.__doc__ = doc
- except pywintypes.com_error:
- handle_com_error ()
-
- def __call__ (self, *args, **kwargs):
- """Execute the call to a WMI method, returning
- a tuple (even if is of only one value) containing
- the out and return parameters.
- """
- try:
- if self.in_parameters:
- parameter_names = {}
- for name, is_array in self.in_parameter_names:
- parameter_names[name] = is_array
-
- parameters = self.in_parameters
-
- #
- # Check positional parameters first
- #
- for n_arg in range (len (args)):
- arg = args[n_arg]
- parameter = parameters.Properties_[n_arg]
- if parameter.IsArray:
- try: list (arg)
- except TypeError: raise TypeError ("parameter %d must be iterable" % n_arg)
- parameter.Value = arg
-
- #
- # If any keyword param supersedes a positional one,
- # it'll simply overwrite it.
- #
- for k, v in kwargs.items ():
- is_array = parameter_names.get (k)
- if is_array is None:
- raise AttributeError ("%s is not a valid parameter for %s" % (k, self.__doc__))
- else:
- if is_array:
- try: list (v)
- except TypeError: raise TypeError ("%s must be iterable" % k)
- parameters.Properties_ (k).Value = v
-
- result = self.ole_object.ExecMethod_ (self.method.Name, self.in_parameters)
- else:
- result = self.ole_object.ExecMethod_ (self.method.Name)
-
- results = []
- for name, is_array in self.out_parameter_names:
- value = result.Properties_ (name).Value
- if is_array:
- #
- # Thanks to Jonas Bjering for bug report and patch
- #
- results.append (list (value or []))
- else:
- results.append (value)
- return tuple (results)
-
- except pywintypes.com_error:
- handle_com_error ()
-
- def __repr__ (self):
- return "<function %s>" % self.__doc__
-
-class _wmi_property (object):
-
- def __init__ (self, property):
- self.property = property
- self.name = property.Name
- self.value = property.Value
- self.qualifiers = dict ((q.Name, q.Value) for q in property.Qualifiers_)
- self.type = self.qualifiers.get ("CIMTYPE", None)
-
- def set (self, value):
- self.property.Value = value
-
- def __getattr__ (self, attr):
- return getattr (self.property, attr)
-
-#
-# class _wmi_object
-#
-class _wmi_object:
- """The heart of the WMI module: wraps the objects returned by COM
- ISWbemObject interface and provide readier access to their properties
- and methods resulting in a more Pythonic interface. Not usually
- instantiated directly, rather as a result of calling a :class:`_wmi_class`
- on the parent :class:`_wmi_namespace`.
-
- If you get hold of a WMI-related COM object from some other
- source than this module, you can wrap it in one of these objects
- to get the benefits of the module::
-
- import win32com.client
- import wmi
-
- wmiobj = win32com.client.GetObject ("winmgmts:Win32_LogicalDisk.DeviceID='C:'")
- c_drive = wmi._wmi_object (wmiobj)
- print c_drive
- """
-
- def __init__ (self, ole_object, instance_of=None, fields=[], property_map={}):
- try:
- _set (self, "ole_object", ole_object)
- _set (self, "id", ole_object.Path_.DisplayName.lower ())
- _set (self, "_instance_of", instance_of)
- _set (self, "properties", {})
- _set (self, "methods", {})
- _set (self, "property_map", property_map)
- _set (self, "_associated_classes", None)
- _set (self, "_keys", None)
-
- if fields:
- for field in fields:
- self.properties[field] = None
- else:
- for p in ole_object.Properties_:
- self.properties[p.Name] = None
-
- for m in ole_object.Methods_:
- self.methods[m.Name] = None
-
- _set (self, "_properties", self.properties.keys ())
- _set (self, "_methods", self.methods.keys ())
- _set (self, "qualifiers", dict ((q.Name, q.Value) for q in self.ole_object.Qualifiers_))
-
- except pywintypes.com_error:
- handle_com_error ()
-
- def __lt__ (self, other):
- return self.id < other.id
-
- def __str__ (self):
- """For a call to print [object] return the OLE description
- of the properties / values of the object
- """
- try:
- return self.ole_object.GetObjectText_ ()
- except pywintypes.com_error:
- handle_com_error ()
-
- def __repr__ (self):
- """
- Indicate both the fact that this is a wrapped WMI object
- and the WMI object's own identifying class.
- """
- try:
- return "<%s: %s>" % (self.__class__.__name__, str (self.Path_.Path))
- except pywintypes.com_error:
- handle_com_error ()
-
- def _cached_properties (self, attribute):
- if self.properties[attribute] is None:
- self.properties[attribute] = _wmi_property (self.ole_object.Properties_ (attribute))
- return self.properties[attribute]
-
- def _cached_methods (self, attribute):
- if self.methods[attribute] is None:
- self.methods[attribute] = _wmi_method (self.ole_object, attribute)
- return self.methods[attribute]
-
- def __getattr__ (self, attribute):
- """
- Attempt to pass attribute calls to the proxied COM object.
- If the attribute is recognised as a property, return its value;
- if it is recognised as a method, return a method wrapper which
- can then be called with parameters; otherwise pass the lookup
- on to the underlying object.
- """
- try:
- if attribute in self.properties:
- property = self._cached_properties (attribute)
- factory = self.property_map.get (attribute, self.property_map.get (property.type, lambda x: x))
- value = factory (property.value)
- #
- # If this is an association, certain of its properties
- # are actually the paths to the aspects of the association,
- # so translate them automatically into WMI objects.
- #
- if property.type.startswith ("ref:"):
- return WMI (moniker=value)
- else:
- return value
- elif attribute in self.methods:
- return self._cached_methods (attribute)
- else:
- return getattr (self.ole_object, attribute)
- except pywintypes.com_error:
- handle_com_error ()
-
- def __setattr__ (self, attribute, value):
- """If the attribute to be set is valid for the proxied
- COM object, set that objects's parameter value; if not,
- raise an exception.
- """
- try:
- if attribute in self.properties:
- self._cached_properties (attribute).set (value)
- if self.ole_object.Path_.Path:
- self.ole_object.Put_ ()
- else:
- raise AttributeError (attribute)
- except pywintypes.com_error:
- handle_com_error ()
-
- def __eq__ (self, other):
- return self.id == other.id
-
- def __hash__ (self):
- return hash (self.id)
-
- def _getAttributeNames (self):
- """Return list of methods/properties for IPython completion"""
- attribs = [str (x) for x in self.methods.keys ()]
- attribs.extend ([str (x) for x in self.properties.keys ()])
- return attribs
-
- def _get_keys (self):
- """A WMI object is uniquely defined by a set of properties
- which constitute its keys. Lazily retrieves the keys for this
- instance or class.
-
- :returns: list of key property names
- """
- # NB You can get the keys of an instance more directly, via
- # Path\_.Keys but this doesn't apply to classes. The technique
- # here appears to work for both.
- if self._keys is None:
- _set (self, "_keys", [])
- for property in self.ole_object.Properties_:
- for qualifier in property.Qualifiers_:
- if qualifier.Name == "key" and qualifier.Value:
- self._keys.append (property.Name)
- return self._keys
- keys = property (_get_keys)
-
- def put (self):
- """Push all outstanding property updates back to the
- WMI database.
- """
- self.ole_object.Put_ ()
-
- def set (self, **kwargs):
- """Set several properties of the underlying object
- at one go. This is particularly useful in combination
- with the new () method below. However, an instance
- which has been spawned in this way won't have enough
- information to write pack, so only try if the
- instance has a path.
- """
- if kwargs:
- try:
- for attribute, value in kwargs.items ():
- if attribute in self.properties:
- self._cached_properties (attribute).set (value)
- else:
- raise AttributeError (attribute)
- #
- # Only try to write the attributes
- # back if the object exists.
- #
- if self.ole_object.Path_.Path:
- self.ole_object.Put_ ()
- except pywintypes.com_error:
- handle_com_error ()
-
- def path (self):
- """Return the WMI URI to this object. Can be used to
- determine the path relative to the parent namespace::
-
- pp0 = wmi.WMI ().Win32_ParallelPort ()[0]
- print pp0.path ().RelPath
-
- .. Do more with this
- """
- try:
- return self.ole_object.Path_
- except pywintypes.com_error:
- handle_com_error ()
-
- def derivation (self):
- """Return a tuple representing the object derivation for
- this object, with the most specific object first::
-
- pp0 = wmi.WMI ().Win32_ParallelPort ()[0]
- print ' <- '.join (pp0.derivation ())
- """
- try:
- return self.ole_object.Derivation_
- except pywintypes.com_error:
- handle_com_error ()
-
- def _cached_associated_classes (self):
- if self._associated_classes is None:
- if isinstance (self, _wmi_class):
- params = {'bSchemaOnly' : True}
- else:
- params = {'bClassesOnly' : True}
- try:
- associated_classes = dict (
- (assoc.Path_.Class, _wmi_class (self._namespace, assoc)) for
- assoc in self.ole_object.Associators_ (**params)
- )
- _set (self, "_associated_classes", associated_classes)
- except pywintypes.com_error:
- handle_com_error ()
-
- return self._associated_classes
- associated_classes = property (_cached_associated_classes)
-
- def associators (self, wmi_association_class="", wmi_result_class=""):
- """Return a list of objects related to this one, optionally limited
- either by association class (ie the name of the class which relates
- them) or by result class (ie the name of the class which would be
- retrieved)::
-
- c = wmi.WMI ()
- pp = c.Win32_ParallelPort ()[0]
-
- for i in pp.associators (wmi_association_class="Win32_PortResource"):
- print i
-
- for i in pp.associators (wmi_result_class="Win32_PnPEntity"):
- print i
- """
- try:
- return [
- _wmi_object (i) for i in \
- self.ole_object.Associators_ (
- strAssocClass=wmi_association_class,
- strResultClass=wmi_result_class
- )
- ]
- except pywintypes.com_error:
- handle_com_error ()
-
- def references (self, wmi_class=""):
- """Return a list of associations involving this object, optionally
- limited by the result class (the name of the association class).
-
- NB Associations are treated specially; although WMI only returns
- the string corresponding to the instance of each associated object,
- this module will automatically convert that to the object itself::
-
- c = wmi.WMI ()
- sp = c.Win32_SerialPort ()[0]
-
- for i in sp.references ():
- print i
-
- for i in sp.references (wmi_class="Win32_SerialPortSetting"):
- print i
- """
- #
- # FIXME: Allow an actual class to be passed in, using
- # its .Path_.RelPath property to determine the string
- #
- try:
- return [_wmi_object (i) for i in self.ole_object.References_ (strResultClass=wmi_class)]
- except pywintypes.com_error:
- handle_com_error ()
-
-#
-# class _wmi_event
-#
-class _wmi_event (_wmi_object):
- """Slight extension of the _wmi_object class to allow
- objects which are the result of events firing to return
- extra information such as the type of event.
- """
- event_type_re = re.compile ("__Instance(Creation|Modification|Deletion)Event")
- def __init__ (self, event, event_info, fields=[]):
- _wmi_object.__init__ (self, event, fields=fields)
- _set (self, "event_type", None)
- _set (self, "timestamp", None)
- _set (self, "previous", None)
-
- if event_info:
- event_type = self.event_type_re.match (event_info.Path_.Class).group (1).lower ()
- _set (self, "event_type", event_type)
- if hasattr (event_info, "TIME_CREATED"):
- _set (self, "timestamp", from_1601 (event_info.TIME_CREATED))
- if hasattr (event_info, "PreviousInstance"):
- _set (self, "previous", event_info.PreviousInstance)
-
-#
-# class _wmi_class
-#
-class _wmi_class (_wmi_object):
- """Currying class to assist in issuing queries against
- a WMI namespace. The idea is that when someone issues
- an otherwise unknown method against the WMI object, if
- it matches a known WMI class a query object will be
- returned which may then be called with one or more params
- which will form the WHERE clause::
-
- c = wmi.WMI ()
- c_drives = c.Win32_LogicalDisk (Name='C:')
- """
- def __init__ (self, namespace, wmi_class):
- _wmi_object.__init__ (self, wmi_class)
- _set (self, "_class_name", wmi_class.Path_.Class)
- if namespace:
- _set (self, "_namespace", namespace)
- else:
- class_moniker = wmi_class.Path_.DisplayName
- winmgmts, namespace_moniker, class_name = class_moniker.split (":")
- namespace = _wmi_namespace (GetObject (winmgmts + ":" + namespace_moniker), False)
- _set (self, "_namespace", namespace)
-
- def query (self, fields=[], **where_clause):
- """Make it slightly easier to query against the class,
- by calling the namespace's query with the class preset.
- Won't work if the class has been instantiated directly.
- """
- #
- # FIXME: Not clear if this can ever happen
- #
- if self._namespace is None:
- raise x_wmi_no_namespace ("You cannot query directly from a WMI class")
-
- try:
- field_list = ", ".join (fields) or "*"
- wql = "SELECT " + field_list + " FROM " + self._class_name
- if where_clause:
- wql += " WHERE " + " AND ". join (["%s = '%s'" % (k, v) for k, v in where_clause.items ()])
- return self._namespace.query (wql, self, fields)
- except pywintypes.com_error:
- handle_com_error ()
-
- __call__ = query
-
- def watch_for (
- self,
- notification_type="operation",
- delay_secs=1,
- fields=[],
- **where_clause
- ):
- if self._namespace is None:
- raise x_wmi_no_namespace ("You cannot watch directly from a WMI class")
-
- valid_notification_types = ("operation", "creation", "deletion", "modification")
- if notification_type.lower () not in valid_notification_types:
- raise x_wmi ("notification_type must be one of %s" % ", ".join (valid_notification_types))
-
- return self._namespace.watch_for (
- notification_type=notification_type,
- wmi_class=self,
- delay_secs=delay_secs,
- fields=fields,
- **where_clause
- )
-
- def instances (self):
- """Return a list of instances of the WMI class
- """
- try:
- return [_wmi_object (instance, self) for instance in self.Instances_ ()]
- except pywintypes.com_error:
- handle_com_error ()
-
- def new (self, **kwargs):
- """This is the equivalent to the raw-WMI SpawnInstance\_
- method. Note that there are relatively few uses for
- this, certainly fewer than you might imagine. Most
- classes which need to create a new *real* instance
- of themselves, eg Win32_Process, offer a .Create
- method. SpawnInstance\_ is generally reserved for
- instances which are passed as parameters to such
- `.Create` methods, a common example being the
- `Win32_SecurityDescriptor`, passed to `Win32_Share.Create`
- and other instances which need security.
-
- The example here is `Win32_ProcessStartup`, which
- controls the shown/hidden state etc. of a new
- `Win32_Process` instance::
-
- import win32con
- import wmi
- c = wmi.WMI ()
- startup = c.Win32_ProcessStartup.new (ShowWindow=win32con.SW_SHOWMINIMIZED)
- pid, retval = c.Win32_Process.Create (
- CommandLine="notepad.exe",
- ProcessStartupInformation=startup
- )
-
- .. warning::
- previous versions of this docstring illustrated using this function
- to create a new process. This is *not* a good example of its use;
- it is better handled with something like the example above.
- """
- try:
- obj = _wmi_object (self.SpawnInstance_ (), self)
- obj.set (**kwargs)
- return obj
- except pywintypes.com_error:
- handle_com_error ()
-
-#
-# class _wmi_result
-#
-class _wmi_result:
- """Simple, data only result for targeted WMI queries which request
- data only result classes via fetch_as_classes.
- """
- def __init__(self, obj, attributes):
- if attributes:
- for attr in attributes:
- self.__dict__[attr] = obj.Properties_ (attr).Value
- else:
- for p in obj.Properties_:
- attr = p.Name
- self.__dict__[attr] = obj.Properties_(attr).Value
-
-#
-# class WMI
-#
-class _wmi_namespace:
- """A WMI root of a computer system. The classes attribute holds a list
- of the classes on offer. This means you can explore a bit with
- things like this::
-
- c = wmi.WMI ()
- for i in c.classes:
- if "user" in i.lower ():
- print i
- """
- def __init__ (self, namespace, find_classes):
- _set (self, "_namespace", namespace)
- #
- # wmi attribute preserved for backwards compatibility
- #
- _set (self, "wmi", namespace)
-
- self._classes = None
- self._classes_map = {}
- #
- # Pick up the list of classes under this namespace
- # so that they can be queried, and used as though
- # properties of the namespace by means of the __getattr__
- # hook below.
- # If the namespace does not support SubclassesOf, carry on
- # regardless
- #
- if find_classes:
- _ = self.classes
-
- def __repr__ (self):
- return "<_wmi_namespace: %s>" % self.wmi
-
- def __str__ (self):
- return repr (self)
-
- def _get_classes (self):
- if self._classes is None:
- self._classes = self.subclasses_of ()
- return SelfDeprecatingDict (dict.fromkeys (self._classes))
- classes = property (_get_classes)
-
- def get (self, moniker):
- try:
- return _wmi_object (self.wmi.Get (moniker))
- except pywintypes.com_error:
- handle_com_error ()
-
- def handle (self):
- """The raw OLE object representing the WMI namespace"""
- return self._namespace
-
- def subclasses_of (self, root="", regex=r".*"):
- try:
- SubclassesOf = self._namespace.SubclassesOf
- except AttributeError:
- return set ()
- else:
- return set (
- c.Path_.Class
- for c in SubclassesOf (root)
- if re.match (regex, c.Path_.Class)
- )
-
- def instances (self, class_name):
- """Return a list of instances of the WMI class. This is
- (probably) equivalent to querying with no qualifiers::
-
- wmi.WMI ().instances ("Win32_LogicalDisk")
- # should be the same as
- wmi.WMI ().Win32_LogicalDisk ()
- """
- try:
- return [_wmi_object (obj) for obj in self._namespace.InstancesOf (class_name)]
- except pywintypes.com_error:
- handle_com_error ()
-
- def new (self, wmi_class, **kwargs):
- """This is now implemented by a call to :meth:`_wmi_class.new`"""
- return getattr (self, wmi_class).new (**kwargs)
-
- new_instance_of = new
-
- def _raw_query (self, wql):
- """Execute a WQL query and return its raw results. Use the flags
- recommended by Microsoft to achieve a read-only, semi-synchronous
- query where the time is taken while looping through.
- NB Backslashes need to be doubled up.
- """
- flags = wbemFlagReturnImmediately | wbemFlagForwardOnly
- wql = wql.replace ("\\", "\\\\")
- try:
- return self._namespace.ExecQuery (strQuery=wql, iFlags=flags)
- except pywintypes.com_error:
- handle_com_error ()
-
- def query (self, wql, instance_of=None, fields=[]):
- """Perform an arbitrary query against a WMI object, and return
- a list of _wmi_object representations of the results.
- """
- return [ _wmi_object (obj, instance_of, fields) for obj in self._raw_query(wql) ]
-
- def fetch_as_classes (self, wmi_classname, fields=(), **where_clause):
- """Build and execute a wql query to fetch the specified list of fields from
- the specified wmi_classname + where_clause, then return the results as
- a list of simple class instances with attributes matching field_list.
-
- If fields is left empty, select * and pre-load all class attributes for
- each class returned.
- """
- wql = "SELECT %s FROM %s" % (fields and ", ".join (fields) or "*", wmi_classname)
- if where_clause:
- wql += " WHERE " + " AND ".join (["%s = '%s'" % (k, v) for k, v in where_clause.items()])
- return [_wmi_result (obj, fields) for obj in self._raw_query(wql)]
-
- def fetch_as_lists (self, wmi_classname, fields, **where_clause):
- """Build and execute a wql query to fetch the specified list of fields from
- the specified wmi_classname + where_clause, then return the results as
- a list of lists whose values correspond to field_list.
- """
- wql = "SELECT %s FROM %s" % (", ".join (fields), wmi_classname)
- if where_clause:
- wql += " WHERE " + " AND ".join (["%s = '%s'" % (k, v) for k, v in where_clause.items()])
- results = []
- for obj in self._raw_query(wql):
- results.append ([obj.Properties_ (field).Value for field in fields])
- return results
-
- def watch_for (
- self,
- raw_wql=None,
- notification_type="operation",
- wmi_class=None,
- delay_secs=1,
- fields=[],
- **where_clause
- ):
- """Set up an event tracker on a WMI event. This function
- returns an wmi_watcher which can be called to get the
- next event::
-
- c = wmi.WMI ()
-
- raw_wql = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'"
- watcher = c.watch_for (raw_wql=raw_wql)
- while 1:
- process_created = watcher ()
- print process_created.Name
-
- # or
-
- watcher = c.watch_for (
- notification_type="Creation",
- wmi_class="Win32_Process",
- delay_secs=2,
- Name='calc.exe'
- )
- calc_created = watcher ()
-
- Now supports timeout on the call to watcher::
-
- import pythoncom
- import wmi
- c = wmi.WMI (privileges=["Security"])
- watcher1 = c.watch_for (
- notification_type="Creation",
- wmi_class="Win32_NTLogEvent",
- Type="error"
- )
- watcher2 = c.watch_for (
- notification_type="Creation",
- wmi_class="Win32_NTLogEvent",
- Type="warning"
- )
-
- while 1:
- try:
- error_log = watcher1 (500)
- except wmi.x_wmi_timed_out:
- pythoncom.PumpWaitingMessages ()
- else:
- print error_log
-
- try:
- warning_log = watcher2 (500)
- except wmi.x_wmi_timed_out:
- pythoncom.PumpWaitingMessages ()
- else:
- print warning_log
- """
- if isinstance (wmi_class, _wmi_class):
- class_name = wmi_class._class_name
- else:
- class_name = wmi_class
- wmi_class = getattr (self, class_name)
- is_extrinsic = "__ExtrinsicEvent" in wmi_class.derivation ()
- if raw_wql:
- wql = raw_wql
- else:
- fields = set (['TargetInstance'] + fields)
- field_list = ", ".join (fields) or "*"
- if is_extrinsic:
- if where_clause:
- where = " WHERE " + " AND ".join (["%s = '%s'" % (k, v) for k, v in where_clause.items ()])
- else:
- where = ""
- wql = "SELECT " + field_list + " FROM " + class_name + where
- else:
- if where_clause:
- where = " AND " + " AND ".join (["TargetInstance.%s = '%s'" % (k, v) for k, v in where_clause.items ()])
- else:
- where = ""
- wql = \
- "SELECT %s FROM __Instance%sEvent WITHIN %d WHERE TargetInstance ISA '%s' %s" % \
- (field_list, notification_type, delay_secs, class_name, where)
-
- try:
- return _wmi_watcher (
- self._namespace.ExecNotificationQuery (wql),
- is_extrinsic=is_extrinsic,
- fields=fields
- )
- except pywintypes.com_error:
- handle_com_error ()
-
- def __getattr__ (self, attribute):
- """Offer WMI classes as simple attributes. Pass through any untrapped
- unattribute to the underlying OLE object. This means that new or
- unmapped functionality is still available to the module user.
- """
- #
- # Don't try to match against known classes as was previously
- # done since the list may not have been requested
- # (find_classes=False).
- #
- try:
- return self._cached_classes (attribute)
- except pywintypes.com_error:
- return getattr (self._namespace, attribute)
-
- def _cached_classes (self, class_name):
- """Standard caching helper which keeps track of classes
- already retrieved by name and returns the existing object
- if found. If this is the first retrieval, store it and
- pass it back
- """
- if class_name not in self._classes_map:
- self._classes_map[class_name] = _wmi_class (self, self._namespace.Get (class_name))
- return self._classes_map[class_name]
-
- def _getAttributeNames (self):
- """Return list of classes for IPython completion engine"""
- return [x for x in self.classes if not x.startswith ('__')]
-
-#
-# class _wmi_watcher
-#
-class _wmi_watcher:
- """Helper class for WMI.watch_for below (qv)"""
-
- _event_property_map = {
- "TargetInstance" : _wmi_object,
- "PreviousInstance" : _wmi_object
- }
- def __init__ (self, wmi_event, is_extrinsic, fields=[]):
- self.wmi_event = wmi_event
- self.is_extrinsic = is_extrinsic
- self.fields = fields
-
- def __call__ (self, timeout_ms=-1):
- """When called, return the instance which caused the event. Supports
- timeout in milliseconds (defaulting to infinite). If the watcher
- times out, :exc:`x_wmi_timed_out` is raised. This makes it easy to support
- watching for multiple objects.
- """
- try:
- event = self.wmi_event.NextEvent (timeout_ms)
- if self.is_extrinsic:
- return _wmi_event (event, None, self.fields)
- else:
- return _wmi_event (
- event.Properties_ ("TargetInstance").Value,
- _wmi_object (event, property_map=self._event_property_map),
- self.fields
- )
- except pywintypes.com_error:
- handle_com_error ()
-
-PROTOCOL = "winmgmts:"
-def connect (
- computer="",
- impersonation_level="",
- authentication_level="",
- authority="",
- privileges="",
- moniker="",
- wmi=None,
- namespace="",
- suffix="",
- user="",
- password="",
- find_classes=False,
- debug=False
-):
- """The WMI constructor can either take a ready-made moniker or as many
- parts of one as are necessary. Eg::
-
- c = wmi.WMI (moniker="winmgmts:{impersonationLevel=Delegate}//remote")
- # or
- c = wmi.WMI (computer="remote", privileges=["!RemoteShutdown", "Security"])
-
- I daren't link to a Microsoft URL; they change so often. Try Googling for
- WMI construct moniker and see what it comes back with.
-
- For complete control, a named argument "wmi" can be supplied, which
- should be a SWbemServices object, which you create yourself. Eg::
-
- loc = win32com.client.Dispatch("WbemScripting.SWbemLocator")
- svc = loc.ConnectServer(...)
- c = wmi.WMI(wmi=svc)
-
- This is the only way of connecting to a remote computer with a different
- username, as the moniker syntax does not allow specification of a user
- name.
-
- If the `wmi` parameter is supplied, all other parameters are ignored.
- """
- global _DEBUG
- _DEBUG = debug
-
- try:
- try:
- if wmi:
- obj = wmi
-
- elif moniker:
- if not moniker.startswith (PROTOCOL):
- moniker = PROTOCOL + moniker
- obj = GetObject (moniker)
-
- else:
- if user:
- if privileges or suffix:
- raise x_wmi_authentication ("You can't specify privileges or a suffix as well as a username")
- elif computer in (None, '', '.'):
- raise x_wmi_authentication ("You can only specify user/password for a remote connection")
- else:
- obj = connect_server (
- server=computer,
- namespace=namespace,
- user=user,
- password=password,
- authority=authority,
- impersonation_level=impersonation_level,
- authentication_level=authentication_level
- )
-
- else:
- moniker = construct_moniker (
- computer=computer,
- impersonation_level=impersonation_level,
- authentication_level=authentication_level,
- authority=authority,
- privileges=privileges,
- namespace=namespace,
- suffix=suffix
- )
- obj = GetObject (moniker)
-
- wmi_type = get_wmi_type (obj)
-
- if wmi_type == "namespace":
- return _wmi_namespace (obj, find_classes)
- elif wmi_type == "class":
- return _wmi_class (None, obj)
- elif wmi_type == "instance":
- return _wmi_object (obj)
- else:
- raise x_wmi ("Unknown moniker type")
-
- except pywintypes.com_error:
- handle_com_error ()
-
- except x_wmi_uninitialised_thread:
- raise x_wmi_uninitialised_thread ("WMI returned a syntax error: you're probably running inside a thread without first calling pythoncom.CoInitialize[Ex]")
-
-WMI = connect
-
-def construct_moniker (
- computer=None,
- impersonation_level=None,
- authentication_level=None,
- authority=None,
- privileges=None,
- namespace=None,
- suffix=None
-):
- security = []
- if impersonation_level: security.append ("impersonationLevel=%s" % impersonation_level)
- if authentication_level: security.append ("authenticationLevel=%s" % authentication_level)
- #
- # Use of the authority descriptor is invalid on the local machine
- #
- if authority and computer: security.append ("authority=%s" % authority)
- if privileges: security.append ("(%s)" % ", ".join (privileges))
-
- moniker = [PROTOCOL]
- if security: moniker.append ("{%s}!" % ",".join (security))
- if computer: moniker.append ("//%s/" % computer)
- if namespace:
- parts = re.split (r"[/\\]", namespace)
- if parts[0] != 'root':
- parts.insert (0, "root")
- moniker.append ("/".join (parts))
- if suffix: moniker.append (":%s" % suffix)
- return "".join (moniker)
-
-def get_wmi_type (obj):
- try:
- path = obj.Path_
- except AttributeError:
- return "namespace"
- else:
- if path.IsClass:
- return "class"
- else:
- return "instance"
-
-def connect_server (
- server,
- namespace = "",
- user = "",
- password = "",
- locale = "",
- authority = "",
- impersonation_level="",
- authentication_level="",
- security_flags = 0x80,
- named_value_set = None
-):
- """Return a remote server running WMI
-
- :param server: name of the server
- :param namespace: namespace to connect to - defaults to whatever's defined as default
- :param user: username to connect as, either local or domain (dom\\name or user@domain for XP)
- :param password: leave blank to use current context
- :param locale: desired locale in form MS_XXXX (eg MS_409 for Am En)
- :param authority: either "Kerberos:" or an NT domain. Not needed if included in user
- :param impersonation_level: valid WMI impersonation level
- :param security_flags: if 0, connect will wait forever; if 0x80, connect will timeout at 2 mins
- :param named_value_set: typically empty, otherwise a context-specific `SWbemNamedValueSet`
-
- Example::
-
- remote_connetion = wmi.connect_server (
- server="remote_machine", user="myname", password="mypassword"
- )
- c = wmi.WMI (wmi=remote_connection)
- """
- #
- # Thanks to Matt Mercer for example code to set
- # impersonation & authentication on ConnectServer
- #
- if impersonation_level:
- try:
- impersonation = getattr (obj._constants, "wbemImpersonationLevel%s" % impersonation_level.title ())
- except AttributeError:
- raise x_wmi_authentication ("No such impersonation level: %s" % impersonation_level)
- else:
- impersonation = None
-
- if authentication_level:
- try:
- authentication = getattr (obj._constants, "wbemAuthenticationLevel%s" % authentication_level.title ())
- except AttributeError:
- raise x_wmi_authentication ("No such impersonation level: %s" % impersonation_level)
- else:
- authentication = None
-
- server = Dispatch ("WbemScripting.SWbemLocator").\
- ConnectServer (
- server,
- namespace,
- user,
- password,
- locale,
- authority,
- security_flags,
- named_value_set
- )
- if impersonation:
- server.Security_.ImpersonationLevel = impersonation
- if authentication:
- server.Security_.AuthenticationLevel = authentication
- return server
-
-def Registry (
- computer=None,
- impersonation_level="Impersonate",
- authentication_level="Default",
- authority=None,
- privileges=None,
- moniker=None
-):
-
- warnings.warn ("This function can be implemented using wmi.WMI (namespace='DEFAULT').StdRegProv", DeprecationWarning)
- if not moniker:
- moniker = construct_moniker (
- computer=computer,
- impersonation_level=impersonation_level,
- authentication_level=authentication_level,
- authority=authority,
- privileges=privileges,
- namespace="default",
- suffix="StdRegProv"
- )
-
- try:
- return _wmi_object (GetObject (moniker))
-
- except pywintypes.com_error:
- handle_com_error ()
-
-#
-# Typical use test
-#
-if __name__ == '__main__':
- system = WMI ()
- for my_computer in system.Win32_ComputerSystem ():
- print ("Disks on", my_computer.Name)
- for disk in system.Win32_LogicalDisk ():
- print (disk.Caption, disk.Description, disk.ProviderName or "")
-
+"""
+Windows Management Instrumentation (WMI) is Microsoft's answer to
+the DMTF's Common Information Model. It allows you to query just
+about any conceivable piece of information from any computer which
+is running the necessary agent and over which have you the
+necessary authority.
+
+Since the COM implementation doesn't give much away to Python
+programmers, I've wrapped it in some lightweight classes with
+some getattr / setattr magic to ease the way. In particular:
+
+* The :class:`_wmi_namespace` object itself will determine its classes
+ and allow you to return all instances of any of them by
+ using its name as an attribute::
+
+ disks = wmi.WMI ().Win32_LogicalDisk ()
+
+* In addition, you can specify what would become the WHERE clause
+ as keyword parameters::
+
+ fixed_disks = wmi.WMI ().Win32_LogicalDisk (DriveType=3)
+
+* The objects returned by a WMI lookup are wrapped in a Python
+ class which determines their methods and classes and allows
+ you to access them as though they were Python classes. The
+ methods only allow named parameters::
+
+ for p in wmi.WMI ().Win32_Process (Name="notepad.exe"):
+ p.Terminate (Result=1)
+
+* Doing a print on one of the WMI objects will result in its
+ `GetObjectText\_` method being called, which usually produces
+ a meaningful printout of current values.
+ The repr of the object will include its full WMI path,
+ which lets you get directly to it if you need to.
+
+* You can get the associators and references of an object as
+ a list of python objects by calling the associators () and
+ references () methods on a WMI Python object::
+
+ for p in wmi.WMI ().Win32_Process (Name="notepad.exe"):
+ for r in p.references ():
+ print r
+
+ .. note::
+ Don't do this on a Win32_ComputerSystem object; it will
+ take all day and kill your machine!
+
+
+* WMI classes (as opposed to instances) are first-class
+ objects, so you can get hold of a class, and call
+ its methods or set up a watch against it::
+
+ process = wmi.WMI ().Win32_Process
+ process.Create (CommandLine="notepad.exe")
+
+* To make it easier to use in embedded systems and py2exe-style
+ executable wrappers, the module will not force early Dispatch.
+ To do this, it uses a handy hack by Thomas Heller for easy access
+ to constants.
+
+Typical usage will be::
+
+ import wmi
+
+ vodev1 = wmi.WMI ("vodev1")
+ for disk in vodev1.Win32_LogicalDisk ():
+ if disk.DriveType == 3:
+ space = 100 * long (disk.FreeSpace) / long (disk.Size)
+ print "%s has %d%% free" % (disk.Name, space)
+
+Many thanks, obviously to Mark Hammond for creating the win32all
+extensions, but also to Alex Martelli and Roger Upole, whose
+c.l.py postings pointed me in the right direction.
+Thanks especially in release 1.2 to Paul Tiemann for his code
+contributions and robust testing.
+"""
+__VERSION__ = __version__ = "1.4.6"
+
+_DEBUG = False
+
+import sys
+import datetime
+import re
+import struct
+import warnings
+
+from win32com.client import GetObject, Dispatch
+import pywintypes
+
+def signed_to_unsigned (signed):
+ """Convert a (possibly signed) long to unsigned hex. Useful
+ when converting a COM error code to the more conventional
+ 8-digit hex::
+
+ print "%08X" % signed_to_unsigned (-2147023174)
+ """
+ unsigned, = struct.unpack ("L", struct.pack ("l", signed))
+ return unsigned
+
+class SelfDeprecatingDict (object):
+ """Provides for graceful degradation of objects which
+ are currently dictionaries (and therefore accessed via
+ `.keys`, `.items`, etc.) into lists. Wraps an existing
+ `dict` and allows it to be addressed as a `dict` or as a
+ `list` during an interregnum, issuing a `DeprecationWarning`
+ if accessed as a `dict`.
+ """
+
+ dict_only = set (dir (dict)).difference (dir (list))
+
+ def __init__ (self, dictlike):
+ self.dict = dict (dictlike)
+ self.list = list (self.dict)
+
+ def __getattr__ (self, attribute):
+ if attribute in self.dict_only:
+ warnings.warn ("In future this will be a list and not a dictionary", DeprecationWarning)
+ return getattr (self.dict, attribute)
+ else:
+ return getattr (self.list, attribute)
+
+ def __iter__ (self):
+ return iter (self.list)
+
+ def __str__ (self):
+ return str (self.list)
+
+ def __repr__ (self):
+ return repr (self.list)
+
+ def __getitem__ (self, item):
+ try:
+ return self.list[item]
+ except TypeError:
+ return self.dict[item]
+
+class ProvideConstants (object):
+ """When called on a ``win32com.client.Dispatch`` object,
+ provides lazy access to constants defined in the typelib.
+ They can then be accessed as attributes of the :attr:`_constants`
+ property. (From Thomas Heller on c.l.py).
+ """
+ def __init__(self, comobj):
+ comobj.__dict__["_constants"] = self
+ self.__typecomp = \
+ comobj._oleobj_.GetTypeInfo().GetContainingTypeLib()[0].GetTypeComp()
+
+ def __getattr__(self, name):
+ if name.startswith("__") and name.endswith("__"):
+ raise AttributeError (name)
+ result = self.__typecomp.Bind(name)
+ if not result[0]:
+ raise AttributeError (name)
+ return result[1].value
+
+obj = GetObject ("winmgmts:")
+ProvideConstants (obj)
+
+wbemErrInvalidQuery = obj._constants.wbemErrInvalidQuery
+wbemErrTimedout = obj._constants.wbemErrTimedout
+wbemFlagReturnImmediately = obj._constants.wbemFlagReturnImmediately
+wbemFlagForwardOnly = obj._constants.wbemFlagForwardOnly
+
+#
+# Exceptions
+#
+class x_wmi (Exception):
+ """Ancestor of all wmi-related exceptions. Keeps track of
+ an info message and the underlying COM error if any, exposed
+ as the :attr:`com_error` attribute.
+ """
+ def __init__ (self, info="", com_error=None):
+ self.info = info
+ self.com_error = com_error
+
+ def __str__ (self):
+ return "<x_wmi: %s %s>" % (
+ self.info or "Unexpected COM Error",
+ self.com_error or "(no underlying exception)"
+ )
+
+class x_wmi_invalid_query (x_wmi):
+ "Raised when a WMI returns `wbemErrInvalidQuery`"
+ pass
+
+class x_wmi_timed_out (x_wmi):
+ "Raised when a watcher times out"
+ pass
+
+class x_wmi_no_namespace (x_wmi):
+ """Raised when an attempt is made to query or watch
+ from a class without a namespace.
+ """
+ pass
+
+class x_access_denied (x_wmi):
+ "Raised when WMI raises 80070005"
+ pass
+
+class x_wmi_authentication (x_wmi):
+ "Raised when an invalid combination of authentication properties is attempted when connecting"
+ pass
+
+class x_wmi_uninitialised_thread (x_wmi):
+ """Raised when WMI returns 800401E4 on connection, usually
+ indicating that no COM threading model has been initialised
+ """
+ pass
+
+WMI_EXCEPTIONS = {
+ signed_to_unsigned (wbemErrInvalidQuery) : x_wmi_invalid_query,
+ signed_to_unsigned (wbemErrTimedout) : x_wmi_timed_out,
+ 0x80070005 : x_access_denied,
+ 0x80041003 : x_access_denied,
+ 0x800401E4 : x_wmi_uninitialised_thread,
+}
+
+def handle_com_error (err=None):
+ """Convenience wrapper for displaying all manner of COM errors.
+ Raises a :exc:`x_wmi` exception with more useful information attached
+
+ :param err: The structure attached to a `pywintypes.com_error`
+ """
+ if err is None:
+ _, err, _ = sys.exc_info ()
+ hresult_code, hresult_name, additional_info, parameter_in_error = err.args
+ hresult_code = signed_to_unsigned (hresult_code)
+ exception_string = ["%s - %s" % (hex (hresult_code), hresult_name)]
+ scode = None
+ if additional_info:
+ wcode, source_of_error, error_description, whlp_file, whlp_context, scode = additional_info
+ scode = signed_to_unsigned (scode)
+ exception_string.append (" Error in: %s" % source_of_error)
+ exception_string.append (" %s - %s" % (hex (scode), (error_description or "").strip ()))
+ for error_code, klass in WMI_EXCEPTIONS.items ():
+ if error_code in (hresult_code, scode):
+ break
+ else:
+ klass = x_wmi
+ raise klass (com_error=err)
+
+
+BASE = datetime.datetime (1601, 1, 1)
+def from_1601 (ns100):
+ return BASE + datetime.timedelta (microseconds=int (ns100) / 10)
+
+def from_time (year=None, month=None, day=None, hours=None, minutes=None, seconds=None, microseconds=None, timezone=None):
+ """Convenience wrapper to take a series of date/time elements and return a WMI time
+ of the form `yyyymmddHHMMSS.mmmmmm+UUU`. All elements may be int, string or
+ omitted altogether. If omitted, they will be replaced in the output string
+ by a series of stars of the appropriate length.
+
+ :param year: The year element of the date/time
+ :param month: The month element of the date/time
+ :param day: The day element of the date/time
+ :param hours: The hours element of the date/time
+ :param minutes: The minutes element of the date/time
+ :param seconds: The seconds element of the date/time
+ :param microseconds: The microseconds element of the date/time
+ :param timezone: The timeezone element of the date/time
+
+ :returns: A WMI datetime string of the form: `yyyymmddHHMMSS.mmmmmm+UUU`
+ """
+ def str_or_stars (i, length):
+ if i is None:
+ return "*" * length
+ else:
+ return str (i).rjust (length, "0")
+
+ wmi_time = ""
+ wmi_time += str_or_stars (year, 4)
+ wmi_time += str_or_stars (month, 2)
+ wmi_time += str_or_stars (day, 2)
+ wmi_time += str_or_stars (hours, 2)
+ wmi_time += str_or_stars (minutes, 2)
+ wmi_time += str_or_stars (seconds, 2)
+ wmi_time += "."
+ wmi_time += str_or_stars (microseconds, 6)
+ wmi_time += "+"
+ wmi_time += str_or_stars (timezone, 3)
+
+ return wmi_time
+
+def to_time (wmi_time):
+ """Convenience wrapper to take a WMI datetime string of the form
+ yyyymmddHHMMSS.mmmmmm+UUU and return a 9-tuple containing the
+ individual elements, or None where string contains placeholder
+ stars.
+
+ :param wmi_time: The WMI datetime string in `yyyymmddHHMMSS.mmmmmm+UUU` format
+
+ :returns: A 9-tuple of (year, month, day, hours, minutes, seconds, microseconds, timezone)
+ """
+ def int_or_none (s, start, end):
+ try:
+ return int (s[start:end])
+ except ValueError:
+ return None
+
+ year = int_or_none (wmi_time, 0, 4)
+ month = int_or_none (wmi_time, 4, 6)
+ day = int_or_none (wmi_time, 6, 8)
+ hours = int_or_none (wmi_time, 8, 10)
+ minutes = int_or_none (wmi_time, 10, 12)
+ seconds = int_or_none (wmi_time, 12, 14)
+ microseconds = int_or_none (wmi_time, 15, 21)
+ timezone = wmi_time[22:]
+ if timezone == "***":
+ timezone = None
+
+ return year, month, day, hours, minutes, seconds, microseconds, timezone
+
+def _set (obj, attribute, value):
+ """Helper function to add an attribute directly into the instance
+ dictionary, bypassing possible `__getattr__` calls
+
+ :param obj: Any python object
+ :param attribute: String containing attribute name
+ :param value: Any python object
+ """
+ obj.__dict__[attribute] = value
+
+class _wmi_method:
+ """A currying sort of wrapper around a WMI method name. It
+ abstract's the method's parameters and can be called like
+ a normal Python object passing in the parameter values.
+
+ Output parameters are returned from the call as a tuple.
+ In addition, the docstring is set up as the method's
+ signature, including an indication as to whether any
+ given parameter is expecting an array, and what
+ special privileges are required to call the method.
+ """
+
+ def __init__ (self, ole_object, method_name):
+ """
+ :param ole_object: The WMI class/instance whose method is to be called
+ :param method_name: The name of the method to be called
+ """
+ try:
+ self.ole_object = Dispatch (ole_object)
+ self.method = ole_object.Methods_ (method_name)
+ self.qualifiers = {}
+ for q in self.method.Qualifiers_:
+ self.qualifiers[q.Name] = q.Value
+ self.provenance = "\n".join (self.qualifiers.get ("MappingStrings", []))
+
+ self.in_parameters = self.method.InParameters
+ self.out_parameters = self.method.OutParameters
+ if self.in_parameters is None:
+ self.in_parameter_names = []
+ else:
+ self.in_parameter_names = [(i.Name, i.IsArray) for i in self.in_parameters.Properties_]
+ if self.out_parameters is None:
+ self.out_parameter_names = []
+ else:
+ self.out_parameter_names = [(i.Name, i.IsArray) for i in self.out_parameters.Properties_]
+
+ doc = "%s (%s) => (%s)" % (
+ method_name,
+ ", ".join ([name + ("", "[]")[is_array] for (name, is_array) in self.in_parameter_names]),
+ ", ".join ([name + ("", "[]")[is_array] for (name, is_array) in self.out_parameter_names])
+ )
+ privileges = self.qualifiers.get ("Privileges", [])
+ if privileges:
+ doc += " | Needs: " + ", ".join (privileges)
+ self.__doc__ = doc
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def __call__ (self, *args, **kwargs):
+ """Execute the call to a WMI method, returning
+ a tuple (even if is of only one value) containing
+ the out and return parameters.
+ """
+ try:
+ if self.in_parameters:
+ parameter_names = {}
+ for name, is_array in self.in_parameter_names:
+ parameter_names[name] = is_array
+
+ parameters = self.in_parameters
+
+ #
+ # Check positional parameters first
+ #
+ for n_arg in range (len (args)):
+ arg = args[n_arg]
+ parameter = parameters.Properties_[n_arg]
+ if parameter.IsArray:
+ try: list (arg)
+ except TypeError: raise TypeError ("parameter %d must be iterable" % n_arg)
+ parameter.Value = arg
+
+ #
+ # If any keyword param supersedes a positional one,
+ # it'll simply overwrite it.
+ #
+ for k, v in kwargs.items ():
+ is_array = parameter_names.get (k)
+ if is_array is None:
+ raise AttributeError ("%s is not a valid parameter for %s" % (k, self.__doc__))
+ else:
+ if is_array:
+ try: list (v)
+ except TypeError: raise TypeError ("%s must be iterable" % k)
+ parameters.Properties_ (k).Value = v
+
+ result = self.ole_object.ExecMethod_ (self.method.Name, self.in_parameters)
+ else:
+ result = self.ole_object.ExecMethod_ (self.method.Name)
+
+ results = []
+ for name, is_array in self.out_parameter_names:
+ value = result.Properties_ (name).Value
+ if is_array:
+ #
+ # Thanks to Jonas Bjering for bug report and patch
+ #
+ results.append (list (value or []))
+ else:
+ results.append (value)
+ return tuple (results)
+
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def __repr__ (self):
+ return "<function %s>" % self.__doc__
+
+class _wmi_property (object):
+
+ def __init__ (self, property):
+ self.property = property
+ self.name = property.Name
+ self.value = property.Value
+ self.qualifiers = dict ((q.Name, q.Value) for q in property.Qualifiers_)
+ self.type = self.qualifiers.get ("CIMTYPE", None)
+
+ def set (self, value):
+ self.property.Value = value
+
+ def __getattr__ (self, attr):
+ return getattr (self.property, attr)
+
+#
+# class _wmi_object
+#
+class _wmi_object:
+ """The heart of the WMI module: wraps the objects returned by COM
+ ISWbemObject interface and provide readier access to their properties
+ and methods resulting in a more Pythonic interface. Not usually
+ instantiated directly, rather as a result of calling a :class:`_wmi_class`
+ on the parent :class:`_wmi_namespace`.
+
+ If you get hold of a WMI-related COM object from some other
+ source than this module, you can wrap it in one of these objects
+ to get the benefits of the module::
+
+ import win32com.client
+ import wmi
+
+ wmiobj = win32com.client.GetObject ("winmgmts:Win32_LogicalDisk.DeviceID='C:'")
+ c_drive = wmi._wmi_object (wmiobj)
+ print c_drive
+ """
+
+ def __init__ (self, ole_object, instance_of=None, fields=[], property_map={}):
+ try:
+ _set (self, "ole_object", ole_object)
+ _set (self, "id", ole_object.Path_.DisplayName.lower ())
+ _set (self, "_instance_of", instance_of)
+ _set (self, "properties", {})
+ _set (self, "methods", {})
+ _set (self, "property_map", property_map)
+ _set (self, "_associated_classes", None)
+ _set (self, "_keys", None)
+
+ if fields:
+ for field in fields:
+ self.properties[field] = None
+ else:
+ for p in ole_object.Properties_:
+ self.properties[p.Name] = None
+
+ for m in ole_object.Methods_:
+ self.methods[m.Name] = None
+
+ _set (self, "_properties", self.properties.keys ())
+ _set (self, "_methods", self.methods.keys ())
+ _set (self, "qualifiers", dict ((q.Name, q.Value) for q in self.ole_object.Qualifiers_))
+
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def __lt__ (self, other):
+ return self.id < other.id
+
+ def __str__ (self):
+ """For a call to print [object] return the OLE description
+ of the properties / values of the object
+ """
+ try:
+ return self.ole_object.GetObjectText_ ()
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def __repr__ (self):
+ """
+ Indicate both the fact that this is a wrapped WMI object
+ and the WMI object's own identifying class.
+ """
+ try:
+ return "<%s: %s>" % (self.__class__.__name__, str (self.Path_.Path))
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def _cached_properties (self, attribute):
+ if self.properties[attribute] is None:
+ self.properties[attribute] = _wmi_property (self.ole_object.Properties_ (attribute))
+ return self.properties[attribute]
+
+ def _cached_methods (self, attribute):
+ if self.methods[attribute] is None:
+ self.methods[attribute] = _wmi_method (self.ole_object, attribute)
+ return self.methods[attribute]
+
+ def __getattr__ (self, attribute):
+ """
+ Attempt to pass attribute calls to the proxied COM object.
+ If the attribute is recognised as a property, return its value;
+ if it is recognised as a method, return a method wrapper which
+ can then be called with parameters; otherwise pass the lookup
+ on to the underlying object.
+ """
+ try:
+ if attribute in self.properties:
+ property = self._cached_properties (attribute)
+ factory = self.property_map.get (attribute, self.property_map.get (property.type, lambda x: x))
+ value = factory (property.value)
+ #
+ # If this is an association, certain of its properties
+ # are actually the paths to the aspects of the association,
+ # so translate them automatically into WMI objects.
+ #
+ if property.type.startswith ("ref:"):
+ return WMI (moniker=value)
+ else:
+ return value
+ elif attribute in self.methods:
+ return self._cached_methods (attribute)
+ else:
+ return getattr (self.ole_object, attribute)
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def __setattr__ (self, attribute, value):
+ """If the attribute to be set is valid for the proxied
+ COM object, set that objects's parameter value; if not,
+ raise an exception.
+ """
+ try:
+ if attribute in self.properties:
+ self._cached_properties (attribute).set (value)
+ if self.ole_object.Path_.Path:
+ self.ole_object.Put_ ()
+ else:
+ raise AttributeError (attribute)
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def __eq__ (self, other):
+ return self.id == other.id
+
+ def __hash__ (self):
+ return hash (self.id)
+
+ def _getAttributeNames (self):
+ """Return list of methods/properties for IPython completion"""
+ attribs = [str (x) for x in self.methods.keys ()]
+ attribs.extend ([str (x) for x in self.properties.keys ()])
+ return attribs
+
+ def _get_keys (self):
+ """A WMI object is uniquely defined by a set of properties
+ which constitute its keys. Lazily retrieves the keys for this
+ instance or class.
+
+ :returns: list of key property names
+ """
+ # NB You can get the keys of an instance more directly, via
+ # Path\_.Keys but this doesn't apply to classes. The technique
+ # here appears to work for both.
+ if self._keys is None:
+ _set (self, "_keys", [])
+ for property in self.ole_object.Properties_:
+ for qualifier in property.Qualifiers_:
+ if qualifier.Name == "key" and qualifier.Value:
+ self._keys.append (property.Name)
+ return self._keys
+ keys = property (_get_keys)
+
+ def put (self):
+ """Push all outstanding property updates back to the
+ WMI database.
+ """
+ self.ole_object.Put_ ()
+
+ def set (self, **kwargs):
+ """Set several properties of the underlying object
+ at one go. This is particularly useful in combination
+ with the new () method below. However, an instance
+ which has been spawned in this way won't have enough
+ information to write pack, so only try if the
+ instance has a path.
+ """
+ if kwargs:
+ try:
+ for attribute, value in kwargs.items ():
+ if attribute in self.properties:
+ self._cached_properties (attribute).set (value)
+ else:
+ raise AttributeError (attribute)
+ #
+ # Only try to write the attributes
+ # back if the object exists.
+ #
+ if self.ole_object.Path_.Path:
+ self.ole_object.Put_ ()
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def path (self):
+ """Return the WMI URI to this object. Can be used to
+ determine the path relative to the parent namespace::
+
+ pp0 = wmi.WMI ().Win32_ParallelPort ()[0]
+ print pp0.path ().RelPath
+
+ .. Do more with this
+ """
+ try:
+ return self.ole_object.Path_
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def derivation (self):
+ """Return a tuple representing the object derivation for
+ this object, with the most specific object first::
+
+ pp0 = wmi.WMI ().Win32_ParallelPort ()[0]
+ print ' <- '.join (pp0.derivation ())
+ """
+ try:
+ return self.ole_object.Derivation_
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def _cached_associated_classes (self):
+ if self._associated_classes is None:
+ if isinstance (self, _wmi_class):
+ params = {'bSchemaOnly' : True}
+ else:
+ params = {'bClassesOnly' : True}
+ try:
+ associated_classes = dict (
+ (assoc.Path_.Class, _wmi_class (self._namespace, assoc)) for
+ assoc in self.ole_object.Associators_ (**params)
+ )
+ _set (self, "_associated_classes", associated_classes)
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ return self._associated_classes
+ associated_classes = property (_cached_associated_classes)
+
+ def associators (self, wmi_association_class="", wmi_result_class=""):
+ """Return a list of objects related to this one, optionally limited
+ either by association class (ie the name of the class which relates
+ them) or by result class (ie the name of the class which would be
+ retrieved)::
+
+ c = wmi.WMI ()
+ pp = c.Win32_ParallelPort ()[0]
+
+ for i in pp.associators (wmi_association_class="Win32_PortResource"):
+ print i
+
+ for i in pp.associators (wmi_result_class="Win32_PnPEntity"):
+ print i
+ """
+ try:
+ return [
+ _wmi_object (i) for i in \
+ self.ole_object.Associators_ (
+ strAssocClass=wmi_association_class,
+ strResultClass=wmi_result_class
+ )
+ ]
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def references (self, wmi_class=""):
+ """Return a list of associations involving this object, optionally
+ limited by the result class (the name of the association class).
+
+ NB Associations are treated specially; although WMI only returns
+ the string corresponding to the instance of each associated object,
+ this module will automatically convert that to the object itself::
+
+ c = wmi.WMI ()
+ sp = c.Win32_SerialPort ()[0]
+
+ for i in sp.references ():
+ print i
+
+ for i in sp.references (wmi_class="Win32_SerialPortSetting"):
+ print i
+ """
+ #
+ # FIXME: Allow an actual class to be passed in, using
+ # its .Path_.RelPath property to determine the string
+ #
+ try:
+ return [_wmi_object (i) for i in self.ole_object.References_ (strResultClass=wmi_class)]
+ except pywintypes.com_error:
+ handle_com_error ()
+
+#
+# class _wmi_event
+#
+class _wmi_event (_wmi_object):
+ """Slight extension of the _wmi_object class to allow
+ objects which are the result of events firing to return
+ extra information such as the type of event.
+ """
+ event_type_re = re.compile ("__Instance(Creation|Modification|Deletion)Event")
+ def __init__ (self, event, event_info, fields=[]):
+ _wmi_object.__init__ (self, event, fields=fields)
+ _set (self, "event_type", None)
+ _set (self, "timestamp", None)
+ _set (self, "previous", None)
+
+ if event_info:
+ event_type = self.event_type_re.match (event_info.Path_.Class).group (1).lower ()
+ _set (self, "event_type", event_type)
+ if hasattr (event_info, "TIME_CREATED"):
+ _set (self, "timestamp", from_1601 (event_info.TIME_CREATED))
+ if hasattr (event_info, "PreviousInstance"):
+ _set (self, "previous", event_info.PreviousInstance)
+
+#
+# class _wmi_class
+#
+class _wmi_class (_wmi_object):
+ """Currying class to assist in issuing queries against
+ a WMI namespace. The idea is that when someone issues
+ an otherwise unknown method against the WMI object, if
+ it matches a known WMI class a query object will be
+ returned which may then be called with one or more params
+ which will form the WHERE clause::
+
+ c = wmi.WMI ()
+ c_drives = c.Win32_LogicalDisk (Name='C:')
+ """
+ def __init__ (self, namespace, wmi_class):
+ _wmi_object.__init__ (self, wmi_class)
+ _set (self, "_class_name", wmi_class.Path_.Class)
+ if namespace:
+ _set (self, "_namespace", namespace)
+ else:
+ class_moniker = wmi_class.Path_.DisplayName
+ winmgmts, namespace_moniker, class_name = class_moniker.split (":")
+ namespace = _wmi_namespace (GetObject (winmgmts + ":" + namespace_moniker), False)
+ _set (self, "_namespace", namespace)
+
+ def query (self, fields=[], **where_clause):
+ """Make it slightly easier to query against the class,
+ by calling the namespace's query with the class preset.
+ Won't work if the class has been instantiated directly.
+ """
+ #
+ # FIXME: Not clear if this can ever happen
+ #
+ if self._namespace is None:
+ raise x_wmi_no_namespace ("You cannot query directly from a WMI class")
+
+ try:
+ field_list = ", ".join (fields) or "*"
+ wql = "SELECT " + field_list + " FROM " + self._class_name
+ if where_clause:
+ wql += " WHERE " + " AND ". join (["%s = '%s'" % (k, v) for k, v in where_clause.items ()])
+ return self._namespace.query (wql, self, fields)
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ __call__ = query
+
+ def watch_for (
+ self,
+ notification_type="operation",
+ delay_secs=1,
+ fields=[],
+ **where_clause
+ ):
+ if self._namespace is None:
+ raise x_wmi_no_namespace ("You cannot watch directly from a WMI class")
+
+ valid_notification_types = ("operation", "creation", "deletion", "modification")
+ if notification_type.lower () not in valid_notification_types:
+ raise x_wmi ("notification_type must be one of %s" % ", ".join (valid_notification_types))
+
+ return self._namespace.watch_for (
+ notification_type=notification_type,
+ wmi_class=self,
+ delay_secs=delay_secs,
+ fields=fields,
+ **where_clause
+ )
+
+ def instances (self):
+ """Return a list of instances of the WMI class
+ """
+ try:
+ return [_wmi_object (instance, self) for instance in self.Instances_ ()]
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def new (self, **kwargs):
+ """This is the equivalent to the raw-WMI SpawnInstance\_
+ method. Note that there are relatively few uses for
+ this, certainly fewer than you might imagine. Most
+ classes which need to create a new *real* instance
+ of themselves, eg Win32_Process, offer a .Create
+ method. SpawnInstance\_ is generally reserved for
+ instances which are passed as parameters to such
+ `.Create` methods, a common example being the
+ `Win32_SecurityDescriptor`, passed to `Win32_Share.Create`
+ and other instances which need security.
+
+ The example here is `Win32_ProcessStartup`, which
+ controls the shown/hidden state etc. of a new
+ `Win32_Process` instance::
+
+ import win32con
+ import wmi
+ c = wmi.WMI ()
+ startup = c.Win32_ProcessStartup.new (ShowWindow=win32con.SW_SHOWMINIMIZED)
+ pid, retval = c.Win32_Process.Create (
+ CommandLine="notepad.exe",
+ ProcessStartupInformation=startup
+ )
+
+ .. warning::
+ previous versions of this docstring illustrated using this function
+ to create a new process. This is *not* a good example of its use;
+ it is better handled with something like the example above.
+ """
+ try:
+ obj = _wmi_object (self.SpawnInstance_ (), self)
+ obj.set (**kwargs)
+ return obj
+ except pywintypes.com_error:
+ handle_com_error ()
+
+#
+# class _wmi_result
+#
+class _wmi_result:
+ """Simple, data only result for targeted WMI queries which request
+ data only result classes via fetch_as_classes.
+ """
+ def __init__(self, obj, attributes):
+ if attributes:
+ for attr in attributes:
+ self.__dict__[attr] = obj.Properties_ (attr).Value
+ else:
+ for p in obj.Properties_:
+ attr = p.Name
+ self.__dict__[attr] = obj.Properties_(attr).Value
+
+#
+# class WMI
+#
+class _wmi_namespace:
+ """A WMI root of a computer system. The classes attribute holds a list
+ of the classes on offer. This means you can explore a bit with
+ things like this::
+
+ c = wmi.WMI ()
+ for i in c.classes:
+ if "user" in i.lower ():
+ print i
+ """
+ def __init__ (self, namespace, find_classes):
+ _set (self, "_namespace", namespace)
+ #
+ # wmi attribute preserved for backwards compatibility
+ #
+ _set (self, "wmi", namespace)
+
+ self._classes = None
+ self._classes_map = {}
+ #
+ # Pick up the list of classes under this namespace
+ # so that they can be queried, and used as though
+ # properties of the namespace by means of the __getattr__
+ # hook below.
+ # If the namespace does not support SubclassesOf, carry on
+ # regardless
+ #
+ if find_classes:
+ _ = self.classes
+
+ def __repr__ (self):
+ return "<_wmi_namespace: %s>" % self.wmi
+
+ def __str__ (self):
+ return repr (self)
+
+ def _get_classes (self):
+ if self._classes is None:
+ self._classes = self.subclasses_of ()
+ return SelfDeprecatingDict (dict.fromkeys (self._classes))
+ classes = property (_get_classes)
+
+ def get (self, moniker):
+ try:
+ return _wmi_object (self.wmi.Get (moniker))
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def handle (self):
+ """The raw OLE object representing the WMI namespace"""
+ return self._namespace
+
+ def subclasses_of (self, root="", regex=r".*"):
+ try:
+ SubclassesOf = self._namespace.SubclassesOf
+ except AttributeError:
+ return set ()
+ else:
+ return set (
+ c.Path_.Class
+ for c in SubclassesOf (root)
+ if re.match (regex, c.Path_.Class)
+ )
+
+ def instances (self, class_name):
+ """Return a list of instances of the WMI class. This is
+ (probably) equivalent to querying with no qualifiers::
+
+ wmi.WMI ().instances ("Win32_LogicalDisk")
+ # should be the same as
+ wmi.WMI ().Win32_LogicalDisk ()
+ """
+ try:
+ return [_wmi_object (obj) for obj in self._namespace.InstancesOf (class_name)]
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def new (self, wmi_class, **kwargs):
+ """This is now implemented by a call to :meth:`_wmi_class.new`"""
+ return getattr (self, wmi_class).new (**kwargs)
+
+ new_instance_of = new
+
+ def _raw_query (self, wql):
+ """Execute a WQL query and return its raw results. Use the flags
+ recommended by Microsoft to achieve a read-only, semi-synchronous
+ query where the time is taken while looping through.
+ NB Backslashes need to be doubled up.
+ """
+ flags = wbemFlagReturnImmediately | wbemFlagForwardOnly
+ wql = wql.replace ("\\", "\\\\")
+ try:
+ return self._namespace.ExecQuery (strQuery=wql, iFlags=flags)
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def query (self, wql, instance_of=None, fields=[]):
+ """Perform an arbitrary query against a WMI object, and return
+ a list of _wmi_object representations of the results.
+ """
+ return [ _wmi_object (obj, instance_of, fields) for obj in self._raw_query(wql) ]
+
+ def fetch_as_classes (self, wmi_classname, fields=(), **where_clause):
+ """Build and execute a wql query to fetch the specified list of fields from
+ the specified wmi_classname + where_clause, then return the results as
+ a list of simple class instances with attributes matching field_list.
+
+ If fields is left empty, select * and pre-load all class attributes for
+ each class returned.
+ """
+ wql = "SELECT %s FROM %s" % (fields and ", ".join (fields) or "*", wmi_classname)
+ if where_clause:
+ wql += " WHERE " + " AND ".join (["%s = '%s'" % (k, v) for k, v in where_clause.items()])
+ return [_wmi_result (obj, fields) for obj in self._raw_query(wql)]
+
+ def fetch_as_lists (self, wmi_classname, fields, **where_clause):
+ """Build and execute a wql query to fetch the specified list of fields from
+ the specified wmi_classname + where_clause, then return the results as
+ a list of lists whose values correspond to field_list.
+ """
+ wql = "SELECT %s FROM %s" % (", ".join (fields), wmi_classname)
+ if where_clause:
+ wql += " WHERE " + " AND ".join (["%s = '%s'" % (k, v) for k, v in where_clause.items()])
+ results = []
+ for obj in self._raw_query(wql):
+ results.append ([obj.Properties_ (field).Value for field in fields])
+ return results
+
+ def watch_for (
+ self,
+ raw_wql=None,
+ notification_type="operation",
+ wmi_class=None,
+ delay_secs=1,
+ fields=[],
+ **where_clause
+ ):
+ """Set up an event tracker on a WMI event. This function
+ returns an wmi_watcher which can be called to get the
+ next event::
+
+ c = wmi.WMI ()
+
+ raw_wql = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'"
+ watcher = c.watch_for (raw_wql=raw_wql)
+ while 1:
+ process_created = watcher ()
+ print process_created.Name
+
+ # or
+
+ watcher = c.watch_for (
+ notification_type="Creation",
+ wmi_class="Win32_Process",
+ delay_secs=2,
+ Name='calc.exe'
+ )
+ calc_created = watcher ()
+
+ Now supports timeout on the call to watcher::
+
+ import pythoncom
+ import wmi
+ c = wmi.WMI (privileges=["Security"])
+ watcher1 = c.watch_for (
+ notification_type="Creation",
+ wmi_class="Win32_NTLogEvent",
+ Type="error"
+ )
+ watcher2 = c.watch_for (
+ notification_type="Creation",
+ wmi_class="Win32_NTLogEvent",
+ Type="warning"
+ )
+
+ while 1:
+ try:
+ error_log = watcher1 (500)
+ except wmi.x_wmi_timed_out:
+ pythoncom.PumpWaitingMessages ()
+ else:
+ print error_log
+
+ try:
+ warning_log = watcher2 (500)
+ except wmi.x_wmi_timed_out:
+ pythoncom.PumpWaitingMessages ()
+ else:
+ print warning_log
+ """
+ if isinstance (wmi_class, _wmi_class):
+ class_name = wmi_class._class_name
+ else:
+ class_name = wmi_class
+ wmi_class = getattr (self, class_name)
+ is_extrinsic = "__ExtrinsicEvent" in wmi_class.derivation ()
+ if raw_wql:
+ wql = raw_wql
+ else:
+ fields = set (['TargetInstance'] + fields)
+ field_list = ", ".join (fields) or "*"
+ if is_extrinsic:
+ if where_clause:
+ where = " WHERE " + " AND ".join (["%s = '%s'" % (k, v) for k, v in where_clause.items ()])
+ else:
+ where = ""
+ wql = "SELECT " + field_list + " FROM " + class_name + where
+ else:
+ if where_clause:
+ where = " AND " + " AND ".join (["TargetInstance.%s = '%s'" % (k, v) for k, v in where_clause.items ()])
+ else:
+ where = ""
+ wql = \
+ "SELECT %s FROM __Instance%sEvent WITHIN %d WHERE TargetInstance ISA '%s' %s" % \
+ (field_list, notification_type, delay_secs, class_name, where)
+
+ try:
+ return _wmi_watcher (
+ self._namespace.ExecNotificationQuery (wql),
+ is_extrinsic=is_extrinsic,
+ fields=fields
+ )
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ def __getattr__ (self, attribute):
+ """Offer WMI classes as simple attributes. Pass through any untrapped
+ unattribute to the underlying OLE object. This means that new or
+ unmapped functionality is still available to the module user.
+ """
+ #
+ # Don't try to match against known classes as was previously
+ # done since the list may not have been requested
+ # (find_classes=False).
+ #
+ try:
+ return self._cached_classes (attribute)
+ except pywintypes.com_error:
+ return getattr (self._namespace, attribute)
+
+ def _cached_classes (self, class_name):
+ """Standard caching helper which keeps track of classes
+ already retrieved by name and returns the existing object
+ if found. If this is the first retrieval, store it and
+ pass it back
+ """
+ if class_name not in self._classes_map:
+ self._classes_map[class_name] = _wmi_class (self, self._namespace.Get (class_name))
+ return self._classes_map[class_name]
+
+ def _getAttributeNames (self):
+ """Return list of classes for IPython completion engine"""
+ return [x for x in self.classes if not x.startswith ('__')]
+
+#
+# class _wmi_watcher
+#
+class _wmi_watcher:
+ """Helper class for WMI.watch_for below (qv)"""
+
+ _event_property_map = {
+ "TargetInstance" : _wmi_object,
+ "PreviousInstance" : _wmi_object
+ }
+ def __init__ (self, wmi_event, is_extrinsic, fields=[]):
+ self.wmi_event = wmi_event
+ self.is_extrinsic = is_extrinsic
+ self.fields = fields
+
+ def __call__ (self, timeout_ms=-1):
+ """When called, return the instance which caused the event. Supports
+ timeout in milliseconds (defaulting to infinite). If the watcher
+ times out, :exc:`x_wmi_timed_out` is raised. This makes it easy to support
+ watching for multiple objects.
+ """
+ try:
+ event = self.wmi_event.NextEvent (timeout_ms)
+ if self.is_extrinsic:
+ return _wmi_event (event, None, self.fields)
+ else:
+ return _wmi_event (
+ event.Properties_ ("TargetInstance").Value,
+ _wmi_object (event, property_map=self._event_property_map),
+ self.fields
+ )
+ except pywintypes.com_error:
+ handle_com_error ()
+
+PROTOCOL = "winmgmts:"
+def connect (
+ computer="",
+ impersonation_level="",
+ authentication_level="",
+ authority="",
+ privileges="",
+ moniker="",
+ wmi=None,
+ namespace="",
+ suffix="",
+ user="",
+ password="",
+ find_classes=False,
+ debug=False
+):
+ """The WMI constructor can either take a ready-made moniker or as many
+ parts of one as are necessary. Eg::
+
+ c = wmi.WMI (moniker="winmgmts:{impersonationLevel=Delegate}//remote")
+ # or
+ c = wmi.WMI (computer="remote", privileges=["!RemoteShutdown", "Security"])
+
+ I daren't link to a Microsoft URL; they change so often. Try Googling for
+ WMI construct moniker and see what it comes back with.
+
+ For complete control, a named argument "wmi" can be supplied, which
+ should be a SWbemServices object, which you create yourself. Eg::
+
+ loc = win32com.client.Dispatch("WbemScripting.SWbemLocator")
+ svc = loc.ConnectServer(...)
+ c = wmi.WMI(wmi=svc)
+
+ This is the only way of connecting to a remote computer with a different
+ username, as the moniker syntax does not allow specification of a user
+ name.
+
+ If the `wmi` parameter is supplied, all other parameters are ignored.
+ """
+ global _DEBUG
+ _DEBUG = debug
+
+ try:
+ try:
+ if wmi:
+ obj = wmi
+
+ elif moniker:
+ if not moniker.startswith (PROTOCOL):
+ moniker = PROTOCOL + moniker
+ obj = GetObject (moniker)
+
+ else:
+ if user:
+ if privileges or suffix:
+ raise x_wmi_authentication ("You can't specify privileges or a suffix as well as a username")
+ elif computer in (None, '', '.'):
+ raise x_wmi_authentication ("You can only specify user/password for a remote connection")
+ else:
+ obj = connect_server (
+ server=computer,
+ namespace=namespace,
+ user=user,
+ password=password,
+ authority=authority,
+ impersonation_level=impersonation_level,
+ authentication_level=authentication_level
+ )
+
+ else:
+ moniker = construct_moniker (
+ computer=computer,
+ impersonation_level=impersonation_level,
+ authentication_level=authentication_level,
+ authority=authority,
+ privileges=privileges,
+ namespace=namespace,
+ suffix=suffix
+ )
+ obj = GetObject (moniker)
+
+ wmi_type = get_wmi_type (obj)
+
+ if wmi_type == "namespace":
+ return _wmi_namespace (obj, find_classes)
+ elif wmi_type == "class":
+ return _wmi_class (None, obj)
+ elif wmi_type == "instance":
+ return _wmi_object (obj)
+ else:
+ raise x_wmi ("Unknown moniker type")
+
+ except pywintypes.com_error:
+ handle_com_error ()
+
+ except x_wmi_uninitialised_thread:
+ raise x_wmi_uninitialised_thread ("WMI returned a syntax error: you're probably running inside a thread without first calling pythoncom.CoInitialize[Ex]")
+
+WMI = connect
+
+def construct_moniker (
+ computer=None,
+ impersonation_level=None,
+ authentication_level=None,
+ authority=None,
+ privileges=None,
+ namespace=None,
+ suffix=None
+):
+ security = []
+ if impersonation_level: security.append ("impersonationLevel=%s" % impersonation_level)
+ if authentication_level: security.append ("authenticationLevel=%s" % authentication_level)
+ #
+ # Use of the authority descriptor is invalid on the local machine
+ #
+ if authority and computer: security.append ("authority=%s" % authority)
+ if privileges: security.append ("(%s)" % ", ".join (privileges))
+
+ moniker = [PROTOCOL]
+ if security: moniker.append ("{%s}!" % ",".join (security))
+ if computer: moniker.append ("//%s/" % computer)
+ if namespace:
+ parts = re.split (r"[/\\]", namespace)
+ if parts[0] != 'root':
+ parts.insert (0, "root")
+ moniker.append ("/".join (parts))
+ if suffix: moniker.append (":%s" % suffix)
+ return "".join (moniker)
+
+def get_wmi_type (obj):
+ try:
+ path = obj.Path_
+ except AttributeError:
+ return "namespace"
+ else:
+ if path.IsClass:
+ return "class"
+ else:
+ return "instance"
+
+def connect_server (
+ server,
+ namespace = "",
+ user = "",
+ password = "",
+ locale = "",
+ authority = "",
+ impersonation_level="",
+ authentication_level="",
+ security_flags = 0x80,
+ named_value_set = None
+):
+ """Return a remote server running WMI
+
+ :param server: name of the server
+ :param namespace: namespace to connect to - defaults to whatever's defined as default
+ :param user: username to connect as, either local or domain (dom\\name or user@domain for XP)
+ :param password: leave blank to use current context
+ :param locale: desired locale in form MS_XXXX (eg MS_409 for Am En)
+ :param authority: either "Kerberos:" or an NT domain. Not needed if included in user
+ :param impersonation_level: valid WMI impersonation level
+ :param security_flags: if 0, connect will wait forever; if 0x80, connect will timeout at 2 mins
+ :param named_value_set: typically empty, otherwise a context-specific `SWbemNamedValueSet`
+
+ Example::
+
+ remote_connetion = wmi.connect_server (
+ server="remote_machine", user="myname", password="mypassword"
+ )
+ c = wmi.WMI (wmi=remote_connection)
+ """
+ #
+ # Thanks to Matt Mercer for example code to set
+ # impersonation & authentication on ConnectServer
+ #
+ if impersonation_level:
+ try:
+ impersonation = getattr (obj._constants, "wbemImpersonationLevel%s" % impersonation_level.title ())
+ except AttributeError:
+ raise x_wmi_authentication ("No such impersonation level: %s" % impersonation_level)
+ else:
+ impersonation = None
+
+ if authentication_level:
+ try:
+ authentication = getattr (obj._constants, "wbemAuthenticationLevel%s" % authentication_level.title ())
+ except AttributeError:
+ raise x_wmi_authentication ("No such impersonation level: %s" % impersonation_level)
+ else:
+ authentication = None
+
+ server = Dispatch ("WbemScripting.SWbemLocator").\
+ ConnectServer (
+ server,
+ namespace,
+ user,
+ password,
+ locale,
+ authority,
+ security_flags,
+ named_value_set
+ )
+ if impersonation:
+ server.Security_.ImpersonationLevel = impersonation
+ if authentication:
+ server.Security_.AuthenticationLevel = authentication
+ return server
+
+def Registry (
+ computer=None,
+ impersonation_level="Impersonate",
+ authentication_level="Default",
+ authority=None,
+ privileges=None,
+ moniker=None
+):
+
+ warnings.warn ("This function can be implemented using wmi.WMI (namespace='DEFAULT').StdRegProv", DeprecationWarning)
+ if not moniker:
+ moniker = construct_moniker (
+ computer=computer,
+ impersonation_level=impersonation_level,
+ authentication_level=authentication_level,
+ authority=authority,
+ privileges=privileges,
+ namespace="default",
+ suffix="StdRegProv"
+ )
+
+ try:
+ return _wmi_object (GetObject (moniker))
+
+ except pywintypes.com_error:
+ handle_com_error ()
+
+#
+# Typical use test
+#
+if __name__ == '__main__':
+ system = WMI ()
+ for my_computer in system.Win32_ComputerSystem ():
+ print ("Disks on", my_computer.Name)
+ for disk in system.Win32_LogicalDisk ():
+ print (disk.Caption, disk.Description, disk.ProviderName or "")
+
diff --git a/test/_bsd.py b/test/_bsd.py
index 6f6c8a79..80d8d7da 100644
--- a/test/_bsd.py
+++ b/test/_bsd.py
@@ -1,141 +1,141 @@
-#!/usr/bin/env python
-#
-# $Id$
-#
-
-import unittest
-import subprocess
-import time
-import re
-import sys
-
-import psutil
-
-from test_psutil import reap_children, PYTHON, DEVNULL
-from _posix import ps
-
-
-def sysctl(cmdline):
- """Expects a sysctl command with an argument and parse the result
- returning only the value of interest.
- """
- p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
- result = p.communicate()[0].strip().split()[1]
- if sys.version_info >= (3,):
- result = str(result, sys.stdout.encoding)
- try:
- return int(result)
- except ValueError:
- return result
-
-def parse_sysctl_vmtotal(output):
- """Parse sysctl vm.vmtotal output returning total and free memory
- values.
- """
- line = output.split('\n')[4] # our line of interest
- mobj = re.match(r'Virtual\s+Memory.*Total:\s+(\d+)K,\s+Active\s+(\d+)K.*', line)
- total, active = mobj.groups()
- # values are represented in kilo bytes
- total = int(total) * 1024
- active = int(active) * 1024
- free = total - active
- return total, free
-
-
-class BSDSpecificTestCase(unittest.TestCase):
-
- def setUp(self):
- self.pid = subprocess.Popen(PYTHON, stdout=DEVNULL, stderr=DEVNULL).pid
-
- def tearDown(self):
- reap_children()
-
- def test_TOTAL_PHYMEM(self):
- sysctl_hwphymem = sysctl('sysctl hw.physmem')
- self.assertEqual(sysctl_hwphymem, psutil.TOTAL_PHYMEM)
-
- def test_avail_phymem(self):
- # This test is not particularly accurate and may fail if the OS is
- # consuming memory for other applications.
- # We just want to test that the difference between psutil result
- # and sysctl's is not too high.
- _sum = sum((sysctl("sysctl vm.stats.vm.v_inactive_count"),
- sysctl("sysctl vm.stats.vm.v_cache_count"),
- sysctl("sysctl vm.stats.vm.v_free_count")
- ))
- _pagesize = sysctl("sysctl hw.pagesize")
- sysctl_avail_phymem = _sum * _pagesize
- psutil_avail_phymem = psutil.avail_phymem()
- difference = abs(psutil_avail_phymem - sysctl_avail_phymem)
- # On my system both sysctl and psutil report the same values.
- # Let's use a tollerance of 0.5 MB and consider the test as failed
- # if we go over it.
- if difference > (0.5 * 2**20):
- self.fail("sysctl=%s; psutil=%s; difference=%s;" %(
- sysctl_avail_phymem, psutil_avail_phymem, difference))
-
- def test_total_virtmem(self):
- # This test is not particularly accurate and may fail if the OS is
- # consuming memory for other applications.
- # We just want to test that the difference between psutil result
- # and sysctl's is not too high.
- p = subprocess.Popen("sysctl vm.vmtotal", shell=1, stdout=subprocess.PIPE)
- result = p.communicate()[0].strip()
- if sys.version_info >= (3,):
- result = str(result, sys.stdout.encoding)
- sysctl_total_virtmem, _ = parse_sysctl_vmtotal(result)
- psutil_total_virtmem = psutil.total_virtmem()
- difference = abs(sysctl_total_virtmem - psutil_total_virtmem)
-
- # On my system I get a difference of 4657152 bytes, probably because
- # the system is consuming memory for this same test.
- # Assuming psutil is right, let's use a tollerance of 10 MB and consider
- # the test as failed if we go over it.
- if difference > (10 * 2**20):
- self.fail("sysctl=%s; psutil=%s; difference=%s;" %(
- sysctl_total_virtmem, psutil_total_virtmem, difference)
- )
-
- def test_avail_virtmem(self):
- # This test is not particularly accurate and may fail if the OS is
- # consuming memory for other applications.
- # We just want to test that the difference between psutil result
- # and sysctl's is not too high.
- p = subprocess.Popen("sysctl vm.vmtotal", shell=1, stdout=subprocess.PIPE)
- result = p.communicate()[0].strip()
- if sys.version_info >= (3,):
- result = str(result, sys.stdout.encoding)
- _, sysctl_avail_virtmem = parse_sysctl_vmtotal(result)
- psutil_avail_virtmem = psutil.avail_virtmem()
- difference = abs(sysctl_avail_virtmem - psutil_avail_virtmem)
- # let's assume the test is failed if difference is > 0.5 MB
- if difference > (0.5 * 2**20):
- self.fail("sysctl=%s; psutil=%s; difference=%s;" %(
- sysctl_avail_virtmem, psutil_avail_virtmem, difference))
-
- def test_cached_mem(self):
- sysctl_mem = sysctl("sysctl vm.stats.vm.v_cache_count")
- psutil_mem = psutil.cached_mem()
- self.assertEqual(sysctl_mem, psutil_mem)
-
- def test_process_create_time(self):
- cmdline = "ps -o lstart -p %s" %self.pid
- p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
- output = p.communicate()[0]
- if sys.version_info >= (3,):
- output = str(output, sys.stdout.encoding)
- start_ps = output.replace('STARTED', '').strip()
- start_psutil = psutil.Process(self.pid).create_time
- start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
- time.localtime(start_psutil))
- self.assertEqual(start_ps, start_psutil)
-
-
-if __name__ == '__main__':
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(BSDSpecificTestCase))
- unittest.TextTestRunner(verbosity=2).run(test_suite)
-
-
-
-
+#!/usr/bin/env python
+#
+# $Id$
+#
+
+import unittest
+import subprocess
+import time
+import re
+import sys
+
+import psutil
+
+from test_psutil import reap_children, PYTHON, DEVNULL
+from _posix import ps
+
+
+def sysctl(cmdline):
+ """Expects a sysctl command with an argument and parse the result
+ returning only the value of interest.
+ """
+ p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
+ result = p.communicate()[0].strip().split()[1]
+ if sys.version_info >= (3,):
+ result = str(result, sys.stdout.encoding)
+ try:
+ return int(result)
+ except ValueError:
+ return result
+
+def parse_sysctl_vmtotal(output):
+ """Parse sysctl vm.vmtotal output returning total and free memory
+ values.
+ """
+ line = output.split('\n')[4] # our line of interest
+ mobj = re.match(r'Virtual\s+Memory.*Total:\s+(\d+)K,\s+Active\s+(\d+)K.*', line)
+ total, active = mobj.groups()
+ # values are represented in kilo bytes
+ total = int(total) * 1024
+ active = int(active) * 1024
+ free = total - active
+ return total, free
+
+
+class BSDSpecificTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.pid = subprocess.Popen(PYTHON, stdout=DEVNULL, stderr=DEVNULL).pid
+
+ def tearDown(self):
+ reap_children()
+
+ def test_TOTAL_PHYMEM(self):
+ sysctl_hwphymem = sysctl('sysctl hw.physmem')
+ self.assertEqual(sysctl_hwphymem, psutil.TOTAL_PHYMEM)
+
+ def test_avail_phymem(self):
+ # This test is not particularly accurate and may fail if the OS is
+ # consuming memory for other applications.
+ # We just want to test that the difference between psutil result
+ # and sysctl's is not too high.
+ _sum = sum((sysctl("sysctl vm.stats.vm.v_inactive_count"),
+ sysctl("sysctl vm.stats.vm.v_cache_count"),
+ sysctl("sysctl vm.stats.vm.v_free_count")
+ ))
+ _pagesize = sysctl("sysctl hw.pagesize")
+ sysctl_avail_phymem = _sum * _pagesize
+ psutil_avail_phymem = psutil.avail_phymem()
+ difference = abs(psutil_avail_phymem - sysctl_avail_phymem)
+ # On my system both sysctl and psutil report the same values.
+ # Let's use a tollerance of 0.5 MB and consider the test as failed
+ # if we go over it.
+ if difference > (0.5 * 2**20):
+ self.fail("sysctl=%s; psutil=%s; difference=%s;" %(
+ sysctl_avail_phymem, psutil_avail_phymem, difference))
+
+ def test_total_virtmem(self):
+ # This test is not particularly accurate and may fail if the OS is
+ # consuming memory for other applications.
+ # We just want to test that the difference between psutil result
+ # and sysctl's is not too high.
+ p = subprocess.Popen("sysctl vm.vmtotal", shell=1, stdout=subprocess.PIPE)
+ result = p.communicate()[0].strip()
+ if sys.version_info >= (3,):
+ result = str(result, sys.stdout.encoding)
+ sysctl_total_virtmem, _ = parse_sysctl_vmtotal(result)
+ psutil_total_virtmem = psutil.total_virtmem()
+ difference = abs(sysctl_total_virtmem - psutil_total_virtmem)
+
+ # On my system I get a difference of 4657152 bytes, probably because
+ # the system is consuming memory for this same test.
+ # Assuming psutil is right, let's use a tollerance of 10 MB and consider
+ # the test as failed if we go over it.
+ if difference > (10 * 2**20):
+ self.fail("sysctl=%s; psutil=%s; difference=%s;" %(
+ sysctl_total_virtmem, psutil_total_virtmem, difference)
+ )
+
+ def test_avail_virtmem(self):
+ # This test is not particularly accurate and may fail if the OS is
+ # consuming memory for other applications.
+ # We just want to test that the difference between psutil result
+ # and sysctl's is not too high.
+ p = subprocess.Popen("sysctl vm.vmtotal", shell=1, stdout=subprocess.PIPE)
+ result = p.communicate()[0].strip()
+ if sys.version_info >= (3,):
+ result = str(result, sys.stdout.encoding)
+ _, sysctl_avail_virtmem = parse_sysctl_vmtotal(result)
+ psutil_avail_virtmem = psutil.avail_virtmem()
+ difference = abs(sysctl_avail_virtmem - psutil_avail_virtmem)
+ # let's assume the test is failed if difference is > 0.5 MB
+ if difference > (0.5 * 2**20):
+ self.fail("sysctl=%s; psutil=%s; difference=%s;" %(
+ sysctl_avail_virtmem, psutil_avail_virtmem, difference))
+
+ def test_cached_mem(self):
+ sysctl_mem = sysctl("sysctl vm.stats.vm.v_cache_count")
+ psutil_mem = psutil.cached_mem()
+ self.assertEqual(sysctl_mem, psutil_mem)
+
+ def test_process_create_time(self):
+ cmdline = "ps -o lstart -p %s" %self.pid
+ p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
+ output = p.communicate()[0]
+ if sys.version_info >= (3,):
+ output = str(output, sys.stdout.encoding)
+ start_ps = output.replace('STARTED', '').strip()
+ start_psutil = psutil.Process(self.pid).create_time
+ start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
+ time.localtime(start_psutil))
+ self.assertEqual(start_ps, start_psutil)
+
+
+if __name__ == '__main__':
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(unittest.makeSuite(BSDSpecificTestCase))
+ unittest.TextTestRunner(verbosity=2).run(test_suite)
+
+
+
+
diff --git a/test/_linux.py b/test/_linux.py
index c29ebc7b..f60c33fc 100644
--- a/test/_linux.py
+++ b/test/_linux.py
@@ -1,24 +1,24 @@
-#!/usr/bin/env python
-#
-# $Id$
-#
-
-import unittest
-import subprocess
-import time
-
-import psutil
-
-from test_psutil import PYTHON, DEVNULL, reap_children
-from _posix import ps
-
-
-class LinuxSpecificTestCase(unittest.TestCase):
-
- def setUp(self):
- self.pid = subprocess.Popen(PYTHON, stdout=DEVNULL, stderr=DEVNULL).pid
-
- def tearDown(self):
- reap_children()
-
-
+#!/usr/bin/env python
+#
+# $Id$
+#
+
+import unittest
+import subprocess
+import time
+
+import psutil
+
+from test_psutil import PYTHON, DEVNULL, reap_children
+from _posix import ps
+
+
+class LinuxSpecificTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.pid = subprocess.Popen(PYTHON, stdout=DEVNULL, stderr=DEVNULL).pid
+
+ def tearDown(self):
+ reap_children()
+
+
diff --git a/test/_osx.py b/test/_osx.py
index 41818d93..3192448b 100644
--- a/test/_osx.py
+++ b/test/_osx.py
@@ -1,64 +1,64 @@
-#!/usr/bin/env python
-#
-# $Id$
-#
-
-import unittest
-import subprocess
-import time
-import re
-import sys
-
-import psutil
-
-from test_psutil import reap_children, PYTHON, DEVNULL
-#from _posix import ps
-
-
-def sysctl(cmdline):
- """Expects a sysctl command with an argument and parse the result
- returning only the value of interest.
- """
- p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
- result = p.communicate()[0].strip().split()[1]
- if sys.version_info >= (3,):
- result = str(result, sys.stdout.encoding)
- try:
- return int(result)
- except ValueError:
- return result
-
-
-class OSXSpecificTestCase(unittest.TestCase):
-
- def setUp(self):
- self.pid = subprocess.Popen(PYTHON, stdout=DEVNULL, stderr=DEVNULL).pid
-
- def tearDown(self):
- reap_children()
-
- def test_TOTAL_PHYMEM(self):
- sysctl_hwphymem = sysctl('sysctl hw.physmem')
- self.assertEqual(sysctl_hwphymem, psutil.TOTAL_PHYMEM)
-
- def test_process_create_time(self):
- cmdline = "ps -o lstart -p %s" %self.pid
- p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
- output = p.communicate()[0]
- if sys.version_info >= (3,):
- output = str(output, sys.stdout.encoding)
- start_ps = output.replace('STARTED', '').strip()
- start_psutil = psutil.Process(self.pid).create_time
- start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
- time.localtime(start_psutil))
- self.assertEqual(start_ps, start_psutil)
-
-
-if __name__ == '__main__':
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(OSXSpecificTestCase))
- unittest.TextTestRunner(verbosity=2).run(test_suite)
-
-
-
-
+#!/usr/bin/env python
+#
+# $Id$
+#
+
+import unittest
+import subprocess
+import time
+import re
+import sys
+
+import psutil
+
+from test_psutil import reap_children, PYTHON, DEVNULL
+#from _posix import ps
+
+
+def sysctl(cmdline):
+ """Expects a sysctl command with an argument and parse the result
+ returning only the value of interest.
+ """
+ p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
+ result = p.communicate()[0].strip().split()[1]
+ if sys.version_info >= (3,):
+ result = str(result, sys.stdout.encoding)
+ try:
+ return int(result)
+ except ValueError:
+ return result
+
+
+class OSXSpecificTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.pid = subprocess.Popen(PYTHON, stdout=DEVNULL, stderr=DEVNULL).pid
+
+ def tearDown(self):
+ reap_children()
+
+ def test_TOTAL_PHYMEM(self):
+ sysctl_hwphymem = sysctl('sysctl hw.physmem')
+ self.assertEqual(sysctl_hwphymem, psutil.TOTAL_PHYMEM)
+
+ def test_process_create_time(self):
+ cmdline = "ps -o lstart -p %s" %self.pid
+ p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
+ output = p.communicate()[0]
+ if sys.version_info >= (3,):
+ output = str(output, sys.stdout.encoding)
+ start_ps = output.replace('STARTED', '').strip()
+ start_psutil = psutil.Process(self.pid).create_time
+ start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
+ time.localtime(start_psutil))
+ self.assertEqual(start_ps, start_psutil)
+
+
+if __name__ == '__main__':
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(unittest.makeSuite(OSXSpecificTestCase))
+ unittest.TextTestRunner(verbosity=2).run(test_suite)
+
+
+
+
diff --git a/test/_posix.py b/test/_posix.py
index 11a1d8a9..82e98a00 100755
--- a/test/_posix.py
+++ b/test/_posix.py
@@ -1,136 +1,136 @@
-#!/usr/bin/env python
-#
-# $Id$
-#
-
-import unittest
-import subprocess
-import time
-import sys
-import os
-
-import psutil
-
-from test_psutil import kill, PYTHON, DEVNULL
-
-
-def ps(cmd):
- """Expects a ps command with a -o argument and parse the result
- returning only the value of interest.
- """
- if not sys.platform.lower().startswith("linux"):
- cmd = cmd.replace(" --no-headers ", " ")
- p = subprocess.Popen(cmd, shell=1, stdout=subprocess.PIPE)
- output = p.communicate()[0].strip()
- if sys.version_info >= (3,):
- output = str(output, sys.stdout.encoding)
- if not sys.platform.lower().startswith("linux"):
- output = output.split('\n')[1]
- try:
- return int(output)
- except ValueError:
- return output
-
-
-class PosixSpecificTestCase(unittest.TestCase):
- """Compare psutil results against 'ps' command line utility."""
-
- # for ps -o arguments see: http://unixhelp.ed.ac.uk/CGI/man-cgi?ps
-
- def setUp(self):
- self.pid = subprocess.Popen([PYTHON, "-E", "-O"], stdout=DEVNULL, stderr=DEVNULL).pid
-
- def tearDown(self):
- kill(self.pid)
-
- def test_process_parent_pid(self):
- ppid_ps = ps("ps --no-headers -o ppid -p %s" %self.pid)
- ppid_psutil = psutil.Process(self.pid).ppid
- self.assertEqual(ppid_ps, ppid_psutil)
-
- def test_process_uid(self):
- uid_ps = ps("ps --no-headers -o uid -p %s" %self.pid)
- uid_psutil = psutil.Process(self.pid).uid
- self.assertEqual(uid_ps, uid_psutil)
-
- def test_process_gid(self):
- gid_ps = ps("ps --no-headers -o rgid -p %s" %self.pid)
- gid_psutil = psutil.Process(self.pid).gid
- self.assertEqual(gid_ps, gid_psutil)
-
- def test_process_username(self):
- username_ps = ps("ps --no-headers -o user -p %s" %self.pid)
- username_psutil = psutil.Process(self.pid).username
- self.assertEqual(username_ps, username_psutil)
-
- def test_process_rss_memory(self):
- # give python interpreter some time to properly initialize
- # so that the results are the same
- time.sleep(0.1)
- rss_ps = ps("ps --no-headers -o rss -p %s" %self.pid)
- rss_psutil = psutil.Process(self.pid).get_memory_info()[0] / 1024
- self.assertEqual(rss_ps, rss_psutil)
-
- def test_process_vsz_memory(self):
- # give python interpreter some time to properly initialize
- # so that the results are the same
- time.sleep(0.1)
- vsz_ps = ps("ps --no-headers -o vsz -p %s" %self.pid)
- vsz_psutil = psutil.Process(self.pid).get_memory_info()[1] / 1024
- self.assertEqual(vsz_ps, vsz_psutil)
-
- def test_process_name(self):
- # use command + arg since "comm" keyword not supported on all platforms
- name_ps = ps("ps --no-headers -o command -p %s" %self.pid).split(' ')[0]
- # remove path if there is any, from the command
- name_ps = os.path.basename(name_ps)
- name_psutil = psutil.Process(self.pid).name
- self.assertEqual(name_ps, name_psutil)
-
- def test_process_pathname(self):
- ps_pathname = ps("ps --no-headers -o command -p %s" %self.pid).split(' ')[0]
- psutil_pathname = os.path.join(psutil.Process(self.pid).path,
- psutil.Process(self.pid).name)
- self.assertEqual(ps_pathname, psutil_pathname)
-
- def test_process_cmdline(self):
- ps_cmdline = ps("ps --no-headers -o command -p %s" %self.pid)
- psutil_cmdline = " ".join(psutil.Process(self.pid).cmdline)
- self.assertEqual(ps_cmdline, psutil_cmdline)
-
- def test_get_pids(self):
- # Note: this test might fail if the OS is starting/killing
- # other processes in the meantime
- p = subprocess.Popen(["ps", "ax", "-o", "pid"], stdout=subprocess.PIPE)
- output = p.communicate()[0].strip()
- if sys.version_info >= (3,):
- output = str(output, sys.stdout.encoding)
- output = output.replace('PID', '')
- p.wait()
- pids_ps = []
- for pid in output.split('\n'):
- if pid:
- pids_ps.append(int(pid.strip()))
- # remove ps subprocess pid which is supposed to be dead in meantime
- pids_ps.remove(p.pid)
- # not all systems include pid 0 in their list but psutil does so
- # we force it
- if 0 not in pids_ps:
- pids_ps.append(0)
-
- pids_psutil = psutil.get_pid_list()
- pids_ps.sort()
- pids_psutil.sort()
-
- if pids_ps != pids_psutil:
- difference = filter(lambda x:x not in pids_ps, pids_psutil) + \
- filter(lambda x:x not in pids_psutil, pids_ps)
- self.fail("difference: " + str(difference))
-
-
-if __name__ == '__main__':
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(PosixSpecificTestCase))
- unittest.TextTestRunner(verbosity=2).run(test_suite)
-
-
+#!/usr/bin/env python
+#
+# $Id$
+#
+
+import unittest
+import subprocess
+import time
+import sys
+import os
+
+import psutil
+
+from test_psutil import kill, PYTHON, DEVNULL
+
+
+def ps(cmd):
+ """Expects a ps command with a -o argument and parse the result
+ returning only the value of interest.
+ """
+ if not sys.platform.lower().startswith("linux"):
+ cmd = cmd.replace(" --no-headers ", " ")
+ p = subprocess.Popen(cmd, shell=1, stdout=subprocess.PIPE)
+ output = p.communicate()[0].strip()
+ if sys.version_info >= (3,):
+ output = str(output, sys.stdout.encoding)
+ if not sys.platform.lower().startswith("linux"):
+ output = output.split('\n')[1]
+ try:
+ return int(output)
+ except ValueError:
+ return output
+
+
+class PosixSpecificTestCase(unittest.TestCase):
+ """Compare psutil results against 'ps' command line utility."""
+
+ # for ps -o arguments see: http://unixhelp.ed.ac.uk/CGI/man-cgi?ps
+
+ def setUp(self):
+ self.pid = subprocess.Popen([PYTHON, "-E", "-O"], stdout=DEVNULL, stderr=DEVNULL).pid
+
+ def tearDown(self):
+ kill(self.pid)
+
+ def test_process_parent_pid(self):
+ ppid_ps = ps("ps --no-headers -o ppid -p %s" %self.pid)
+ ppid_psutil = psutil.Process(self.pid).ppid
+ self.assertEqual(ppid_ps, ppid_psutil)
+
+ def test_process_uid(self):
+ uid_ps = ps("ps --no-headers -o uid -p %s" %self.pid)
+ uid_psutil = psutil.Process(self.pid).uid
+ self.assertEqual(uid_ps, uid_psutil)
+
+ def test_process_gid(self):
+ gid_ps = ps("ps --no-headers -o rgid -p %s" %self.pid)
+ gid_psutil = psutil.Process(self.pid).gid
+ self.assertEqual(gid_ps, gid_psutil)
+
+ def test_process_username(self):
+ username_ps = ps("ps --no-headers -o user -p %s" %self.pid)
+ username_psutil = psutil.Process(self.pid).username
+ self.assertEqual(username_ps, username_psutil)
+
+ def test_process_rss_memory(self):
+ # give python interpreter some time to properly initialize
+ # so that the results are the same
+ time.sleep(0.1)
+ rss_ps = ps("ps --no-headers -o rss -p %s" %self.pid)
+ rss_psutil = psutil.Process(self.pid).get_memory_info()[0] / 1024
+ self.assertEqual(rss_ps, rss_psutil)
+
+ def test_process_vsz_memory(self):
+ # give python interpreter some time to properly initialize
+ # so that the results are the same
+ time.sleep(0.1)
+ vsz_ps = ps("ps --no-headers -o vsz -p %s" %self.pid)
+ vsz_psutil = psutil.Process(self.pid).get_memory_info()[1] / 1024
+ self.assertEqual(vsz_ps, vsz_psutil)
+
+ def test_process_name(self):
+ # use command + arg since "comm" keyword not supported on all platforms
+ name_ps = ps("ps --no-headers -o command -p %s" %self.pid).split(' ')[0]
+ # remove path if there is any, from the command
+ name_ps = os.path.basename(name_ps)
+ name_psutil = psutil.Process(self.pid).name
+ self.assertEqual(name_ps, name_psutil)
+
+ def test_process_pathname(self):
+ ps_pathname = ps("ps --no-headers -o command -p %s" %self.pid).split(' ')[0]
+ psutil_pathname = os.path.join(psutil.Process(self.pid).path,
+ psutil.Process(self.pid).name)
+ self.assertEqual(ps_pathname, psutil_pathname)
+
+ def test_process_cmdline(self):
+ ps_cmdline = ps("ps --no-headers -o command -p %s" %self.pid)
+ psutil_cmdline = " ".join(psutil.Process(self.pid).cmdline)
+ self.assertEqual(ps_cmdline, psutil_cmdline)
+
+ def test_get_pids(self):
+ # Note: this test might fail if the OS is starting/killing
+ # other processes in the meantime
+ p = subprocess.Popen(["ps", "ax", "-o", "pid"], stdout=subprocess.PIPE)
+ output = p.communicate()[0].strip()
+ if sys.version_info >= (3,):
+ output = str(output, sys.stdout.encoding)
+ output = output.replace('PID', '')
+ p.wait()
+ pids_ps = []
+ for pid in output.split('\n'):
+ if pid:
+ pids_ps.append(int(pid.strip()))
+ # remove ps subprocess pid which is supposed to be dead in meantime
+ pids_ps.remove(p.pid)
+ # not all systems include pid 0 in their list but psutil does so
+ # we force it
+ if 0 not in pids_ps:
+ pids_ps.append(0)
+
+ pids_psutil = psutil.get_pid_list()
+ pids_ps.sort()
+ pids_psutil.sort()
+
+ if pids_ps != pids_psutil:
+ difference = filter(lambda x:x not in pids_ps, pids_psutil) + \
+ filter(lambda x:x not in pids_psutil, pids_ps)
+ self.fail("difference: " + str(difference))
+
+
+if __name__ == '__main__':
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(unittest.makeSuite(PosixSpecificTestCase))
+ unittest.TextTestRunner(verbosity=2).run(test_suite)
+
+
diff --git a/test/_windows.py b/test/_windows.py
index 0d6fcb4b..bcd9abec 100644
--- a/test/_windows.py
+++ b/test/_windows.py
@@ -1,144 +1,144 @@
-#!/usr/bin/env python
-#
-# $Id$
-#
-
-
-import os
-import unittest
-import platform
-import subprocess
-import signal
-import time
-import warnings
-
-import psutil
-from test_psutil import reap_children, PYTHON, DEVNULL
-try:
- from psutil import wmi
-except ImportError:
- warnings.warn("Can't import WMI module; Windows specific tests disabled",
- RuntimeWarning)
- wmi = None
-
-
-class WindowsSpecificTestCase(unittest.TestCase):
-
- def setUp(self):
- self.pid = subprocess.Popen([PYTHON, "-E", "-O"], stdout=DEVNULL, stderr=DEVNULL).pid
-
- def tearDown(self):
- reap_children()
-
- def test_issue_24(self):
- p = psutil.Process(0)
- self.assertRaises(psutil.AccessDenied, p.kill)
-
- def test_pid_4(self):
- p = psutil.Process(4)
- self.assertEqual(p.name, 'System')
- # use __str__ to access all common Process properties to check
- # that nothing strange happens
- str(p)
- p.username
- self.assertTrue(p.create_time >= 0.0)
- try:
- rss, vms = p.get_memory_info()
- except psutil.AccessDenied:
- # expected on Windows Vista and Windows 7
- if not platform.uname()[1] in ('vista', 'win-7'):
- raise
- else:
- self.assertTrue(rss > 0)
- self.assertEqual(vms, 0)
-
- def test_signal(self):
- p = psutil.Process(self.pid)
- self.assertRaises(ValueError, p.send_signal, signal.SIGINT)
-
- if wmi is not None:
-
- # --- Process class tests
-
- def test_process_name(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- self.assertEqual(p.name, w.Caption)
-
- def test_process_path(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- self.assertEqual(os.path.join(p.path, p.name), w.ExecutablePath)
-
- def test_process_cmdline(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- self.assertEqual(' '.join(p.cmdline), w.CommandLine)
-
- def test_process_username(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- domain, _, username = w.GetOwner()
- username = "%s\\%s" %(domain, username)
- self.assertEqual(p.username, username)
-
- def test_process_rss_memory(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- rss = p.get_memory_info()[0]
- self.assertEqual(rss, int(w.WorkingSetSize))
-
- def test_process_vsz_memory(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- vsz = p.get_memory_info()[1]
- self.assertEqual(vsz, int(w.PageFileUsage) * 1024)
-
- def test_process_create_time(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- wmic_create = str(w.CreationDate.split('.')[0])
- psutil_create = time.strftime("%Y%m%d%H%M%S",
- time.localtime(p.create_time))
- self.assertEqual(wmic_create, psutil_create)
-
-
- # --- psutil namespace functions and constants tests
-
- def test_NUM_CPUS(self):
- num_cpus = int(os.environ['NUMBER_OF_PROCESSORS'])
- self.assertEqual(num_cpus, psutil.NUM_CPUS)
-
- def test_TOTAL_PHYMEM(self):
- w = wmi.WMI().Win32_ComputerSystem()[0]
- self.assertEqual(int(w.TotalPhysicalMemory), psutil.TOTAL_PHYMEM)
-
- def test__UPTIME(self):
- # _UPTIME constant is not public but it is used internally
- # as value to return for pid 0 creation time.
- # WMI behaves the same.
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(0)
- wmic_create = str(w.CreationDate.split('.')[0])
- psutil_create = time.strftime("%Y%m%d%H%M%S",
- time.localtime(p.create_time))
-
- def test_get_pids(self):
- # Note: this test might fail if the OS is starting/killing
- # other processes in the meantime
- w = wmi.WMI().Win32_Process()
- wmi_pids = [x.ProcessId for x in w]
- wmi_pids.sort()
- psutil_pids = psutil.get_pid_list()
- psutil_pids.sort()
- if wmi_pids != psutil_pids:
- difference = filter(lambda x:x not in wmi_pids, psutil_pids) + \
- filter(lambda x:x not in psutil_pids, wmi_pids)
- self.fail("difference: " + str(difference))
-
-
-if __name__ == '__main__':
- test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(WindowsSpecificTestCase))
- unittest.TextTestRunner(verbosity=2).run(test_suite)
-
+#!/usr/bin/env python
+#
+# $Id$
+#
+
+
+import os
+import unittest
+import platform
+import subprocess
+import signal
+import time
+import warnings
+
+import psutil
+from test_psutil import reap_children, PYTHON, DEVNULL
+try:
+ from psutil import wmi
+except ImportError:
+ warnings.warn("Can't import WMI module; Windows specific tests disabled",
+ RuntimeWarning)
+ wmi = None
+
+
+class WindowsSpecificTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.pid = subprocess.Popen([PYTHON, "-E", "-O"], stdout=DEVNULL, stderr=DEVNULL).pid
+
+ def tearDown(self):
+ reap_children()
+
+ def test_issue_24(self):
+ p = psutil.Process(0)
+ self.assertRaises(psutil.AccessDenied, p.kill)
+
+ def test_pid_4(self):
+ p = psutil.Process(4)
+ self.assertEqual(p.name, 'System')
+ # use __str__ to access all common Process properties to check
+ # that nothing strange happens
+ str(p)
+ p.username
+ self.assertTrue(p.create_time >= 0.0)
+ try:
+ rss, vms = p.get_memory_info()
+ except psutil.AccessDenied:
+ # expected on Windows Vista and Windows 7
+ if not platform.uname()[1] in ('vista', 'win-7'):
+ raise
+ else:
+ self.assertTrue(rss > 0)
+ self.assertEqual(vms, 0)
+
+ def test_signal(self):
+ p = psutil.Process(self.pid)
+ self.assertRaises(ValueError, p.send_signal, signal.SIGINT)
+
+ if wmi is not None:
+
+ # --- Process class tests
+
+ def test_process_name(self):
+ w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+ p = psutil.Process(self.pid)
+ self.assertEqual(p.name, w.Caption)
+
+ def test_process_path(self):
+ w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+ p = psutil.Process(self.pid)
+ self.assertEqual(os.path.join(p.path, p.name), w.ExecutablePath)
+
+ def test_process_cmdline(self):
+ w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+ p = psutil.Process(self.pid)
+ self.assertEqual(' '.join(p.cmdline), w.CommandLine)
+
+ def test_process_username(self):
+ w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+ p = psutil.Process(self.pid)
+ domain, _, username = w.GetOwner()
+ username = "%s\\%s" %(domain, username)
+ self.assertEqual(p.username, username)
+
+ def test_process_rss_memory(self):
+ w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+ p = psutil.Process(self.pid)
+ rss = p.get_memory_info()[0]
+ self.assertEqual(rss, int(w.WorkingSetSize))
+
+ def test_process_vsz_memory(self):
+ w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+ p = psutil.Process(self.pid)
+ vsz = p.get_memory_info()[1]
+ self.assertEqual(vsz, int(w.PageFileUsage) * 1024)
+
+ def test_process_create_time(self):
+ w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+ p = psutil.Process(self.pid)
+ wmic_create = str(w.CreationDate.split('.')[0])
+ psutil_create = time.strftime("%Y%m%d%H%M%S",
+ time.localtime(p.create_time))
+ self.assertEqual(wmic_create, psutil_create)
+
+
+ # --- psutil namespace functions and constants tests
+
+ def test_NUM_CPUS(self):
+ num_cpus = int(os.environ['NUMBER_OF_PROCESSORS'])
+ self.assertEqual(num_cpus, psutil.NUM_CPUS)
+
+ def test_TOTAL_PHYMEM(self):
+ w = wmi.WMI().Win32_ComputerSystem()[0]
+ self.assertEqual(int(w.TotalPhysicalMemory), psutil.TOTAL_PHYMEM)
+
+ def test__UPTIME(self):
+ # _UPTIME constant is not public but it is used internally
+ # as value to return for pid 0 creation time.
+ # WMI behaves the same.
+ w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+ p = psutil.Process(0)
+ wmic_create = str(w.CreationDate.split('.')[0])
+ psutil_create = time.strftime("%Y%m%d%H%M%S",
+ time.localtime(p.create_time))
+
+ def test_get_pids(self):
+ # Note: this test might fail if the OS is starting/killing
+ # other processes in the meantime
+ w = wmi.WMI().Win32_Process()
+ wmi_pids = [x.ProcessId for x in w]
+ wmi_pids.sort()
+ psutil_pids = psutil.get_pid_list()
+ psutil_pids.sort()
+ if wmi_pids != psutil_pids:
+ difference = filter(lambda x:x not in wmi_pids, psutil_pids) + \
+ filter(lambda x:x not in psutil_pids, wmi_pids)
+ self.fail("difference: " + str(difference))
+
+
+if __name__ == '__main__':
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(unittest.makeSuite(WindowsSpecificTestCase))
+ unittest.TextTestRunner(verbosity=2).run(test_suite)
+
diff --git a/test/test_psutil.py b/test/test_psutil.py
index 91052175..647362c9 100644
--- a/test/test_psutil.py
+++ b/test/test_psutil.py
@@ -43,8 +43,8 @@ def kill(pid):
psutil.Process(pid).kill()
def reap_children():
- """Kill any subprocess started by this test suite and ensure that
- no zombies stick around to hog resources and create problems when
+ """Kill any subprocess started by this test suite and ensure that
+ no zombies stick around to hog resources and create problems when
looking for refleaks.
"""
if os.name == 'posix':
@@ -552,7 +552,7 @@ class TestCase(unittest.TestCase):
if os.name == 'posix':
if hasattr(os, 'getuid') and os.getuid() > 0:
def test_unix_access_denied(self):
- p = psutil.Process(1)
+ p = psutil.Process(1)
self.assertRaises(psutil.AccessDenied, p.kill)
self.assertRaises(psutil.AccessDenied, p.send_signal, signal.SIGTERM)
self.assertRaises(psutil.AccessDenied, p.terminate)
@@ -582,7 +582,7 @@ if hasattr(os, 'getuid'):
if sys.platform.lower().startswith("linux"):
- # overridden tests known to raise AccessDenied when run
+ # overridden tests known to raise AccessDenied when run
# as limited user
def test_getcwd(self):
self.assertRaises(psutil.AccessDenied, TestCase.test_getcwd, self)