You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.x使用ctypes调用Windows API出现ERROR_BAD_LENGTH(24)错误

Process32First返回ERROR_BAD_LENGTH错误的解决方法

错误原因

  • 结构体定义存在两处致命错误:
    1. 结构属性_fields_未进行Python语法要求的类内缩进,导致所有字段都没有被正确注册到ENTRY结构中,ctypes.sizeof(ENTRY)计算出的结构大小远小于Windows API要求的PROCESSENTRY32结构大小
    2. 末尾的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 23:54:04