如何排除EnumWindows()Python回调失败

2024-10-03 15:31:19 发布

您现在位置:Python中文网/ 问答频道 /正文

问题

我尝试使用Python中的EnumWindows()(与ctypes一起使用)。我似乎在回调函数上遇到了一些问题,尽管只有在回调被调用超过1K次(大概值)之后才会发生。在

例如:

from ctypes import *
import ctypes.wintypes as wintypes

WNDENUMPROC = CFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.INT)
EnumWindows = windll.user32.EnumWindows
EnumWindows.argtypes = [ WNDENUMPROC, wintypes.INT ]
EnumWindows.restype = wintypes.BOOL

def py_callback( hwnd, lparam ):
    print('{}'.format(hwnd))
    return True

EnumWindows(WNDENUMPROC(py_callback),0)

当我运行这个(使用WinPythonzero,python3.5)时,回调被成功地调用了很多次。我看到窗口句柄integers print()ed。 但在某些时候,它失败了:

^{pr2}$

“缺少字节”值每次都会更改。在

Python发行版

我有一个Python的微安装,它被部署到许多生产机器上(或者我可能只更新Python发行版)。它是winpythonzero3.5.2。在

这个脚本在我的产品发行版上失败了。我对最新的3.6.2winpython进行了测试,结果是一样的。在

我可以在python3.6(Anaconda)中运行相同的脚本,而不会出错。在

我需要弄清楚这里出了什么问题,这样如果我需要修复客户,我可以尽可能地进行最小的更改。在

故障排除

多次调用“advice”来检查消息的“多次引用”失败。我对此表示怀疑。在

是否有一些底层依赖关系可以解释Python发行版之间的不同行为?在

它似乎在窗口列表的末尾失败了。如果我从一个正在工作的发行版和一个坏发行版连续运行脚本,我得到的句柄数是相同的。在

你知道为什么这会在一段时间内奏效然后失败吗?在


Tags: 函数frompyimport脚本callbackctypes句柄
1条回答
网友
1楼 · 发布于 2024-10-03 15:31:19

脚本中有一些错误:

from ctypes import *
import ctypes.wintypes as wintypes

# LPARAM is not necessarily INT-sized.  Use the correct type.
# CALLBACK is __stdcall, so WINFUNCTYPE should be used instead of CFUNCTYPE,
# which is __cdecl calling convention
WNDENUMPROC = WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)

# WinDLL should be used instead of windll.  Setting argtypes/restype on the windll
# common instance could affect other modules.
EnumWindows = WinDLL('user32').EnumWindows
EnumWindows.argtypes = WNDENUMPROC, wintypes.LPARAM  # LPARAM not INT
EnumWindows.restype = wintypes.BOOL

# Using a decorator keeps a reference to the callback.
# Building it in the EnumWindows call means it is released after the call.
# Not a problem in EnumWindows case since it isn't needed after the call
# returns, but for functions that register a callback and return immediately
# it is a problem.
@WNDENUMPROC
def py_callback( hwnd, lparam ):
    print(hwnd)
    return True

EnumWindows(py_callback,0)

相关问题 更多 >