Python检查进程是否正在运行

时间:2011-10-16 20:33:03

标签: python windows

我正在尝试创建一个python脚本,稍后我将其作为服务运行。现在我只想在iTunes运行时运行代码的特定部分。我从一些研究中了解到,轮询整个命令列表然后搜索该列表的应用程序是昂贵的。

我发现基于UNIX的操作系统上的进程创建了一个锁定文件来通知程序当前正在运行,此时我们可以使用os.stat(location_of_file)检查文件是否存在以确定程序是否存在是否跑步。

是否在Windows上创建了类似的锁定文件?

如果没有,我们可以通过哪种方式确定进程是否正在运行?

我正在使用python 2.7和iTunes COM界面。

19 个答案:

答案 0 :(得分:39)

您无法依赖Linux或Windows中的锁定文件。我会咬紧牙关并遍历所有正在运行的程序。我真的不相信它会像你想象的那样“昂贵”。 psutil是一个优秀的跨平台python模块电缆,可以枚举系统中所有正在运行的程序。

import psutil    
"someProgram" in (p.name() for p in psutil.process_iter())

答案 1 :(得分:6)

锁定文件通常不在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

答案 2 :(得分:6)

尽管@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())

答案 3 :(得分: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

答案 4 :(得分:3)

如果找到具有给定类名的任何窗口,

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托盘图标的窗口类名称是使用Autohotkey Window Spy的DropboxTrayIcon。

另见

MSDN FindWindow

答案 5 :(得分:3)

Psutil suggested by Mark,确实是最好的解决方案,唯一的缺点是GPL兼容许可证。如果这是一个问题,那么您可以调用Windows的进程信息命令:wmic process其中WMI可用(XP专业版,vista版,win7版)或tasklist。以下是对此的说明:How to call an external program in python and retrieve the output and return code?(不是唯一可能的方式......)

答案 6 :(得分:2)

您是否对使用其他程序获取信息的Python命令感到满意?

如果是这样,我建议您查看PsList及其所有选项。例如,以下内容将告诉您任何正在运行的iTunes进程

PsList itunes

如果你能弄清楚如何解释结果,那么这应该会让你前进。

修改

当我运行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

答案 7 :(得分:2)

如果不能像python脚本那样依赖进程名称,而python脚本总是将python.exe作为进程名称。如果发现这个方法非常方便

import psutil
psutil.pid_exists(pid)

检查文档以获取更多信息 http://psutil.readthedocs.io/en/latest/#psutil.pid_exists

答案 8 :(得分:1)

尝试以下代码:

import subprocess
def process_exists(process_name):
    progs = str(subprocess.check_output('tasklist'))
    if process_name in progs:
        return True
    else:
        return False

并检查该进程是否正在运行:

if process_exists('example.exe'):
    #do something

答案 9 :(得分:1)

有一个名为wmi的python模块。

import wmi
c=wmi.WMI()
def check_process_running(str_):
    if(c.Win32_Process(name=str_)):
        print("Process is running")
    else:
        print("Process is not running")

         
check_process_running("yourprocess.exe")  

答案 10 :(得分:0)

您可以只使用 os.kill 发送 0 信号(不会终止进程)并检查错误。

from os import kill

def check_if_running(pid):
    try:
        kill(pid, 0)
    except:
        return False
    return True

答案 11 :(得分:0)

无需长代码即可确定应用程序是否正在运行 这适用于那些在 PYTHON 中使用 TK 的人和 Python 初学者

对于 Tk

from tkinter import *
import os

root = Tk()

def killer(appname):
    a = os.system(f'taskkill /PID '+appname+'.exe /F')
    if a==1 or a==0:
        l1.config(text=appname+' Has Been Killed Successfully')
    else:
        l1.config(text=appname+" Is Not Running")

Button(text="Kill VLC MEIDA PLAYER",command=lambda:(killer('VLC'))).pack()
Button(text="Kill CMD",command=lambda:(killer('CMD'))).pack()
Button(text="Kill Notepad",command=lambda:(killer('NOTEPAD'))).pack()

l1 = Label(text="")
l1.pack()

root.mainloop()

对于 Python 控制台

a = os.system('taskkill /PID cmd.exe /F') 
# Here Insted Of Cmd You Can Give Your Program Name
if a==0 or a==1:
    print('Cmd Is Running And Is Killed')
else:
    print('CMD is Not Running')
inn = input('Press Any Key To Continue')
# Insted Of Cmd.exe You Can Give Your Program Name Such As VLC.exe

谢谢

答案 12 :(得分:0)

Psutil 是最好的解决方案。

import psutil

processes = list(p.name() for p in psutil.process_iter())
# print(processes)
count = processes.count("<app_name>.exe")

if count == 1:
    logging.info('Application started')
    # print('Application started')
else:
    logging.info('Process is already running!')
    # print('Process is already running!')
    sys.exit(0)                          # Stops duplicate instance from running

答案 13 :(得分:0)

根据ewerybody帖子:https://stackoverflow.com/a/29275361/7530957

可能会出现多个问题:

  • 多个同名进程
  • 漫长进程的名称

如果进程名称很长,那么'ewerybody's'代码将不起作用。所以这条线有问题:

last_line.lower().startswith(process_name.lower())

因为last_line将比进程名称短。

因此,如果您只想知道一个或多个进程是否处于活动状态:

from subprocess import check_output

def process_exists(process_name):
    call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name
    if check_output(call).splitlines()[3:]:
        return True

代替一个或多个过程的所有信息

from subprocess import check_output

def process_exists(process_name):
    call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name
    processes = []
    for process in check_output(call).splitlines()[3:]:
        process = process.decode()
        processes.append(process.split())
    return processes

答案 14 :(得分:0)

import psutil

def check_process_status(process_name):
    """
    Return status of process based on process name.
    """
    process_status = [ proc.status() for proc in psutil.process_iter() if proc.name() == process_name ]
    if process_status:
        print("Process name %s and staus %s"%(process_name, process_status[0]))
    else:
        print("Process name not valid", process_name)

答案 15 :(得分:0)

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 !')

答案 16 :(得分:0)

如果您正在使用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秒钟内强制重新与应用程序连接)。

答案 17 :(得分:0)

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

答案 18 :(得分:0)

这很好用

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