Проверка Python, запущен процесс или нет
Я пытаюсь создать скрипт на Python, который позже я буду запускать как сервис. Теперь я хочу запускать определенную часть кода только во время работы iTunes. Из некоторых исследований я понимаю, что опрос всего списка команд, а затем поиск приложения для этого списка стоит дорого.
Я обнаружил, что процессы в операционных системах на основе UNIX создают файл блокировки для уведомления о том, что программа в данный момент выполняется, и в этот момент мы можем использовать os.stat(location_of_file)
чтобы проверить, существует ли файл, чтобы определить, запущена ли программа или не.
Существует ли аналогичный файл блокировки, созданный в Windows?
Если нет, то каковы различные способы в Python, с помощью которых мы можем определить, запущен процесс или нет?
Я использую Python 2.7 и интерфейс iTunes COM.
Ответы
Ответ 1
Вы не можете полагаться на блокировку файлов в Linux или Windows. Я бы просто укусил пулю и перебрал все работающие программы. Я правда не верю, что это будет так "дорого", как вы думаете. psutil - превосходный кроссплатформенный кабель модуля Python для перечисления всех запущенных программ в системе.
import psutil
"someProgram" in (p.name() for p in psutil.process_iter())
Ответ 2
Хотя @zeller сказал, что уже здесь приведен пример использования tasklist
. Поскольку я просто искал альтернативы ванильного питона...
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())
и теперь вы можете сделать:
>>> process_exists('eclipse.exe')
True
>>> process_exists('AJKGVSJGSCSeclipse.exe')
False
Чтобы не вызывать это несколько раз и иметь обзор всех процессов таким образом, вы можете сделать что-то вроде:
# 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())
Ответ 3
Файлы блокировки обычно не используются в 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
Ответ 4
Я хотел бы добавить это решение в список в исторических целях. Он позволяет вам найти на основе .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
Ответ 5
Вы были бы довольны тем, что ваша команда 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, то есть аргументе -e
:
pslist -e itunes
Ответ 6
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."
Я обнаружил, что имя класса окна для значка в Dropboxbox было DropboxTrayIcon, используя Autohotkey Window Spy.
См. также
MSDN FindWindow
Ответ 7
Psutil, предложенный Mark, на самом деле является лучшим решением, единственным недостатком является лицензия, совместимая с GPL. Если это проблема, вы можете вызвать команды информации о процессе Windows: wmic process
, где доступен WMI (XP pro, vista, win7) или tasklist
. Вот описание, чтобы сделать это: Как вызвать внешнюю программу на python и получить код вывода и возврата? (не единственный возможный способ...)
Ответ 8
Если вы не можете полагаться на имя процесса, например, скрипты python, которые всегда будут иметь имя python.exe. Если этот метод очень удобен,
import psutil
psutil.pid_exists(pid)
проверить документы для получения дополнительной информации
http://psutil.readthedocs.io/en/latest/#psutil.pid_exists
Ответ 9
Это хорошо работает
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
Ответ 10
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())
для Python 3.7
Ответ 11
Если вы тестируете приложение с помощью Behave, вы можете использовать pywinauto
.
Аналогично предыдущему комментарию, вы можете использовать эту функцию:
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
может быть 'uia' или 'win32'
timeout
, если в отношении силы повторно соединиться с приложением в течение 5 секунд.
Ответ 12
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 !')