繁体   English   中英

如何对EnumWindows()Python回调失败进行故障排除

[英]How to Troubleshoot EnumWindows() Python Callback Failure

问题

我正在尝试从Python(使用ctypes)使用EnumWindows( )。 我的回调函数似乎有些麻烦,尽管它仅在调用回调超过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 zero,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)

“字节丢失”值每次都会更改。

Python发行版

我有一个微型安装的Python,它已部署到许多生产机器上(否则我可能只是更新Python发行版)。 这是WinPython Zero 3.5.2。

该脚本在我的生产发行版上失败。 我针对最新的3.6.2 WinPython进行了尝试,结果是相同的。

我可以使用Python 3.6(Anaconda)运行相同的脚本,而不会出现错误。

我需要弄清楚这里出了什么问题,以便在需要修复客户端的情况下,我可以进行最小的更改。

故障排除

对此错误消息的大多数引用“使用了不足的参数调用”建议仔细检查调用约定,但是回调在失败之前可以工作很多次。 我对此表示怀疑。

我是否可以查看一些潜在的依赖关系,这些依赖关系可以解释我在Python发行版之间看到的不同行为?

它似乎在窗口列表的末尾失败。 如果我从一个有效的发行版和一个糟糕的发行版中连续运行脚本,我将得到相同数量的发射句柄。

关于为什么这会工作一段时间然后失败的任何想法?

您的脚本中有一些错误:

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM