Description
From g.rodola on July 13, 2012 13:31:17
This is similar to issue 297 but for Windows.
On Windows we use native APIs to extract process information such as CPU times,
memory info etc.
Such APIs systematically fail with an AccessDenied exception for any process
owned by NT AUTHORITY SYSTEM user (system processes, typically) imposing a
severe usability issue for those who want to inspect processes not owned by the
current user (e.g. a task manager like app).
Example:
PID NAME RSS MEM
0 System Idle Process 0
4 System ACCESS DENIED
172 conhost.exe 3723264
248 svchost.exe ACCESS DENIED
284 smss.exe ACCESS DENIED
320 svchost.exe ACCESS DENIED
328 TSVNCache.exe 7729152
376 csrss.exe ACCESS DENIED
408 wininit.exe ACCESS DENIED
424 csrss.exe ACCESS DENIED
464 winlogon.exe ACCESS DENIED
512 services.exe ACCESS DENIED
520 lsass.exe ACCESS DENIED
528 lsm.exe ACCESS DENIED
564 python.exe 8675328
572 procexp64.exe 18870272
628 svchost.exe ACCESS DENIED
688 VBoxService.exe ACCESS DENIED
728 svchost.exe ACCESS DENIED
796 explorer.exe 46014464
816 svchost.exe ACCESS DENIED
856 svchost.exe ACCESS DENIED
900 svchost.exe ACCESS DENIED
968 svchost.exe ACCESS DENIED
1064 dllhost.exe 5214208
1280 cmd.exe 6815744
1296 svchost.exe ACCESS DENIED
1600 python.exe 5832704
1632 svchost.exe ACCESS DENIED
1772 taskhost.exe 5554176
1840 dwm.exe 3375104
1852 TortoiseUDiff.exe 4263936
1952 VBoxTray.exe 3039232
2036 procexp.exe 5611520
I realized that a considerable amount of process information which we currently
extract by using documented Windows APIs is also stored in the
SYSTEM_PROCESS_INFORMATION structure, which can be obtained via
NtQuerySystemInformation():
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/System%20Information/Structures/SYSTEM_PROCESS_INFORMATION.html
The peculiarity of NtQuerySystemInformation() is that it succeeds for
basically ALL processes except for PID 0!
On the other hand it is sensibly slower compared to using native APIs.
As such, a natural approach seems to be using the current, native APIs
implementation and fall back on using NtQuerySystemInformation in case of
permission error. Something like:
def get_process_cpu_times():
try:
return _psutil_mswindows.get_process_cpu_times() # native API method
except AccessDenied:
return _psutil_mswindows.get_process_cpu_times_2() # alternative method
Obviously, a robust set of unit tests will have to be written in order to make
sure that the two methods return the exact same value.
Follows a summary of Process methods which can apparently take benefit from
this approach:
---------------------------------------------------------------------------
| psutil method | Win API | PINFO struct |
---------------------------------------------------------------------------
| create_time | GetProcessTimes | CreateTime |
| nice/priority | GetPriorityClass | BasePriority |
| get_cpu_times() | GetProcessTimes | UserTime, KernelTime |
| get_cpu_percent() | GetProcessTimes | UserTime, KernelTime |
| get_num_handles() | GetProcessHandleCount | HandleCount |
| get_memory_info() | GetProcessMemoryInfo | WorkingSetSize and others |
| get_ext_memory_info() | GetProcessMemoryInfo | WorkingSetSize and others |
| get_memory_percent() | GetProcessMemoryInfo | WorkingSetSize and others |
| get_threads() | GetThreadTimes | Threads* |
| get_io_counters() | GetProcessIoCounters | *OperationCount |
---------------------------------------------------------------------------
@wj32.64, given the massive amount of code rewriting involved, I'd like to hear
your opinion about this. Does it sounds reasonable and reliable to you?
Original issue: http://code.google.com/p/psutil/issues/detail?id=304