Python проверяет, запущен ли процесс или нет
Я пытаюсь создать скрипт python, который я позже запущу как сервис. Теперь я хочу запустить определенную часть кода только тогда, когда работает iTunes. Я понимаю из некоторых исследований, что опрос всего списка команд, а затем поиск приложения для этого списка стоит дорого.
я узнал, что процессы в UNIX - операционных системах создают файл блокировки, чтобы уведомить, что программа в настоящее время работает, и в этот момент мы можем использовать os.stat(location_of_file)
чтобы проверить, если файл существует, чтобы определить, запущена программа или нет.
есть ли аналогичный файл блокировки, созданный в Windows?
если нет, то каковы различные способы в Python, с помощью которых мы можем определить, запущен ли процесс или нет?
Я использую интерфейс python 2.7 и iTunes COM.
9 ответов
вы не можете полагаться на файлы блокировки в Linux или Windows. Я бы просто укусил пулю и перебрал все запущенные программы. Я действительно не верю, что это будет так "дорого", как вы думаете. psutil является отличным кросс-платформенный модуль python кабель перечисления всех запущенных программ в системе.
import psutil
"someProgram" in (p.name() for p in psutil.process_iter())
файлы блокировки обычно не используются в Windows (и редко в Unix). Обычно, когда программа Windows хочет узнать, запущен ли уже другой экземпляр, она вызывает FindWindow
С известным названием или именем класса.
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
win32ui.FindWindow(classname, None)
возвращает дескриптор окна, если окно с заданным именем класса. Он поднимает 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."
я обнаружил, что имя класса окна для значка в трее Dropbox было DropboxTrayIcon с помощью AutoHotkey Window Spy.
см. также
Psutil предложил Марк, действительно самое лучшее решение, свой единственный недостаток лицензия ГПЛ совместимая. Если это проблема, то вы можете вызвать команды информации о процессе Windows:wmic process
где WMI доступен (XP pro, vista, win7) или tasklist
. Вот описание, чтобы сделать это:как вызвать внешнюю программу в python и получить код вывода и возврата? (не единственный возможный путь...)
хотя @zeller сказал, что это уже вот пример того, как использовать tasklist
. Как я только что искал ванилин альтернативы python...
import subprocess
def processExists(processname):
tlcall = 'TASKLIST', '/FI', 'imagename eq %s' % processname
# shell=True hides the shell window, stdout to PIPE enables
# communicate() to get the tasklist command result
tlproc = subprocess.Popen(tlcall, shell=True, stdout=subprocess.PIPE)
# trimming it to the actual lines with information
tlout = tlproc.communicate()[0].strip().split('\r\n')
# if TASKLIST returns single line without processname: it's not running
if len(tlout) > 1 and processname in tlout[-1]:
print('process "%s" is running!' % processname)
return True
else:
print(tlout[0])
print('process "%s" is NOT running!' % processname)
return False
и теперь вы можете сделать:
>>> processExists('eclipse.exe')
process "eclipse.exe" is running!
True
>>> processExists('AJKGVSJGSCSeclipse.exe')
INFO: No tasks are running which match the specified criteria.
process "AJKGVSJGSCSeclipse.exe" is NOT running!
False
чтобы избежать вызова этого несколько раз и иметь обзор всех процессов таким образом, вы могли бы сделать что-то вроде:
# get info dict about all running processes
tlcall = 'TASKLIST', '/FO', 'CSV'
tlproc = subprocess.Popen(tlcall, shell=True, stdout=subprocess.PIPE)
# get rid of extra " and split into lines
tlout = tlproc.communicate()[0].replace('"', '').split('\r\n')
tlhead = tlout[0].split(',')
tllist = [i.split(',') for i in tlout[1:] if i]
# make dict with proc names as keys and dicts with the extra nfo as values
processDict = dict( [( i[0], dict(zip(tlhead[1:], i[1:])) ) for i in tllist] )
print(processDict.keys())
Я хотел бы добавить это решение в Список для исторических целей. Это позволяет узнать на основе .exe вместо заголовка окна, а также возвращает память, используемую & 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
фрагмент вывода примера:
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
Вы были бы счастливы, если бы ваша команда Python запускала другую программу для получения информации?
если это так, я бы предложил вам взглянуть на программа pslist и все его варианты. Например, следующее расскажет вам о любом запущенном процессе iTunes
PsList itunes
если вы можете понять, как интерпретировать результаты, это, надеюсь, поможет вам.
Edit:
когда я не запуск iTunes, я получаю следующий:
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
С itunes работает, я получаю эту дополнительную строку:
iTunes 928 8 24 813 106168 0:00:08.734 0:02:08.672
однако следующая команда выводит информацию только о самой программе iTunes, т. е. с помощью :
pslist -e itunes
если не может полагаться на имя процесса, как скрипты python, которые всегда будут иметь python.exe как имя процесса. Если нашел этот метод очень удобно
import psutil
psutil.pid_exists(pid)
проверить Docs для получения дополнительной информации http://psutil.readthedocs.io/en/latest/#psutil.pid_exists
это работает хорошо
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