Check if a process is running or not on Windows?

PythonWindowsPython 2.7

Python Problem Overview


I am trying to create a python script which I will later run as a service. Now I want to run a particular part of the code only when iTunes is running. I understand from some research that polling the entire command list and then searching for the application for that list is expensive.

I found out that processes on UNIX-based operating systems create a lock file to notify that a program is currently running, at which point we can use os.stat(location_of_file) to check if the file exists to determine if a program is running or not.

Is there a similar lock file created on Windows?

If not what are the various ways in Python by which we can determine if a process is running or not?

I am using python 2.7 and iTunes COM interface.

Python Solutions


Solution 1 - Python

You can not rely on lock files in Linux or Windows. I would just bite the bullet and iterate through all the running programs. I really do not believe it will be as "expensive" as you think. psutil is an excellent cross-platform python module cable of enumerating all the running programs on a system.

import psutil    
"someProgram" in (p.name() for p in psutil.process_iter())

Solution 2 - Python

Although @zeller said it already here is an example how to use tasklist. As I was just looking for vanilla python alternatives...

import subprocess

def process_exists(process_name):
    call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name
    # use buildin check_output right away
    output = subprocess.check_output(call).decode()
    # check in last line for process name
    last_line = output.strip().split('\r\n')[-1]
    # because Fail message could be translated
    return last_line.lower().startswith(process_name.lower())

and now you can do:

>>> process_exists('eclipse.exe')
True

>>> process_exists('AJKGVSJGSCSeclipse.exe')
False

To avoid calling this multiple times and have an overview of all the processes this way you could do something like:

# get info dict about all running processes
import subprocess
output = subprocess.check_output(('TASKLIST', '/FO', 'CSV')).decode()
# get rid of extra " and split into lines
output = output.replace('"', '').split('\r\n')
keys = output[0].split(',')
proc_list = [i.split(',') for i in output[1:] if i]
# make dict with proc names as keys and dicts with the extra nfo as values
proc_dict = dict((i[0], dict(zip(keys[1:], i[1:]))) for i in proc_list)
for name, values in sorted(proc_dict.items(), key=lambda x: x[0].lower()):
    print('%s: %s' % (name, values))

Solution 3 - Python

win32ui.FindWindow(classname, None) returns a window handle if any window with the given class name is found. It raises window32ui.error otherwise.

import win32ui

def WindowExists(classname):
    try:
        win32ui.FindWindow(classname, None)
    except win32ui.error:
        return False
    else:
        return True

if WindowExists("DropboxTrayIcon"):
    print "Dropbox is running, sir."
else:
    print "Dropbox is running..... not."

I found that the window class name for the Dropbox tray icon was DropboxTrayIcon using Autohotkey Window Spy.

See also

MSDN FindWindow

Solution 4 - Python

Lock files are generally not used on Windows (and rarely on Unix). Typically when a Windows program wants to see if another instance of itself is already running, it will call http://docs.activestate.com/activepython/2.5/pywin32/win32ui__FindWindow_meth.html">`FindWindow`</a> with a known title or class name.

def iTunesRunning():
    import win32ui
    # may need FindWindow("iTunes", None) or FindWindow(None, "iTunes")
    # or something similar
    if FindWindow("iTunes", "iTunes"):
        print "Found an iTunes window"
        return True

Solution 5 - Python

I'd like to add this solution to the list, for historical purposes. It allows you to find out based on .exe instead of window title, and also returns memory used & PID.

processes = subprocess.Popen('tasklist', stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE).communicate()[0]
# Put a regex for exact matches, or a simple 'in' for naive matches

A slice of example output:

notepad.exe                  13944 Console                    1     11,920 K
python.exe                    5240 Console                    1     28,616 K
conhost.exe                   9796 Console                    1      7,812 K
svchost.exe                   1052 Services                   0     18,524 K
iTunes.exe                    1108 Console                    1    157,764 K

Solution 6 - Python

Psutil suggested by Mark, is really the best solution, its only drawback is the GPL compatible license. If that's a problem, then you can invoke Windows' process info commands: wmic process where WMI is available (XP pro, vista, win7) or tasklist. Here is a description to do it: https://stackoverflow.com/questions/706989/how-to-call-an-external-program-in-python-and-retrieve-the-output-and-return-cod (not the only possible way...)

Solution 7 - Python

import psutil

for p in psutil.process_iter(attrs=['pid', 'name']):
    if "itunes.exe" in (p.info['name']).lower():
        print("yes", (p.info['name']).lower())

for python 3.7


import psutil

for p in psutil.process_iter(attrs=['pid', 'name']):
    if p.info['name'] == "itunes.exe":
        print("yes", (p.info['name']))

This works for python 3.8 & psutil 5.7.0, windows

Solution 8 - Python

Would you be happy with your Python command running another program to get the info?

If so, I'd suggest you have a look at PsList and all its options. For example, The following would tell you about any running iTunes process

PsList itunes

If you can work out how to interpret the results, this should hopefully get you going.

Edit:

When I'm not running iTunes, I get the following:

pslist v1.29 - Sysinternals PsList
Copyright (C) 2000-2009 Mark Russinovich
Sysinternals

Process information for CLARESPC:

Name                Pid Pri Thd  Hnd   Priv        CPU Time    Elapsed Time
iTunesHelper       3784   8  10  229   3164     0:00:00.046     3:41:05.053

With itunes running, I get this one extra line:

iTunes              928   8  24  813 106168     0:00:08.734     0:02:08.672

However, the following command prints out info only about the iTunes program itself, i.e. with the -e argument:

pslist -e itunes

Solution 9 - Python

If can't rely on the process name like python scripts which will always have python.exe as process name. If found this method very handy

import psutil
psutil.pid_exists(pid)

check docs for further info http://psutil.readthedocs.io/en/latest/#psutil.pid_exists

Solution 10 - Python

There is a python module called wmi.

import wmi
c=wmi.WMI()
def check_process_running(str_):
    if(c.Win32_Process(name=str_)):
        print("Process is running")
    else:
        print("Process is not running")

		 
check_process_running("yourprocess.exe")  

Solution 11 - Python

Try this code:

import subprocess
def process_exists(process_name):
    progs = str(subprocess.check_output('tasklist'))
    if process_name in progs:
        return True
    else:
        return False

And to check if the process is running:

if process_exists('example.exe'):
    #do something

Solution 12 - Python

According to the ewerybody post: https://stackoverflow.com/a/29275361/7530957

Multiple problems can arise:

  • Multiple processes with the same name
  • Name of the long process

The 'ewerybody's' code will not work if the process name is long. So there is a problem with this line:

last_line.lower().startswith(process_name.lower())

Because last_line will be shorter than the process name.

So if you just want to know if a process/processes is/are active:

from subprocess import check_output

def process_exists(process_name):
    call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name
    if check_output(call).splitlines()[3:]:
        return True

Instead for all the information of a process/processes

from subprocess import check_output

def process_exists(process_name):
    call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name
    processes = []
    for process in check_output(call).splitlines()[3:]:
        process = process.decode()
        processes.append(process.split())
    return processes

Solution 13 - Python

This method below can be used to detect weather the process [ eg: notepad.exe ] is runing or not.

from pymem import Pymem
import pymem

while (True):

	try:

		pm = Pymem('notepad.exe')
		print('Notepad Started And Is Running....')

	except:

		print ('Notepad Is Not Running....')

Pymem Package Is Needed. To Install It,

pip install pymem

Solution 14 - Python

This works nicely

def running():
    n=0# number of instances of the program running 
    prog=[line.split() for line in subprocess.check_output("tasklist").splitlines()]
    [prog.pop(e) for e in [0,1,2]] #useless 
    for task in prog:
        if task[0]=="itunes.exe":
            n=n+1
    if n>0:
        return True
    else:
        return False

Solution 15 - Python

If you are testing application with Behave you can use pywinauto. Similar with previously comment, you can use this function:

def check_if_app_is_running(context, processName):
try:
    context.controller = pywinauto.Application(backend='uia').connect(best_match = processName, timeout = 5)
    context.controller.top_window().set_focus()
    return True
except pywinauto.application.ProcessNotFoundError:
    pass
return False

backend can be 'uia' or 'win32'

timeout if for force reconnect with the applicaction during 5 seconds.

Solution 16 - Python

import subprocess as sp
for v in str(sp.check_output('powershell "gps | where {$_.MainWindowTitle}"')).split(' '):
    if len(v) is not 0 and '-' not in v and '\\r\\' not in v and 'iTunes' in v: print('Found !')

Solution 17 - Python

import psutil

def check_process_status(process_name):
	"""
	Return status of process based on process name.
	"""
	process_status = [ proc.status() for proc in psutil.process_iter() if proc.name() == process_name ]
	if process_status:
		print("Process name %s and staus %s"%(process_name, process_status[0]))
	else:
		print("Process name not valid", process_name)

Solution 18 - Python

Psutil is the best solution for this.

import psutil

processes = list(p.name() for p in psutil.process_iter())
# print(processes)
count = processes.count("<app_name>.exe")

if count == 1:
    logging.info('Application started')
    # print('Application started')
else:
    logging.info('Process is already running!')
    # print('Process is already running!')
    sys.exit(0)                          # Stops duplicate instance from running

Solution 19 - Python

You can just use os.kill sending a 0 signal (that doesn't kill the process) and checking for errors.

from os import kill

def check_if_running(pid):
    try:
        kill(pid, 0)
    except:
        return False
    return True

Solution 20 - Python

I liked the solution of @ewerybody with this little change

import subprocess

def process_exists(process_name):
    call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name
    # use buildin check_output right away
    output = subprocess.check_output(call).decode()

    # check in last line for process name
    last_line = output.split('\r\n')
    
    #first result is 3 because the headers
    #or in case more than one, you can use the last one using [-2] index
    data = " ".join(last_line[3].split()).split()  

    #return a list with the name and pid 
    return( [data[0], data[1]] )  

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionnightf0xView Question on Stackoverflow
Solution 1 - PythonMarkView Answer on Stackoverflow
Solution 2 - PythonewerybodyView Answer on Stackoverflow
Solution 3 - PythonJisang YooView Answer on Stackoverflow
Solution 4 - PythonGabeView Answer on Stackoverflow
Solution 5 - Pythonstd''OrgnlDaveView Answer on Stackoverflow
Solution 6 - PythonzellerView Answer on Stackoverflow
Solution 7 - Python0m3rView Answer on Stackoverflow
Solution 8 - PythonClare MacraeView Answer on Stackoverflow
Solution 9 - PythonAkramView Answer on Stackoverflow
Solution 10 - PythonA. FaiyazView Answer on Stackoverflow
Solution 11 - Pythonmg34View Answer on Stackoverflow
Solution 12 - PythonSqualoView Answer on Stackoverflow
Solution 13 - PythonAK-HACKS-OR-TRICKSView Answer on Stackoverflow
Solution 14 - PythonPaulo Castro Da SilvaView Answer on Stackoverflow
Solution 15 - PythonPiniView Answer on Stackoverflow
Solution 16 - PythonNaveen YadavView Answer on Stackoverflow
Solution 17 - PythonViraj WadateView Answer on Stackoverflow
Solution 18 - PythonVoldemortView Answer on Stackoverflow
Solution 19 - PythonthalescrView Answer on Stackoverflow
Solution 20 - PythonOscar AlbertView Answer on Stackoverflow