3

I have a simple piece of code taken mostly from this answer, with some adjustments:

import psutil

try:
    if "firefox.exe" in (p.name() for p in psutil.process_iter()):
        print('Firefox is running')
    else:
        print('Firefox is not running')
except Exception as e:
    print(e)

If Firefox is running when I run this code, it prints the expected Firefox is running. But if Firefox isn't running, I get psutil.AccessDenied (pid=9092) instead of the expected Firefox is not running.

I also noticed that if firefox.exe is mis-spelled, I get the AccessDenied error again. I could just print('Firefox is not running') inside the except block, but that doesn't seem very smart.

Does anyone know why this is happening?

Rachel Gallen
  • 27,943
  • 21
  • 72
  • 81
Have a nice day
  • 1,007
  • 5
  • 11

2 Answers2

2

process_iter() allows you to specify the attributes that should be returned. So tell it to just return the names, and compare them.

if any(p.info['name'] == "firefox.exe" for p in psutil.process_iter(['name'])):

Got this from the documentation:

Find process by name

Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Because this (p.name() for p in psutil.process_iter()) is a generator, and when the process is not spotted in a user processes, it tries to list the system ones. Consider suppressing this exception with warning like print('Firefox is not running by current user')

I get psutil.AccessDenied (pid=9092)

Other possible reason is that process was terminated after the iterator got pid to retrieve. Since you can't be sure the process won't disappear while your python process was suspended by OS scheduler, ignorance seems to be a legit solution.

UPD: aaand that's the case (dead process yielded) https://github.com/giampaolo/psutil/blob/c3e63b4dd59f1724a7fa29371e53dfa7f46cbcd3/psutil/__init__.py#L1453-L1465

When you tried to access the process name (which wasn't cached), it was already dead. So I would just skip it instead of behaving like it's running.

madbird
  • 1,326
  • 7
  • 11