我正在尝试创建一个python脚本,稍后我将其作为服务运行。现在我只想在iTunes运行时运行代码的特定部分。我从一些研究中了解到,轮询整个命令列表然后搜索该列表的应用程序是昂贵的。
我发现基于UNIX的操作系统上的进程创建了一个锁定文件来通知程序当前正在运行,此时我们可以使用os.stat(location_of_file)
检查文件是否存在以确定程序是否存在是否跑步。
是否在Windows上创建了类似的锁定文件?
如果没有,我们可以通过哪种方式确定进程是否正在运行?
我正在使用python 2.7和iTunes COM界面。
答案 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。
另见
答案 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 初学者
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()
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