如何防止Windows进入空闲状态?

Posted

技术标签:

【中文标题】如何防止Windows进入空闲状态?【英文标题】:How to prevent Windows from entering idle state? 【发布时间】:2011-09-12 05:32:31 【问题描述】:

我正在开发一个 C# 应用程序,它在没有任何 Windows 控件的情况下在后台运行。

我想通知 Windows 我的应用程序仍处于活动状态,以防止 Windows 进入空闲状态。

是否有任何 API 可从我的应用程序调用,通知 Windows 操作系统我的应用程序仍然存在?

提前致谢。

【问题讨论】:

一定要让你的用户知道应用程序需要持续运行,并且它可以防止 Windows 进入空闲状态。这对于使用笔记本电脑的用户来说尤其重要。 【参考方案1】:

你必须使用SetThreadExecutionState 函数。像这样的:

public partial class MyWinForm: Window

    private uint fPreviousExecutionState;

    public Window1()
    
        InitializeComponent();

        // Set new state to prevent system sleep
        fPreviousExecutionState = NativeMethods.SetThreadExecutionState(
            NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED);
        if (fPreviousExecutionState == 0)
        
            Console.WriteLine("SetThreadExecutionState failed. Do something here...");
            Close();
        
    

    protected override void OnClosed(System.EventArgs e)
    
        base.OnClosed(e);

        // Restore previous state
        if (NativeMethods.SetThreadExecutionState(fPreviousExecutionState) == 0)
        
            // No way to recover; already exiting
        
    


internal static class NativeMethods

    // Import SetThreadExecutionState Win32 API and necessary flags
    [DllImport("kernel32.dll")]
    public static extern uint SetThreadExecutionState(uint esFlags);
    public const uint ES_CONTINUOUS = 0x80000000;
    public const uint ES_SYSTEM_REQUIRED = 0x00000001;

【讨论】:

在我们客户的一些 Windows XP 机器上,NativeMethods.SetThreadExecutionState 永远不会返回 0,知道吗? @Alessio - 返回0 表示方法失败。来自SetThreadExecutionState的文档——“如果函数成功,返回值为之前的线程执行状态。如果函数失败,返回值为NULL。” (注意 - 我假设您可能已经想通了,但想发布一个完整的答案并帮助其他可能出现并查看您的评论的人) 在尝试解决运行 Windows 8.1 的 Surface Pro 3 反复出现且难以解决的睡眠问题时,我可以明确指出,很遗憾,此解决方案不适用于此操作系统上的此问题。跨度> 可能是我,但这在 Windows 10 中似乎不起作用 在 Win 10 @ecklerpa 中为我工作。另外,如果有人需要为可见的应用程序执行此操作,请记住设置 ES_DISPLAY_REQUIRED 以避免显示关闭。【参考方案2】:

你有几个选择:

使用SetThreadExecutionState,其中:

使应用程序能够通知系统它正在使用,从而防止系统在应用程序运行时进入睡眠或关闭显示器。

您可以在哪里使用ES_SYSTEM_REQUIRED 标志

通过重置系统空闲计时器强制系统处于工作状态。

使用SendInput 来伪造击键、鼠标移动/点击

另一种选择是将您的应用更改为 Windows 服务。

SetThreadExecutionState 示例

// Television recording is beginning. Enable away mode and prevent
// the sleep idle time-out.
SetThreadExecutionState(
    ES_CONTINUOUS | 
    ES_SYSTEM_REQUIRED | 
    ES_AWAYMODE_REQUIRED);

// Wait until recording is complete...
// Clear EXECUTION_STATE flags to disable away mode and allow the system
// to idle to sleep normally.
SetThreadExecutionState(ES_CONTINUOUS);

【讨论】:

【参考方案3】:

您可以使用此处描述的SetThreadExecutionState

SetThreadExecutionState Function

由于它是一个 Win32 API 函数,要从 C# 中使用它,您需要 PInvoke 它。这里描述了这些步骤,包括一个示例方法PreventSleep 来临时禁用睡眠模式:

PInvoke.net: setthreadexecutionstate (kernel32)

【讨论】:

【参考方案4】:

我认为没有任何方法可以直接在托管代码中执行此操作。

快速搜索发现this 2 年前的帖子。基本上你需要做一些互操作来调用原始 Windows API。

【讨论】:

【参考方案5】:

这里是SetThreadExecutionState C# 实现

【讨论】:

以上是关于如何防止Windows进入空闲状态?的主要内容,如果未能解决你的问题,请参考以下文章

当我的程序运行时,防止 Windows 进入睡眠状态?

Rabbitmq 空闲连接断开

在 windows 上使用 tensorflow 时,GPU 大部分时间都处于空闲状态

Linux/Windows 睡眠时间

如何检测是不是有任何进程阻止 Windows 进入睡眠状态?

Windows安全模式能不能防止别的软件读取屏幕?