Подтвердить что ты не робот

Проверка Python, запущен процесс или нет

Я пытаюсь создать скрипт на Python, который позже я буду запускать как сервис. Теперь я хочу запускать определенную часть кода только во время работы iTunes. Из некоторых исследований я понимаю, что опрос всего списка команд, а затем поиск приложения для этого списка стоит дорого.

Я обнаружил, что процессы в операционных системах на основе UNIX создают файл блокировки для уведомления о том, что программа в данный момент выполняется, и в этот момент мы можем использовать os.stat(location_of_file) чтобы проверить, существует ли файл, чтобы определить, запущена ли программа или не.

Существует ли аналогичный файл блокировки, созданный в Windows?

Если нет, то каковы различные способы в Python, с помощью которых мы можем определить, запущен процесс или нет?

Я использую Python 2.7 и интерфейс iTunes COM.

4b9b3361

Ответ 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 !')