我正在尝试创build一个Python脚本,我将稍后作为服务运行。 现在我只想在iTunes运行时运行代码的特定部分。 我从一些研究中了解到,轮询整个命令列表然后search该列表的应用程序非常昂贵。
我发现基于Unix操作系统的程序创build一个锁文件来通知程序正在运行。 所以我们可以使用os.stat(location_of_file)来检查文件是否存在以确定程序是否正在运行。
有没有在Windows中创build一个类似的locking文件?
如果不是什么python中的各种方式,我们可以确定一个进程是否正在运行?
我正在使用Python 2.7和iTunes COM接口。
您不能依靠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托盘图标的窗口类名称是使用Autohotkey窗口间谍的DropboxTrayIcon。
也可以看看
MSDN FindWindow
Mark提出的Psutil确实是最好的解决方案,唯一的缺点就是GPL兼容许可证。 如果这是一个问题,那么你可以调用Windows的进程信息命令:WMI wmic process
,其中WMI可用(XP专业版,Vista,WIN7)或tasklist
。 这是一个描述: 如何在python中调用外部程序并检索输出和返回代码? (不是唯一可能的方法…)
虽然@zeller表示已经在这里是一个如何使用tasklist
的例子。 当我正在寻找香草蟒的替代品…
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())
你会喜欢你的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
为了历史目的,我想将此解决方案添加到列表中。 它可以让你找出基于.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
这很好
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