使用psutil获取Windows应用运行时长的相关技术疑问
获取Windows应用的实际运行时长(基于psutil的实现方案)
问题背景
在Windows系统中,我想用Python结合psutil库编写程序,获取应用从启动到当前的运行时长,初始代码如下:
psutil.process_iter.cache_clear() processes = psutil.process_iter() for process in processes: duration = time.time() - process.create_time() converted_time = convert_seconds(duration) # Converts seconds into a more readable form print(converted_time)
但碰到单个应用存在多个运行进程的情况,我有几个疑问:
- 单应用多进程时,是否始终存在一个进程的运行时长和应用总启动时长一致?比如谷歌浏览器已运行X小时,是否必然有一个进程的运行时长也是X小时?
- 取该应用中运行时间最长的进程,能否得到应用的实际运行时长?
- 有没有更优的实现方案?
核心问题解答
1. 是否总有进程时长与应用总时长一致?
多数桌面应用(比如Chrome、Edge、Office系列)的主进程是最早启动的,它的创建时间就是应用的启动时间,所以运行时长和应用总时长完全一致。但存在例外:
- 部分应用的主进程可能在运行中重启(比如带自动更新机制的客户端、部分后台服务),原主进程被销毁后,新主进程的创建时间会晚于实际应用启动时间;
- 极少数采用无主进程架构的应用(比如分布式渲染工具),所有进程按需启动销毁,不存在和应用总时长一致的进程。
2. 取最长运行时长的进程是否可行?
正常场景下这个方法是有效的——主进程通常最早启动且持续运行,时长最长。但碰到主进程重启、无主进程架构的情况,结果就会出错:比如Chrome主进程意外重启后,新主进程的时长会比之前的子进程短,这时候取最长子进程的时长反而不符合实际应用启动时间。
3. 更优的实现方案
针对Windows系统,结合进程父关系和进程名称可以更精准定位主进程,进而获取准确的启动时间:
- 先筛选出目标应用的所有进程(通过进程名匹配,比如Chrome是
chrome.exe); - 在这些进程里找根进程:父进程不在当前应用进程列表中的进程(通常父进程是系统进程如
explorer.exe、services.exe); - 根进程的创建时间就是应用的启动时间,以此计算运行时长。
如果找不到根进程,再退而求其次取最长运行时间的进程作为备选。
优化后的代码示例:
import psutil import time def convert_seconds(seconds): # 将秒转换为时分秒的可读格式 hours = int(seconds // 3600) minutes = int((seconds % 3600) // 60) secs = int(seconds % 60) return f"{hours}h {minutes}m {secs}s" def get_app_run_duration(app_process_name): # 筛选目标应用的所有进程信息 app_processes = [] for proc in psutil.process_iter(['pid', 'name', 'create_time', 'ppid']): try: if proc.info['name'].lower() == app_process_name.lower(): app_processes.append(proc.info) except (psutil.NoSuchProcess, psutil.AccessDenied): continue if not app_processes: return "应用未运行" # 寻找根进程:父进程不在当前应用进程列表中 app_pids = [p['pid'] for p in app_processes] root_process = None for proc in app_processes: if proc['ppid'] not in app_pids: root_process = proc break # 找不到根进程时,取运行时间最长的进程 if not root_process: root_process = max(app_processes, key=lambda x: time.time() - x['create_time']) # 计算并返回可读时长 duration = time.time() - root_process['create_time'] return convert_seconds(duration) # 示例:获取谷歌浏览器的运行时长 print(get_app_run_duration("chrome.exe"))
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

