调用SetProcessInformation参数无效,如何为进程设置Eco QOS模式?
解决SetProcessInformation错误码87(参数无效)的问题
错误码87是典型的参数无效问题,你的代码存在三个关键错误,逐一修正即可解决:
1. 错误的ProcessPowerThrottling枚举值
你将ProcessPowerThrottling设为4,但根据Windows API定义,PROCESS_INFORMATION_CLASS枚举中的ProcessPowerThrottling成员数值应为92(0x5C)。这个错误直接导致API无法识别你要设置的信息类别,是引发错误87的核心原因之一。
2. PROCESS_POWER_THROTTLING_STATE的ControlMask未正确设置
根据文档,ControlMask字段需要指定你想要修改的节流状态位,不能设为0。启用Eco QOS时,ControlMask和StateMask都要设置为PROCESS_POWER_THROTTLING_EXECUTION_SPEED;禁用时,ControlMask保持该值,StateMask设为0。
3. GetLastError调用方式不可靠
直接调用windll.kernel32.GetLastError可能被其他ctypes操作覆盖错误码,应使用ctypes.get_last_error()来获取准确的错误信息。
修正后的完整代码
import ctypes from ctypes import windll, wintypes from typing import Any class PROCESS_POWER_THROTTLING_STATE(ctypes.Structure): _fields_ = [ ('Version', wintypes.ULONG), ('ControlMask', wintypes.ULONG), ('StateMask', wintypes.ULONG) ] def setEcoQOS(pid: int, enable: bool): PROCESS_SET_INFORMATION = 0x0200 PROCESS_POWER_THROTTLING_CURRENT_VERSION = 1 PROCESS_POWER_THROTTLING_EXECUTION_SPEED = 0x1 # 修正ProcessPowerThrottling的枚举值为正确的92(0x5C) ProcessPowerThrottling = 0x5C SetProcessInformation = windll.kernel32.SetProcessInformation SetProcessInformation.argtypes = ( wintypes.HANDLE, wintypes.DWORD, wintypes.LPVOID, wintypes.DWORD, ) SetProcessInformation.restype = wintypes.BOOL OpenProcess = windll.kernel32.OpenProcess OpenProcess.argtypes = ( wintypes.DWORD, wintypes.BOOL, wintypes.DWORD, ) OpenProcess.restype = wintypes.HANDLE CloseHandle = windll.kernel32.CloseHandle CloseHandle.argtypes = (wintypes.HANDLE,) CloseHandle.restype = wintypes.BOOL hwnd = OpenProcess(PROCESS_SET_INFORMATION, False, pid) if hwnd == 0: raise Exception(f'无法打开进程PID {pid},错误码={ctypes.get_last_error()}') PowerThrottling = PROCESS_POWER_THROTTLING_STATE() PowerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION PowerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED if enable: PowerThrottling.StateMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED else: PowerThrottling.StateMask = 0 ret = SetProcessInformation(hwnd, ProcessPowerThrottling, ctypes.byref(PowerThrottling), ctypes.sizeof(PowerThrottling)) if not ret: raise Exception(f'无法设置进程信息,错误码={ctypes.get_last_error()}') ret = CloseHandle(hwnd) if not ret: raise Exception(f'无法关闭句柄,错误码={ctypes.get_last_error()}') pid = 10688 # 替换为你的目标PID setEcoQOS(pid, True)
为subprocess.Popen启动的进程设置Eco QOS
如果要为subprocess.Popen启动的进程自动启用该模式,只需在创建进程后立即调用setEcoQOS,传入子进程的pid:
import subprocess proc = subprocess.Popen(["your_executable.exe"]) setEcoQOS(proc.pid, True)
内容的提问来源于stack exchange,提问作者notsoeasy
相关产品推荐
相关产品推荐

