1
1
#!/usr/bin/env python
3
# $Id: _psmswindows.py 1157 2011-10-14 18:36:03Z g.rodola $
3
# $Id: _psmswindows.py 1397 2012-06-29 16:33:08Z g.rodola $
5
5
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
6
6
# Use of this source code is governed by a BSD-style license that can be
16
16
import _psutil_mswindows
17
17
from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
18
from psutil._compat import namedtuple
19
18
from psutil._common import *
19
from psutil._compat import PY3, xrange, long
21
21
# Windows specific extended namespace
22
22
__extra__all__ = ["ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
42
41
REALTIME_PRIORITY_CLASS,
45
def _win32_QueryDosDevice(s):
46
return _psutil_mswindows.win32_QueryDosDevice(s)
48
def _convert_raw_path(s):
49
# convert paths using native DOS format like:
50
# "\Device\HarddiskVolume1\Windows\systemew\file.txt"
51
# into: "C:\Windows\systemew\file.txt"
52
if PY3 and not isinstance(s, str):
54
rawdrive = '\\'.join(s.split('\\')[:3])
55
driveletter = _win32_QueryDosDevice(rawdrive)
56
return os.path.join(driveletter, s[len(rawdrive):])
45
59
# --- public functions
47
61
def phymem_usage():
49
63
all = _psutil_mswindows.get_system_phymem()
50
64
total, free, total_pagef, avail_pagef, total_virt, free_virt, percent = all
51
65
used = total - free
52
return ntuple_sysmeminfo(total, used, free, round(percent, 1))
66
return nt_sysmeminfo(total, used, free, round(percent, 1))
54
68
def virtmem_usage():
55
69
"""Virtual system memory as a (total, used, free) tuple."""
59
73
used = total_virt - free_virt
60
74
percent = usage_percent(used, total_virt, _round=1)
61
return ntuple_sysmeminfo(total_virt, used, free_virt, percent)
75
return nt_sysmeminfo(total_virt, used, free_virt, percent)
63
77
def get_disk_usage(path):
64
78
"""Return disk usage associated with path."""
66
80
total, free = _psutil_mswindows.get_disk_usage(path)
67
except WindowsError, err:
82
err = sys.exc_info()[1]
68
83
if not os.path.exists(path):
69
84
raise OSError(errno.ENOENT, "No such file or directory: '%s'" % path)
71
86
used = total - free
72
87
percent = usage_percent(used, total, _round=1)
73
return ntuple_diskinfo(total, used, free, percent)
88
return nt_diskinfo(total, used, free, percent)
75
90
def disk_partitions(all):
76
91
"""Return disk partitions."""
78
drive_letters = _psutil_mswindows.win32_GetLogicalDriveStrings()
79
for letter in drive_letters:
81
type = _psutil_mswindows.win32_GetDriveType(letter)
82
if not os.path.exists(mountpoint):
83
# usually a CD-ROM device with no disk inserted
86
if type not in ('cdrom', 'fixed', 'removable'):
90
ntuple = ntuple_partition(letter, mountpoint, type)
91
retlist.append(ntuple)
92
rawlist = _psutil_mswindows.get_disk_partitions(all)
93
return [nt_partition(*x) for x in rawlist]
95
96
_cputimes_ntuple = namedtuple('cputimes', 'user system idle')
117
def get_system_users():
118
"""Return currently connected users as a list of namedtuples."""
120
rawlist = _psutil_mswindows.get_system_users()
122
user, hostname, tstamp = item
123
nt = nt_user(user, None, hostname, tstamp)
116
127
get_pid_list = _psutil_mswindows.get_pid_list
117
128
pid_exists = _psutil_mswindows.pid_exists
118
129
network_io_counters = _psutil_mswindows.get_network_io_counters
128
139
def wrapper(self, *args, **kwargs):
130
141
return callable(self, *args, **kwargs)
143
err = sys.exc_info()[1]
132
144
if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED):
133
145
raise AccessDenied(self.pid, self._process_name)
134
146
if err.errno == errno.ESRCH:
152
164
"""Return process name as a string of limited len (15)."""
153
165
return _psutil_mswindows.get_process_name(self.pid)
155
168
def get_process_exe(self):
156
# no such thing as "exe" on Windows; it will maybe be determined
157
# later from cmdline[0]
158
if not pid_exists(self.pid):
159
raise NoSuchProcess(self.pid, self._process_name)
160
if self.pid in (0, 4):
161
raise AccessDenied(self.pid, self._process_name)
169
exe = _convert_raw_path(_psutil_mswindows.get_process_exe(self.pid))
170
# Note: if the folder containing the executable is changed
171
# GetProcessImageFileName() returns the previous name, hence
172
# this check. An empty string signals to try to guess the exe
173
# from cmdline later.
174
if not os.path.exists(exe):
165
179
def get_process_cmdline(self):
176
190
"""Returns a tuple or RSS/VMS memory usage in bytes."""
177
191
# special case for 0 (kernel processes) PID
178
192
if self.pid == 0:
179
return ntuple_meminfo(0, 0)
193
return nt_meminfo(0, 0)
180
194
rss, vms = _psutil_mswindows.get_memory_info(self.pid)
181
return ntuple_meminfo(rss, vms)
195
return nt_meminfo(rss, vms)
197
nt_mmap_grouped = namedtuple('mmap', 'path rss')
198
nt_mmap_ext = namedtuple('mmap', 'addr perms path rss')
200
def get_memory_maps(self):
202
raw = _psutil_mswindows.get_process_memory_maps(self.pid)
204
# XXX - can't use wrap_exceptions decorator as we're
205
# returning a generator; probably needs refactoring.
206
err = sys.exc_info()[1]
207
if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED):
208
raise AccessDenied(self.pid, self._process_name)
209
if err.errno == errno.ESRCH:
210
raise NoSuchProcess(self.pid, self._process_name)
213
for addr, perm, path, rss in raw:
214
path = _convert_raw_path(path)
216
yield (addr, perm, path, rss)
184
219
def kill_process(self):
201
236
def get_process_username(self):
202
237
"""Return the name of the user that owns the process"""
203
if self.pid in (0, 4) or self.pid == 8 and _WIN2000:
238
if self.pid in (0, 4):
204
239
return 'NT AUTHORITY\\SYSTEM'
205
return _psutil_mswindows.get_process_username(self.pid);
240
return _psutil_mswindows.get_process_username(self.pid)
208
243
def get_process_create_time(self):
209
244
# special case for kernel process PIDs; return system boot time
210
if self.pid in (0, 4) or self.pid == 8 and _WIN2000:
245
if self.pid in (0, 4):
212
247
return _psutil_mswindows.get_process_create_time(self.pid)
220
255
rawlist = _psutil_mswindows.get_process_threads(self.pid)
222
257
for thread_id, utime, stime in rawlist:
223
ntuple = ntuple_thread(thread_id, utime, stime)
258
ntuple = nt_thread(thread_id, utime, stime)
224
259
retlist.append(ntuple)
228
263
def get_cpu_times(self):
229
264
user, system = _psutil_mswindows.get_process_cpu_times(self.pid)
230
return ntuple_cputimes(user, system)
265
return nt_cputimes(user, system)
233
268
def suspend_process(self):
241
276
def get_process_cwd(self):
242
if self.pid in (0, 4) or self.pid == 8 and _WIN2000:
277
if self.pid in (0, 4):
243
278
raise AccessDenied(self.pid, self._process_name)
244
279
# return a normalized pathname since the native C function appends
245
280
# "\\" at the and of the path
257
292
# (e.g. "C:\") by using Windows's QueryDosDevice()
258
293
raw_file_names = _psutil_mswindows.get_process_open_files(self.pid)
259
294
for file in raw_file_names:
260
if sys.version_info >= (3,):
261
file = file.decode('utf8')
262
if file.startswith('\\Device\\'):
263
rawdrive = '\\'.join(file.split('\\')[:3])
264
driveletter = _psutil_mswindows.win32_QueryDosDevice(rawdrive)
265
file = file.replace(rawdrive, driveletter)
266
if os.path.isfile(file) and file not in retlist:
267
ntuple = ntuple_openfile(file, -1)
268
retlist.append(ntuple)
295
file = _convert_raw_path(file)
296
if os.path.isfile(file) and file not in retlist:
297
ntuple = nt_openfile(file, -1)
298
retlist.append(ntuple)
275
305
% (kind, ', '.join([repr(x) for x in conn_tmap])))
276
306
families, types = conn_tmap[kind]
277
307
ret = _psutil_mswindows.get_process_connections(self.pid, families, types)
278
return [ntuple_connection(*conn) for conn in ret]
308
return [nt_connection(*conn) for conn in ret]
281
311
def get_process_nice(self):
289
319
def get_process_io_counters(self):
290
320
rc, wc, rb, wb =_psutil_mswindows.get_process_io_counters(self.pid)
291
return ntuple_io(rc, wc, rb, wb)
321
return nt_io(rc, wc, rb, wb)
294
324
def get_process_status(self):
297
327
return STATUS_STOPPED
299
329
return STATUS_RUNNING
332
def get_process_cpu_affinity(self):
333
from_bitmask = lambda x: [i for i in xrange(64) if (1 << i) & x]
334
bitmask = _psutil_mswindows.get_process_cpu_affinity(self.pid)
335
return from_bitmask(bitmask)
338
def set_process_cpu_affinity(self, value):
341
raise ValueError("invalid argument %r" % l)
344
if not isinstance(b, (int, long)) or b < 0:
345
raise ValueError("invalid argument %r" % b)
349
# SetProcessAffinityMask() states that ERROR_INVALID_PARAMETER
350
# is returned for an invalid CPU but this seems not to be true,
351
# therefore we check CPUs validy beforehand.
352
allcpus = list(range(len(get_system_per_cpu_times())))
354
if cpu not in allcpus:
355
raise ValueError("invalid CPU %i" % cpu)
357
bitmask = to_bitmask(value)
358
_psutil_mswindows.set_process_cpu_affinity(self.pid, bitmask)
361
def get_num_handles(self):
362
return _psutil_mswindows.get_process_num_handles(self.pid)