python-3.x - Python ctypes EnumThreadWindows 失败并出现错误 87 (ERROR_INVALID_PARAMETER)
问题描述
我似乎无法让 EnumThreadWindows 工作。它一直失败并出现错误 87。代码:
error = ctypes.WinDLL('Kernel32').GetLastError
enum_func = ctypes.WINFUNCTYPE(wintypes.BOOL,
wintypes.HWND,
wintypes.LPARAM)
def callback(hwnd, lParam):
length = ctypes.WinDLL('User32').GetWindowTextLengthW(hwnd) + 1
buf = ctypes.create_unicode_buffer(length)
ctypes.WinDLL('User32').GetWindowTextW(hwnd, buf, length)
print(buf.value)
worker = enum_func(callback)
test = ctypes.WinDLL('User32').EnumThreadWindows(6000, worker, None)
print(error(test))
我试过了pid = wintypes.DWORD(6000)
,test = ctypes.WinDLL('User32').EnumThreadWindows(pid.value, worker, None)
没有用。我究竟做错了什么?
解决方案
这是工作代码。确保传递有效的线程 ID。
您可能对 LPARAM 可以是任何东西(包括 Python 对象)感兴趣,因此如果您传递 Python 对象,则可以在回调中对其进行操作:
import ctypes
from ctypes import wintypes
from collections import namedtuple
Window = namedtuple('Window','hwnd title')
WNDENUMPROC = ctypes.WINFUNCTYPE(wintypes.BOOL,
wintypes.HWND,
ctypes.py_object) # to allow any Python object.
u32 = ctypes.WinDLL('user32',use_last_error=True) # to ensure GetLastError was captured
# Declaring arguments and return type helps catch errors and support 64-bit.
# HWND is 64-bit on 64-bit Python, and could get truncated if left to ctypes default
# of c_int (32-bit). This code works on Python 2.7 and 3.9.
u32.GetWindowTextLengthW.argtypes = wintypes.HWND,
u32.GetWindowTextLengthW.restype = ctypes.c_int
u32.GetWindowTextW.argtypes = wintypes.HWND,wintypes.LPWSTR,ctypes.c_int
u32.GetWindowTextW.restype = ctypes.c_int
u32.EnumThreadWindows.argtypes = wintypes.DWORD,WNDENUMPROC,ctypes.py_object # to pass Python object
u32.EnumThreadWindows.restype = wintypes.BOOL
@WNDENUMPROC # decorator makes this a ctypes-compatible function
def callback(hwnd, lParam):
length = u32.GetWindowTextLengthW(hwnd) + 1
buf = ctypes.create_unicode_buffer(length)
u32.GetWindowTextW(hwnd, buf, length)
lParam.append(Window(hwnd,buf.value)) # append data to the callback parameter
return True # return True to continue enumeration
result = [] # A python object
if u32.EnumThreadWindows(6332, callback, result): # 6332 was a thread in my explore.exe
for wnd in result: # list results when enumeration complete
print(wnd)
else:
print('error:',ctypes.get_last_error()) # print error of EnumThreadWindows.
# Python could use a Win32 function that fails in
# between the ctypes call and calling GetLastError
# directly.
输出:
Window(hwnd=65832, title='')
Window(hwnd=65838, title='')
Window(hwnd=131174, title='')
Window(hwnd=65682, title='')
Window(hwnd=65678, title='')
Window(hwnd=65826, title='Program Manager')
Window(hwnd=196928, title='MSCTFIME UI')
Window(hwnd=65680, title='Default IME')
推荐阅读
- python - 方法调用后更改变量值
- ansible - 使用带有循环的主机清单中的变量
- java - 如何解析来自 openlibrary api 的 Json 数据?使用 Jsoup 和 Gson
- c# - 如何从 C# 应用程序向 Repl.it Node.js 服务器发送字符串
- autodesk-forge - 使用 PATCH 项目时激活了额外的服务?
- javascript - 本地主机上的 FB.api() 在 chrome 和 FF 之间的行为不同
- python - python ide和arduino之间的串行通信冻结
- android - Android Studio 新项目构建失败
- branch.io - 使用 Branch SDK 的 Android 深度链接
- node.js - 安装包时,角度中的 package.json 未更新