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.

см. также

MSDN FindWindow


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