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

Win10下ctypes调用SetThreadExecutionState后无法恢复屏保问题

Win10 屏保被SetThreadExecutionState永久阻止的排查与修复

核心踩坑点说明

SetThreadExecutionState的生效范围是调用该API的线程所属进程,不是全局系统配置。只要有进程调用时传了0x80000002(即ES_CONTINUOUS | ES_DISPLAY_REQUIRED)且没有正常退出重置状态,哪怕你在其他新进程里反复传0x80000000,也清不掉这个进程持有的显示常亮锁,系统会一直判定有应用需要保持屏幕点亮,自然不会触发屏保。

分步排查修复流程

  • 第一步:清理所有残留相关进程
    打开任务管理器的「详细信息」选项卡,把所有python.exe、pythonw.exe、以及你打包生成的屏保控制程序进程全部结束。注意很多人会把这类脚本设为无窗口后台运行,出问题时很容易漏掉后台挂着的pythonw.exe进程。清完之后等够你设置的屏保等待时长,验证是否能正常触发。
  • 第二步:手动重置系统执行状态
    以管理员权限打开PowerShell,逐行执行以下代码,执行完不要立刻关窗口,等10秒再关闭:
    import ctypes
    # 清空所有显示、睡眠阻止标志
    ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
    # 传0彻底重置当前线程的执行状态配置
    ctypes.windll.kernel32.SetThreadExecutionState(0x0)
    
  • 第三步:排查其他持有显示锁的应用
    如果前两步操作完屏保还是不触发,说明不是你写的脚本残留,用系统自带工具查所有持有显示锁的进程:
    管理员权限下执行命令:powercfg /requests
    查看返回结果中[DISPLAY]分类下列出的进程,除系统自带的资源管理器外,视频播放器、浏览器(正在播放网页视频/直播时会持锁)、会议软件、远程桌面类程序全部手动退出,这类程序同样会调用相同API阻止屏保启动。
  • 第四步:重置电源计划到默认
    极少数情况是异常API调用打乱了电源计划配置,直接执行命令powercfg -restoredefaultschemes重置所有电源计划为系统默认,执行完重启电脑,重新设置屏保等待时长即可。

原有控制脚本的修正方案

你之前写的脚本缺少退出兜底逻辑,一旦程序崩溃、被任务管理器强杀,根本走不到重置状态的逻辑,就会出现这次的残留锁问题。修正后的基础逻辑参考:

import ctypes
import atexit

# 常量定义
ES_CONTINUOUS = 0x80000000
ES_DISPLAY_REQUIRED = 0x00000002

def _reset_state():
    # 退出时强制重置为允许屏保状态
    ctypes.windll.kernel32.SetThreadExecutionState(ES_CONTINUOUS)

# 注册退出钩子,程序正常退出、抛异常退出时都会自动执行重置
atexit.register(_reset_state)

def block_screensaver():
    # 阻止屏保、熄屏
    ctypes.windll.kernel32.SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED)

def allow_screensaver():
    # 恢复允许屏保
    ctypes.windll.kernel32.SetThreadExecutionState(ES_CONTINUOUS)

# 程序启动时先主动重置一次,清掉上次运行可能残留的锁
allow_screensaver()

注意:即便是加了退出钩子,如果是直接拔电源、任务管理器强制结束进程树这类极端操作,还是可能出现状态残留,启动时主动重置的逻辑不能省。

内容的提问来源于stack exchange,提问作者Alex B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:33:10