如何获取已打开程序名称?构建应用拦截器遇技术难题
问题
我正在尝试构建一个简易应用拦截器,但试过多种方案后,总是只能获取到窗口标题而非运行程序的名称。
运行程序后得到如下输出:
Ask a public question - Stack Overflow - Google Chrome
我仅需要提取程序名称,比如Google Chrome。
我用pyautogui写了如下代码,但无法准确识别程序名称:
import pyautogui import AppOpener # blocked window blocked = "Microsoft Edge" #this prints list of all the window. windows = pyautogui.getAllWindows() for window in windows: app = window.title app_split_list = str(app).split("-") # the reason why im splitting it is because the window.title is in format like this: New tab - Personal - Microsoft Edge for item in app_split_list: print(item) if blocked in item: print("found") AppOpener.close(blocked) break #this didnt work because the getAllWindows() returned New tab - Personal - Microsoft Edge ( Microsoft Edge is with 2 spaces in between so it didnt got recognized.)
尝试后发现,pyautogui没法直接获取准确的程序名称,只能拿到窗口标题。再次运行程序得到如下输出:
Ask a public question - Stack Overflow - Google Chrome
YouTube - Personal - Microsoft Edge
程序名称确实在标题末尾,但靠分割标题的方法经常失效,比如名称里的空格问题导致识别不到,拦截器没法正常工作。
解决方案
直接从窗口标题提取程序名称容易受格式、空格、本地化等问题影响,这里提供两种可靠的解决思路:
方法1:通过窗口句柄获取进程名(推荐)
借助psutil获取系统进程信息,结合窗口句柄关联到对应进程,直接拿到程序的系统级标识,完全不受窗口标题影响:
import pygetwindow as gw import psutil import AppOpener blocked = "Microsoft Edge" # 进程名和应用显示名的映射,根据需要添加其他程序 process_app_map = { "chrome.exe": "Google Chrome", "msedge.exe": "Microsoft Edge", "firefox.exe": "Mozilla Firefox" } # 获取所有窗口 windows = gw.getAllWindows() for window in windows: try: # 通过窗口句柄获取进程ID pid = window._hWnd # 从进程ID获取进程对象 process = psutil.Process(pid) # 获取进程名并匹配对应应用 process_name = process.name() app_name = process_app_map.get(process_name) if app_name == blocked: print(f"发现拦截目标:{blocked}") AppOpener.close(blocked) break except psutil.NoSuchProcess: # 忽略已关闭的进程 continue
使用前需要先安装依赖:
pip install psutil pygetwindow
方法2:优化标题提取逻辑
如果不想引入额外库,可以对现有代码的标题分割逻辑做优化,处理空格问题:
import pyautogui import AppOpener blocked = "Microsoft Edge" windows = pyautogui.getAllWindows() for window in windows: title = window.title.strip() # 按"-"分割后取最后一段 parts = title.split("-") if len(parts) == 0: continue # 去除所有多余空格(多个空格合并为一个) app_candidate = " ".join(parts[-1].strip().split()) if app_candidate == blocked: print("found") AppOpener.close(blocked) break
说明
- 方法1的可靠性最高,因为进程名是系统级的唯一标识,不会随窗口标题变化而失效;
- 方法2属于临时修复方案,仍可能受部分程序标题格式(比如标题末尾不是程序名)影响;
内容的提问来源于stack exchange,提问作者farahead
相关产品推荐
相关产品推荐

