Python窗口时间追踪程序异常:工作时chrome/edge进程同时出现
问题描述
我工作时容易分心,常被YouTube、WhatsApp这类应用干扰,因此开发了一款追踪时间的Python应用,但遇到问题:当我在Python编程窗口工作时,程序却同时显示chrome.exe和msedge.exe进程,找不到问题根源,特此求助。
附代码:
import time import pygetwindow as gw import win32gui import win32process import psutil import requests def get_active_application(title): try: hwnd = win32gui.FindWindow(None, title) threadid, pid = win32process.GetWindowThreadProcessId(hwnd) process = psutil.Process(pid) process_name = process.name() return process_name except Exception as e: print(f"Error in get_active_application: {e}") return None def post_data(user, window_title, window_application, elapsed_time): if elapsed_time > 5: url = "MyServerPath.php" json_data = { "user": user, "window_title": window_title, "window_application": window_application, "elapsed_time": int(elapsed_time) } try: response = requests.post(url, json=json_data) response.raise_for_status() # Raise an error for bad responses (4xx or 5xx) print(f"USER: {user} Time spent in {window_title} ({window_application}): {int(elapsed_time)} seconds") except requests.RequestException as e: print("POST request failed:", e) def log_window_focus(user): window_logs = {} try: while True: current_window = gw.getActiveWindow() if current_window is not None: window_title = current_window.title window_application = get_active_application(window_title) if window_title not in window_logs: window_logs[window_title] = {"time_spent": 0, "application": window_application} start_time = time.time() while gw.getActiveWindow() is not None and gw.getActiveWindow().title == window_title: time.sleep(1) elapsed_time = time.time() - start_time window_logs[window_title]["time_spent"] += elapsed_time post_data(user, window_title, window_application, elapsed_time) except KeyboardInterrupt: print("\nPuta Sumario") for window, data in window_logs.items(): print(f"{window} ({data['application']}): {data['time_spent']} seconds") if __name__ == "__main__": user = "usertest" log_window_focus(user)

问题原因
当前代码通过win32gui.FindWindow(None, title)根据窗口标题查找句柄,但不同进程的窗口可能有相同的标题(比如浏览器标签页标题和编程工具窗口标题重复),这会导致你拿到的不是当前激活窗口的句柄,而是其他进程(比如Chrome/Edge)的窗口句柄,进而返回错误的进程名。
解决方案
直接使用pygetwindow返回的激活窗口对象自带的句柄(_hWnd属性),而不是通过标题查找,这样能确保获取的是当前激活窗口对应的进程。
修改后的代码如下:
import time import pygetwindow as gw import win32process import psutil import requests def get_active_application(hwnd): try: threadid, pid = win32process.GetWindowThreadProcessId(hwnd) process = psutil.Process(pid) process_name = process.name() return process_name except Exception as e: print(f"Error in get_active_application: {e}") return None def post_data(user, window_title, window_application, elapsed_time): if elapsed_time > 5: url = "MyServerPath.php" json_data = { "user": user, "window_title": window_title, "window_application": window_application, "elapsed_time": int(elapsed_time) } try: response = requests.post(url, json=json_data) response.raise_for_status() # Raise an error for bad responses (4xx or 5xx) print(f"USER: {user} Time spent in {window_title} ({window_application}): {int(elapsed_time)} seconds") except requests.RequestException as e: print("POST request failed:", e) def log_window_focus(user): window_logs = {} try: while True: current_window = gw.getActiveWindow() if current_window is not None: window_title = current_window.title # 直接使用当前激活窗口的句柄 window_application = get_active_application(current_window._hWnd) if window_title not in window_logs: window_logs[window_title] = {"time_spent": 0, "application": window_application} start_time = time.time() while gw.getActiveWindow() is not None and gw.getActiveWindow().title == window_title: time.sleep(1) elapsed_time = time.time() - start_time window_logs[window_title]["time_spent"] += elapsed_time post_data(user, window_title, window_application, elapsed_time) except KeyboardInterrupt: print("\nPuta Sumario") for window, data in window_logs.items(): print(f"{window} ({data['application']}): {data['time_spent']} seconds") if __name__ == "__main__": user = "usertest" log_window_focus(user)
关键修改点
- 调整
get_active_application函数的参数,从接收窗口标题改为接收窗口句柄hwnd - 在
log_window_focus中,直接传入current_window._hWnd到get_active_application,确保获取的是当前激活窗口的进程信息
内容的提问来源于stack exchange,提问作者Mário Jorge Rocha
相关产品推荐
相关产品推荐

