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

如何阻止Windows 11进入睡眠?SetThreadExecutionState尝试无效

阻止Windows 11进入睡眠状态的解决方案

问题重现

尝试通过SetThreadExecutionState的多种参数组合阻止Windows 11睡眠,代码示例如下:

private const uint ES_CONTINUOUS = 0x80000000;
private const uint ES_SYSTEM_REQUIRED = 0x00000001;
private const uint ES_DISPLAY_REQUIRED = 0x00000002;
private const uint ES_AWAYMODE_REQUIRED = 0x00000040;

// 尝试过的调用组合
// ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED

for (;;)
{
    SetThreadExecutionState(ES_SYSTEM_REQUIRED);
    // SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
    // SetThreadExecutionState(ES_AWAYMODE_REQUIRED)
    // SetThreadExecutionState(ES_AWAYMODE_REQUIRED | ES_CONTINUOUS);
    // SetThreadExecutionState(ES_AWAYMODE_REQUIRED | ES_SYSTEM_REQUIRED | ES_CONTINUOUS);

    Thread.Sleep(10000);
    Console.WriteLine("The current time is: " + DateTime.Now);             
}

无论在循环内/外调用该函数,系统仍会在3-5分钟后进入睡眠状态。

可能的原因

  1. ES_CONTINUOUS参数使用不当:单独调用ES_SYSTEM_REQUIRED仅会临时阻止睡眠,系统超时后会恢复原有策略;ES_CONTINUOUS需与其他参数组合使用,才能让唤醒请求持续生效。
  2. Windows 11现代待机(Modern Standby)机制:如果设备启用了S0低功耗待机模式,传统的SetThreadExecutionState可能无法完全覆盖系统的睡眠触发逻辑。
  3. 系统电源策略限制:组策略、管理员设置或厂商电源管理软件可能强制系统进入睡眠,忽略应用层的唤醒请求。
  4. 程序电池优化设置:Windows的电池优化功能可能限制了程序的后台活动,导致唤醒请求被系统忽略。

解决方案

1. 修正SetThreadExecutionState的用法

正确的调用方式是:

  • 程序启动时,调用一次SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED),标记持续的系统唤醒请求;
  • 每隔一段时间(推荐1-2分钟)调用一次SetThreadExecutionState(ES_SYSTEM_REQUIRED),刷新唤醒请求,避免系统超时重置。

修正后的代码示例:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern uint SetThreadExecutionState(uint esFlags);

private const uint ES_CONTINUOUS = 0x80000000;
private const uint ES_SYSTEM_REQUIRED = 0x00000001;

static void Main(string[] args)
{
    // 初始化持续唤醒请求
    SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);

    try
    {
        while (true)
        {
            // 刷新唤醒请求
            SetThreadExecutionState(ES_SYSTEM_REQUIRED);
            Console.WriteLine("当前时间: " + DateTime.Now);
            Thread.Sleep(60000); // 每分钟刷新一次
        }
    }
    finally
    {
        // 程序退出时清除唤醒请求
        SetThreadExecutionState(ES_CONTINUOUS);
    }
}

2. 使用Power API应对现代待机(Modern Standby)

如果设备启用了S0待机模式,需使用PowerSetRequest API来创建系统唤醒请求,示例代码如下:

using System;
using System.Runtime.InteropServices;
using System.Threading;

class Program
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct POWER_REQUEST_CONTEXT
    {
        public UInt32 Version;
        public UInt32 Flags;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string SimpleReasonString;
    }

    [DllImport("kernel32.dll")]
    private static extern IntPtr PowerCreateRequest(ref POWER_REQUEST_CONTEXT Context);

    [DllImport("kernel32.dll")]
    private static extern bool PowerSetRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);

    [DllImport("kernel32.dll")]
    private static extern bool PowerClearRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hObject);

    private enum PowerRequestType
    {
        PowerRequestDisplayRequired = 0,
        PowerRequestSystemRequired,
        PowerRequestAwayModeRequired,
        PowerRequestMaximum
    }

    static void Main(string[] args)
    {
        // 创建电源请求上下文
        POWER_REQUEST_CONTEXT powerRequestContext = new POWER_REQUEST_CONTEXT();
        powerRequestContext.Version = 0;
        powerRequestContext.Flags = 0;
        powerRequestContext.SimpleReasonString = "阻止系统睡眠";

        // 创建电源请求句柄
        IntPtr powerRequestHandle = PowerCreateRequest(ref powerRequestContext);

        if (powerRequestHandle != IntPtr.Zero)
        {
            // 设置系统唤醒请求
            PowerSetRequest(powerRequestHandle, PowerRequestType.PowerRequestSystemRequired);

            try
            {
                while (true)
                {
                    Console.WriteLine("当前时间: " + DateTime.Now);
                    Thread.Sleep(60000);
                }
            }
            finally
            {
                // 清除请求并释放句柄
                PowerClearRequest(powerRequestHandle, PowerRequestType.PowerRequestSystemRequired);
                CloseHandle(powerRequestHandle);
            }
        }
        else
        {
            Console.WriteLine("创建电源请求失败");
        }
    }
}

3. 检查系统设置

  • 电池优化设置:打开「设置」→「系统」→「电池」→「电池优化」,找到你的程序,设置为「不允许」,确保程序后台活动不受限制。
  • 电源计划设置:检查当前电源计划的「睡眠」超时设置,确保没有被强制设置为短时间;若使用笔记本,检查厂商电源管理软件是否有额外的睡眠策略。
  • 组策略检查:运行gpedit.msc,查看「计算机配置」→「管理模板」→「系统」→「电源管理」下的策略,确认没有强制睡眠的设置。

内容的提问来源于stack exchange,提问作者Rowan Smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:22:07