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

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

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

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

提前致谢。

【问题讨论】:

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

标签: c# 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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        这里是SetThreadExecutionState C# 实现

        【讨论】:

          猜你喜欢
          • 2015-07-26
          • 1970-01-01
          • 1970-01-01
          • 2019-08-27
          • 2017-05-24
          • 1970-01-01
          • 2013-11-07
          • 1970-01-01
          相关资源
          最近更新 更多