web-dev-qa-db-fra.com

Python vérifie si un processus est en cours d'exécution ou non

J'essaie de créer un script python que je lancerai plus tard en tant que service. Maintenant, je veux exécuter une partie du code uniquement lorsque iTunes est en cours d'exécution. D'après certaines recherches, des recherches ont montré que parcourir la liste complète des commandes, puis rechercher l'application correspondant à cette liste coûte cher. 

J'ai découvert que les processus sur les systèmes d'exploitation UNIX créent un fichier de verrouillage pour signaler qu'un programme est en cours d'exécution. Nous pouvons alors utiliser os.stat(location_of_file) pour vérifier si le fichier existe afin de déterminer si un programme est en cours d'exécution ou non.

Un fichier de verrouillage similaire a-t-il été créé sous Windows?

Sinon, quels sont les différents moyens en Python permettant de déterminer si un processus est en cours d'exécution ou non?

J'utilise python 2.7 et l'interface COM iTunes.

25
nightf0x

Vous ne pouvez pas compter sur les fichiers de verrouillage sous Linux ou Windows. Je voudrais juste mordre la balle et parcourir tous les programmes en cours d'exécution. Je ne crois vraiment pas que ce sera aussi "cher" que vous le pensez. psutil est un excellent câble de module python multiplate-forme qui énumère tous les programmes en cours d'exécution sur un système.

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

Les fichiers de verrouillage ne sont généralement pas utilisés sous Windows (et rarement sous Unix). Généralement, lorsqu'un programme Windows veut voir si une autre instance est déjà en cours d'exécution, il appelle FindWindow avec un titre ou un nom de classe connu.

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
6
Gabe

Bien que @zeller ait dit qu'il existe déjà un exemple d'utilisation de tasklist. Comme je cherchais/ 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)
    # 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()

et maintenant vous pouvez faire:

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

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

Pour éviter d'appeler cela plusieurs fois et avoir ainsi une vue d'ensemble de tous les processus, vous pouvez effectuer les opérations suivantes:

# get info dict about all running processes
call = 'TASKLIST', '/FO', 'CSV'
output = subprocess.check_output(call)
# 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] )
print(proc_dict.keys())
5
ewerybody

Psutil suggéré par Mark , est vraiment la meilleure solution, son seul inconvénient est la licence compatible GPL. Si cela pose problème, vous pouvez appeler les commandes d'informations de processus de Windows: wmic process où WMI est disponible (XP pro, Vista, win7) ou tasklist. Voici une description pour le faire: Comment appeler un programme externe en python et récupérer le code de sortie et de retour? (pas le seul moyen possible ...)

3
zeller

win32ui.FindWindow(classname, None) renvoie un handle de fenêtre si une fenêtre avec le nom de classe donné est trouvée. Sinon, il soulève window32ui.error.

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."

J'ai trouvé que le nom de classe de la fenêtre pour l'icône de la barre des tâches Dropbox était DropboxTrayIcon utilisant Autohotkey Window Spy.

Voir également

MSDN FindWindow

3
Jisang Yoo

J'aimerais ajouter cette solution à la liste, à des fins historiques. Il vous permet de découvrir basé sur .exe au lieu du titre de la fenêtre, et renvoie également la mémoire utilisée et 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

Une tranche d’exemple de sortie:

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
3
std''OrgnlDave

Si ne peut pas compter sur le nom du processus, comme les scripts python, qui aura toujours python.exe comme nom de processus. Si trouvé cette méthode très pratique

import psutil
psutil.pid_exists(pid)

consultez la documentation pour plus d'informations http://psutil.readthedocs.io/en/latest/#psutil.pid_exists

2
MNIF AKRAM

Seriez-vous satisfait de votre commande Python exécutant un autre programme pour obtenir les informations?

Si tel est le cas, je vous conseillerais de consulter PsList et toutes ses options. Par exemple, ce qui suit vous informera de tout processus en cours d’iTunes

PsList iTunes

Si vous parvenez à comprendre comment interpréter les résultats, cela devrait vous aider.

Modifier:

Lorsque je ne suis pas sous iTunes, je reçois le message suivant:

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

Avec iTunes en cours d'exécution, je reçois cette ligne supplémentaire:

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

Cependant, la commande suivante imprime des informations uniquement sur le programme iTunes lui-même, c'est-à-dire avec l'argument -e:

pslist -e iTunes
2
Clare Macrae

Cela fonctionne bien

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
0