You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SetThreadExecutionState(ES_SYSTEM_REQUIRED)在Windows 11中无法阻止系统休眠的原因及替代API咨询

SetThreadExecutionState在Windows 11失效的原因及解决方法

我之前开发文件传输工具时也碰到过一模一样的问题,折腾了好一阵才搞清楚Windows 11对电源管理API的行为调整。

核心原因:Windows 11对ES_CONTINUOUS标志的强制要求

在Windows 10中,即使单次调用SetThreadExecutionState(ES_SYSTEM_REQUIRED),系统也会累计这些请求维持唤醒状态。但Windows 11为了提升电源效率,对这个API的逻辑做了严格限制:

  • 单纯的ES_SYSTEM_REQUIRED单次调用会被系统视为临时唤醒请求,无法阻止系统进入休眠
  • 必须结合ES_CONTINUOUS标志,明确告诉系统“我需要持续保持唤醒状态,直到主动取消”

Windows文件资源管理器之所以能成功阻止休眠,正是因为它在文件传输启动时调用了SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED),传输结束后再调用SetThreadExecutionState(ES_CONTINUOUS)重置状态,完全符合Win11的电源管理规则。

修复你的代码

针对你的C# WinForms示例,只需要调整调用方式即可:

1. 更新枚举定义,添加ES_CONTINUOUS

public enum EXECUTION_STATE : uint
{
    ES_SYSTEM_REQUIRED = 0x00000001,
    ES_CONTINUOUS = 0x80000000
}

2. 在任务开始时设置持续唤醒状态

比如在窗体加载或者传输启动事件中:

private void Form_Load(object sender, EventArgs e)
{
    // 告诉系统要持续保持唤醒状态
    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED);
    timer1.Start();
}

3. 在任务结束时重置电源状态

比如在窗体关闭或者传输完成事件中:

private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
    // 恢复系统正常的电源管理
    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
}

可选:周期性确认(针对超长任务)

如果你的任务会持续数小时以上,可以在计时器中重复调用带ES_CONTINUOUS的组合,确保系统不会因为超时忽略你的请求:

private void timer1_Tick(object sender, EventArgs e)
{
    label1.Text = (int.Parse(label1.Text) + 1).ToString();
    // 周期性确认持续唤醒需求
    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED);
}

额外注意事项

  • 不要忘记在任务结束后重置状态,否则系统会一直保持唤醒,浪费电量
  • 如果是后台服务类程序,需要确保线程处于活跃状态,Win11对后台线程的电源管理限制更严格
  • 不需要使用ES_AWAYMODE_REQUIRED,这个标志是为远程桌面等场景设计的,普通文件传输用ES_CONTINUOUS | ES_SYSTEM_REQUIRED就足够

内容的提问来源于stack exchange,提问作者Martin Prikryl

火山引擎 最新活动