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.
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())
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
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())
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 ...)
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
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
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
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
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