Python 3.x使用ctypes调用Windows API出现ERROR_BAD_LENGTH(24)错误
Process32First返回ERROR_BAD_LENGTH错误的解决方法
错误原因
- 结构体定义存在两处致命错误:
- 结构属性
_fields_未进行Python语法要求的类内缩进,导致所有字段都没有被正确注册到ENTRY结构中,ctypes.sizeof(ENTRY)计算出的结构大小远小于Windows API要求的PROCESSENTRY32结构大小 - 末尾的exe文件名字段定义错误,官方
PROCESSENTRY32结构的szExeFile是长度为260(MAX_PATH)的字符数组,你错误定义为了单个CHAR类型,进一步导致结构大小不符合要求,这是触发ERROR_BAD_LENGTH的核心原因
- 结构属性
GetLastError调用方式错误:直接通过WinDLL实例调用GetLastError无法拿到正确的错误码,ctypes的内部调用会覆盖系统存储的上一个错误值,需要在加载库时开启use_last_error配置,再通过ctypes.get_last_error()获取正确错误码- 缺少API返回值校验:你没有判断
CreateToolhelp32Snapshot是否返回了有效快照句柄,直接传入后续调用也可能引发额外异常
修正后的可运行代码
import ctypes from ctypes import wintypes # 定义Windows API要求的常量 MAX_PATH = 260 TH32CS_SNAPPROCESS = 0x00000002 # 正确实现PROCESSENTRY32结构 class PROCESSENTRY32(ctypes.Structure): _fields_ = [ ('dwSize', wintypes.DWORD), ('cntUsage', wintypes.DWORD), ('th32ProcessID', wintypes.DWORD), ('th32DefaultHeapID', wintypes.LPVOID), ('th32ModuleID', wintypes.DWORD), ('cntThreads', wintypes.DWORD), ('th32ParentProcessID', wintypes.DWORD), ('pcPriClassBase', wintypes.LONG), ('dwFlags', wintypes.DWORD), ('szExeFile', wintypes.CHAR * MAX_PATH) ] # 加载Kernel32时开启use_last_error保证错误码获取正确 kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) def get_explorer_pid(self): snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, None) if snapshot == ctypes.INVALID_HANDLE_VALUE: print(f"创建进程快照失败,错误码:{ctypes.get_last_error()}") return None entry = PROCESSENTRY32() entry.dwSize = ctypes.sizeof(PROCESSENTRY32) first_ret = kernel32.Process32First(snapshot, ctypes.byref(entry)) if not first_ret: print(f"Process32First调用失败,错误码:{ctypes.get_last_error()}") kernel32.CloseHandle(snapshot) return None # 补充遍历进程找explorer.exe的逻辑 while first_ret: if entry.szExeFile.decode('gbk') == 'explorer.exe': kernel32.CloseHandle(snapshot) return entry.th32ProcessID first_ret = kernel32.Process32Next(snapshot, ctypes.byref(entry)) kernel32.CloseHandle(snapshot) return None
内容的提问来源于stack exchange,提问作者malonn
相关产品推荐
相关产品推荐

