it-swarm.com.de

Python prüfen, ob ein Prozess läuft oder nicht

Ich versuche ein Python-Skript zu erstellen, das ich später als Dienst ausführen werde. Jetzt möchte ich einen bestimmten Teil des Codes nur ausführen, wenn iTunes ausgeführt wird. Aus einigen Nachforschungen geht hervor, dass das Abfragen der gesamten Befehlsliste und das anschließende Suchen nach der Anwendung für diese Liste teuer ist. 

Ich fand heraus, dass Prozesse auf UNIX-basierten Betriebssystemen eine Sperrdatei erstellen, um zu benachrichtigen, dass derzeit ein Programm ausgeführt wird. An diesem Punkt können Sie mit os.stat(location_of_file) prüfen, ob die Datei vorhanden ist, um festzustellen, ob ein Programm ausgeführt wird oder nicht.

Gibt es eine ähnliche Sperrdatei, die unter Windows erstellt wurde?

Wenn nicht, auf welche Weise können wir in Python feststellen, ob ein Prozess ausgeführt wird oder nicht?

Ich verwende Python 2.7 und die COM-Schnittstelle von iTunes.

25
nightf0x

Sie können sich auf Sperrdateien in Linux oder Windows nicht verlassen. Ich würde nur die Kugel beißen und alle laufenden Programme durchlaufen. Ich glaube wirklich nicht, dass es so "teuer" sein wird, wie Sie denken. psutil ist ein hervorragendes plattformübergreifendes Python-Modulkabel, das alle auf einem System laufenden Programme auflistet.

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

Sperrdateien werden im Allgemeinen nicht unter Windows (und selten unter Unix) verwendet. Normalerweise, wenn ein Windows-Programm sehen möchte, ob bereits eine andere Instanz von sich selbst ausgeführt wird, ruft es FindWindow mit einem bekannten Titel oder Klassennamen auf.

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

Obwohl @zeller es bereits gesagt hat, ist hier ein Beispiel, wie man tasklist verwendet. Da ich gerade nach VanillePython-Alternativen gesucht habe ...

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

und jetzt kannst du tun:

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

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

Um das mehrfache Aufrufen zu vermeiden und einen Überblick über alle Prozesse auf diese Weise zu erhalten, können Sie Folgendes tun:

# 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 von Mark vorgeschlagen ist wirklich die beste Lösung, der einzige Nachteil ist die GPL-kompatible Lizenz. Wenn dies ein Problem ist, können Sie die Prozessinformationsbefehle von Windows aufrufen: wmic process wo WMI verfügbar ist (XP pro, Vista, win7) oder tasklist. Hier eine Beschreibung: Wie rufe ich ein externes Programm in Python auf und rufe den Ausgabe- und Rückkehrcode ab? (nicht der einzig mögliche Weg ...)

3
zeller

win32ui.FindWindow(classname, None) gibt ein Fensterhandle zurück, wenn ein Fenster mit dem angegebenen Klassennamen gefunden wird. Sonst wird window32ui.error ausgelöst.

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

Ich fand, dass der Fensterklassenname für das Dropbox-Tray-Symbol DropboxTrayIcon war und Autohotkey Window Spy verwendete.

Siehe auch

MSDN FindWindow

3
Jisang Yoo

Ich möchte diese Lösung aus historischen Gründen in die Liste aufnehmen. Es ermöglicht Ihnen, anhand von .exe anstelle des Fenstertitels herauszufinden, und gibt außerdem den verwendeten Arbeitsspeicher und die PID zurück.

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

Ein Ausschnitt der Beispielausgabe:

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

Wenn Sie sich nicht auf den Prozessnamen wie Python-Skripts verlassen können, wird immer python.exe als Prozessname verwendet. Wenn gefunden, diese Methode sehr praktisch

import psutil
psutil.pid_exists(pid)

in den Dokumenten finden Sie weitere Informationen http://psutil.readthedocs.io/de/latest/#psutil.pid_exists

2
MNIF AKRAM

Würden Sie mit Ihrem Python-Befehl ein anderes Programm ausführen, um die Informationen zu erhalten?

Wenn ja, würde ich vorschlagen, dass Sie sich die PsList und all ihre Optionen ansehen. Zum Beispiel würden Sie Folgendes über jeden laufenden iTunes-Prozess erfahren

PsList iTunes

Wenn Sie herausfinden können, wie die Ergebnisse zu interpretieren sind, sollte dies hoffentlich einen Schritt weiterbringen.

Bearbeiten:

Wenn ich nicht mit iTunes laufe, erhalte ich Folgendes:

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

Wenn iTunes läuft, bekomme ich eine zusätzliche Zeile:

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

Der folgende Befehl gibt jedoch nur Informationen zum iTunes-Programm selbst aus, d. H. Mit dem Argument -e:

pslist -e iTunes
2
Clare Macrae
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())

für python 3.7

0
0m3r

Wenn Sie eine Anwendung mit Behave testen, können Sie pywinauto verwenden. Ähnlich wie bei vorherigen Kommentaren können Sie diese Funktion verwenden:

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 kann 'uia' oder 'win32' sein

timeout Wenn erzwungen wird, wird die Verbindung mit der Anwendung für 5 Sekunden wiederhergestellt.

0
Pini

Das funktioniert gut

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