我尝试使用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)
当我运行它时(使用WinPython零,python 3.5),回调被成功调用多次。我看到窗口句柄整数print()ed。 但在某些时候,它失败了:
...
3740010
4597178
65918
196762
Traceback (most recent call last):
File "t.py", line 13, in <module>
EnumWindows(WNDENUMPROC(py_callback),0)
ValueError: Procedure probably called with not enough arguments (5043578 bytes missing)
缺少&#34;字节&#34;价值每次都在变化。
我有一个Python的微安装部署到一堆生产机器上(或者我可能只是更新Python发行版)。它是WinPython Zero 3.5.2。
脚本在我的制作发行版上失败了。我尝试了最新的3.6.2 WinPython,结果是一样的。
我可以使用Python 3.6(Anaconda)运行相同的脚本而不会出错。
我需要弄清楚这里出了什么问题,这样如果我需要修理客户,我可以做出最小的改变。
大多数对此错误消息的引用&#34;调用时没有足够的参数&#34;建议仔细检查调用约定,但回调在失败之前会多次运行。我对此持怀疑态度。
我可以看到一些潜在的依赖关系可以解释我在Python发行版之间看到的不同行为吗?
在窗口列表的末尾似乎失败了。如果我从一个工作发行版和一个糟糕的发行版中连续运行脚本,我会得到相同数量的发出句柄。
关于为什么这会在一段时间内起作用然后失败的任何想法?
答案 0 :(得分:2)
您的脚本中存在一些错误:
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)