Description
Sometimes, for some odd reason, the psutil returns a process with a name of None
.
For instance, using this code:
import psutil
import time
def fetchProcesses():
for p in psutil.process_iter():
try:
p.dict = p.as_dict(['pid', 'name', 'cpu_percent'])
if p.dict['cpu_percent'] > 70:
print p.dict
except psutil.NoSuchProcess:
pass
fetchProcesses()
time.sleep(0.5)
fetchProcesses()
I'll get output like this:
{'name': u'PlexScriptHost.exe', 'cpu_percent': 97.4}
{'name': u'PlexDlnaServer.exe', 'cpu_percent': 97.4}
{'name': None, 'cpu_percent': 85.2}
So I then tried playing with win32api a bit to grab the file name:
def fetchProcesses():
for p in psutil.process_iter():
try:
p.dict = p.as_dict(['pid', 'name', 'cpu_percent'])
if p.dict['cpu_percent'] > 70:
if p.dict['name'] == None:
print "DEBUG: need to correct process name"
print "DEBUG: opening PID: %i" % p.dict['pid']
pHandle = win32api.OpenProcess(
win32con.PROCESS_VM_READ | win32con.PROCESS_QUERY_INFORMATION,
0, p.dict['pid'])
if pHandle:
filen = win32process.GetModuleFileNameEx(pHandle, 0)
print "Got:", filen
Which resulted in this error:
{'pid': 7272, 'name': u'PlexScriptHost.exe', 'cpu_percent': 92.3}
{'pid': 9360, 'name': u'PlexDlnaServer.exe', 'cpu_percent': 96.5}
DEBUG: need to correct process name
DEBUG: opening PID: 23320
Traceback (most recent call last):
File "monitor.py", line 27, in <module>
fetchProcesses()
File "monitor.py", line 17, in fetchProcesses
0, p.dict['pid'])
pywintypes.error: (5, 'OpenProcess', 'Access is denied.')
Supposedly, you can do some Windows magic to ask for special privileges for making OpenProcess work, but it seemed a bit too hacky at the time, so I avoided it. (You may opt to try this in the future, though! OpenProcessToken
is the starting point.)
I took a cursory look at your code, and it looks like you use OpenProcess as well for process information. (I might be wrong about how you use it... feel free to correct me!)
To work around the issue, I wrote this:
import win32com
from win32com.client import GetObject
WMI = GetObject('winmgmts:')
processes = WMI.InstancesOf('Win32_Process')
for process in processes:
try:
print('PID: ', process.Properties_('ProcessID').Value, 'process: ', process.Properties_('Name').Value)
except:
pass
This does the trick for me, yielding:
...
('process: ', u'blender-app.exe', 'PID: ', 23320)
...
For now, using the above code will be a workaround in case this happens.
It looks like using WMI might be an interesting vector to try. (It might even potentially fix #549... maybe.) What do you think?