Проверка Python, запущен процесс или нет - PullRequest
27 голосов
/ 17 октября 2011

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

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

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

Если нет, то каким образом в Python можно определить, работает ли процесс или нет?

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

Ответы [ 9 ]

39 голосов
/ 17 октября 2011

Нельзя полагаться на блокировку файлов в Linux или Windows.Я бы просто укусил пулю и перебрал все работающие программы.Я правда не верю, что это будет так "дорого", как вы думаете. psutil - превосходный кроссплатформенный кабель модуля Python для перечисления всех запущенных программ в системе.

import psutil    
"someProgram" in (p.name() for p in psutil.process_iter())
6 голосов
/ 26 марта 2015

Хотя @zeller уже сказал, что это пример использования tasklist. Поскольку я просто искал альтернативы vanilla python ...

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())
6 голосов
/ 17 октября 2011

Файлы блокировки обычно не используются в 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 голосов
/ 31 декабря 2016

Я бы хотел добавить это решение в список для исторических целей.Это позволяет вам определять на основе .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
3 голосов
/ 04 сентября 2012

Psutil, предложенный Марком , действительно является лучшим решением, единственным его недостатком является лицензия, совместимая с GPL. Если это проблема, то вы можете вызвать команды с информацией о процессе Windows: wmic process, где доступен WMI (XP pro, vista, win7) или tasklist. Вот описание, чтобы сделать это: Как вызвать внешнюю программу на Python и получить выходной код и код возврата? (не единственный возможный способ ...)

3 голосов
/ 20 августа 2012

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.

См. Также

MSDN FindWindow

2 голосов
/ 17 декабря 2017

Если нельзя полагаться на имя процесса, например, на скрипты python, которые всегда будут иметь python.exe в качестве имени процесса.Если этот метод был очень полезен

import psutil
psutil.pid_exists(pid)

, проверьте документы для получения дополнительной информации http://psutil.readthedocs.io/en/latest/#psutil.pid_exists

2 голосов
/ 17 октября 2011

Будете ли вы довольны тем, что ваша команда 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
0 голосов
/ 14 апреля 2016

Это хорошо работает

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...