win32gui.EnumWindows 以无效窗口句柄开头?

问题描述 投票:0回答:1

我几个月来一直在使用我编写的这段代码来检查我打开的一组窗口是否在特定的窗口标题上停留了给定的秒数,如果是,则关闭它们。该代码在我的 VPS 上持续运行。

import time
import datetime
import win32gui
import win32process

max_downtime = 90
pid_downtimes = {}
cur_pids = []
prev_pids = []

def winEnumHandler(hwnd, ctx):
    class_name = win32gui.GetClassName(hwnd)
    window_text = win32gui.GetWindowText(hwnd)

    if class_name != "ConsoleWindowClass":
        return

    if not window_text.startswith("Plutonium"):
        return

    if "Server restarter" in window_text:
        return

    if "Dedicated Server" in window_text:
        return

    tid, pid = win32process.GetWindowThreadProcessId(hwnd)

    if pid not in pid_downtimes:
        pid_downtimes[pid] = 0

    pid_downtimes[pid] += 1

    if pid_downtimes[pid] >= max_downtime:
        print("Server restarted at:", datetime.datetime.now())
        win32gui.SendMessage(hwnd, 16) # close window
        return

    cur_pids.append(pid)


while True:
    win32gui.EnumWindows(winEnumHandler, None)

    old_pids = [pid for pid in prev_pids if pid not in cur_pids]

    for pid in old_pids:
        if pid in pid_downtimes:
            del pid_downtimes[pid]

    prev_pids = cur_pids
    cur_pids = []

    time.sleep(1)

几天前,第一次崩溃了。

Traceback (most recent call last):
line 43, in <module>
    win32gui.EnumWindows(winEnumHandler, None)
line 12, in winEnumHandler
    class_name = win32gui.GetClassName(hwnd)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
pywintypes.error: (1400, 'GetClassName', 'Invalid window handle.')

有人知道什么会导致它在平稳运行几个月后崩溃吗?它似乎使用来自

winEnumHandler
的无效窗口句柄启动了函数
win32gui.EnumWindows
,我不知道这是可能的。

python pywin32 win32gui
1个回答
0
投票

根据[MS.Learn]:GetClassName函数(winuser.h)强调是我的):

如果函数失败,返回值为零。要获取扩展错误信息,请调用 GetLastError 函数

所以这个函数可以在某些窗口上失败(也许有些窗口没有类?)。所以你的代码必须处理这种情况。可能是这样的:

import pywintypes

# ...

def win_enum_handler(hwnd, ctx):
    window_text = win32gui.GetWindowText(hwnd)
    try:
        class_name = win32gui.GetClassName(hwnd)
    except pywintypes.error:
        class_name = "Could not be determined"

    # ...
© www.soinside.com 2019 - 2024. All rights reserved.