原文:.NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态

在 Windows 系统中,一段时间不操作键盘和鼠标,屏幕便会关闭,系统会进入睡眠状态。但有些程序(比如游戏、视频和演示文稿)在运行过程中应该阻止屏幕关闭,否则屏幕总是关闭,会导致体验会非常糟糕。

本文介绍如何编写 .NET/C# 代码临时阻止屏幕关闭以及系统进入睡眠状态。


本文内容

Windows API

我们需要使用到一个 Windows API:

/// <summary>
/// Enables an application to inform the system that it is in use, thereby preventing the system from entering sleep or turning off the display while the application is running.
/// </summary>
[DllImport("kernel32")]
private static extern ExecutionState SetThreadExecutionState(ExecutionState esFlags);
  • 1
  • 2
  • 3
  • 4
  • 5

使用到的枚举用 C# 类型定义是:

[Flags]
private enum ExecutionState : uint
{
/// <summary>
/// Forces the system to be in the working state by resetting the system idle timer.
/// </summary>
SystemRequired = 0x01, /// <summary>
/// Forces the display to be on by resetting the display idle timer.
/// </summary>
DisplayRequired = 0x02, /// <summary>
/// This value is not supported. If <see cref="UserPresent"/> is combined with other esFlags values, the call will fail and none of the specified states will be set.
/// </summary>
[Obsolete("This value is not supported.")]
UserPresent = 0x04, /// <summary>
/// Enables away mode. This value must be specified with <see cref="Continuous"/>.
/// <para />
/// Away mode should be used only by media-recording and media-distribution applications that must perform critical background processing on desktop computers while the computer appears to be sleeping.
/// </summary>
AwaymodeRequired = 0x40, /// <summary>
/// Informs the system that the state being set should remain in effect until the next call that uses <see cref="Continuous"/> and one of the other state flags is cleared.
/// </summary>
Continuous = 0x80000000,
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

以上所有的注释均照抄自微软的官方 API 文档:

API 封装

如果你擅长阅读英文,那么以上的 API 函数、枚举和注释足够你完成你的任务了。

不过,我这里提供一些封装,以应对一些常用的场景。

using System;
using System.Runtime.InteropServices; namespace Walterlv.Windows
{
/// <summary>
/// 包含控制屏幕关闭以及系统休眠相关的方法。
/// </summary>
public static class SystemSleep
{
/// <summary>
/// 设置此线程此时开始一直将处于运行状态,此时计算机不应该进入睡眠状态。
/// 此线程退出后,设置将失效。
/// 如果需要恢复,请调用 <see cref="RestoreForCurrentThread"/> 方法。
/// </summary>
/// <param name="keepDisplayOn">
/// 表示是否应该同时保持屏幕不关闭。
/// 对于游戏、视频和演示相关的任务需要保持屏幕不关闭;而对于后台服务、下载和监控等任务则不需要。
/// </param>
public static void PreventForCurrentThread(bool keepDisplayOn = true)
{
SetThreadExecutionState(keepDisplayOn
? ExecutionState.Continuous | ExecutionState.SystemRequired | ExecutionState.DisplayRequired
: ExecutionState.Continuous | ExecutionState.SystemRequired);
} /// <summary>
/// 恢复此线程的运行状态,操作系统现在可以正常进入睡眠状态和关闭屏幕。
/// </summary>
public static void RestoreForCurrentThread()
{
SetThreadExecutionState(ExecutionState.Continuous);
} /// <summary>
/// 重置系统睡眠或者关闭屏幕的计时器,这样系统睡眠或者屏幕能够继续持续工作设定的超时时间。
/// </summary>
/// <param name="keepDisplayOn">
/// 表示是否应该同时保持屏幕不关闭。
/// 对于游戏、视频和演示相关的任务需要保持屏幕不关闭;而对于后台服务、下载和监控等任务则不需要。
/// </param>
public static void ResetIdle(bool keepDisplayOn = true)
{
SetThreadExecutionState(keepDisplayOn
? ExecutionState.SystemRequired | ExecutionState.DisplayRequired
: ExecutionState.SystemRequired);
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

如果你对这段封装中的 keepDisplayOn 参数,也就是 ExecutionState.DisplayRequired 枚举不了解,看看下图直接就懂了。一个指的是屏幕关闭,一个指的是系统进入睡眠。

此封装后,使用则相当简单:

// 阻止系统睡眠,阻止屏幕关闭。
SystemSleep.PreventForCurrentThread(); // 恢复此线程曾经阻止的系统休眠和屏幕关闭。
SystemSleep.RestoreForCurrentThread();
  • 1
  • 2
  • 3
  • 4
  • 5

或者:

// 重置系统计时器,临时性阻止系统睡眠和屏幕关闭。
// 此效果类似于手动使用鼠标或键盘控制了一下电脑。
SystemSleep.ResetIdle();
  • 1
  • 2
  • 3

在使用 PreventForCurrentThread 这个 API 的时候,你需要避免程序对空闲时机的控制不好,导致屏幕始终不关闭。

如果你发现无论你设置了多么短的睡眠时间和屏幕关闭时间,屏幕都不会关闭,那就是有某个程序阻止了屏幕关闭,你可以:


参考资料


我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

发布了382 篇原创文章 · 获赞 232 · 访问量 47万+

.NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态的更多相关文章

  1. 阻止系统自动睡眠的小软件,附C#制作过程

    原文 http://www.cnblogs.com/h46incon/p/SleepPreventer.html 因为有时下载东西的时候,不想让电脑自动深入睡眠,所以就开启了离开模式.这样不但不节能环 ...

  2. 阻止系统自动睡眠的小软件,附C#制作过程(执行SetThreadExecutionState API函数,让系统误判)

    因为有时下载东西的时候,不想让电脑自动深入睡眠,所以就开启了离开模式.这样不但不节能环保,而且到真正想要睡眠的时候就是一翻蛋疼. 改过自新,关闭了离开模式,同时无操作30分钟后也会进入睡眠模式.但是在 ...

  3. AlertDialog通过反射机制阻止Dialog关闭

    在开发Android应用程序时,我们可能会用到需要用户输入的Dialog,如登录对话框等.这时候,如果用户没有输入登录信息而点击<确定>按钮时,我们并不希望登录Dialog消失,而是采用一 ...

  4. Android--保持加速度传感器在屏幕关闭后运行

    由于写论文需要,需要用手机加速度采集数据,关于android加速度传感器的介绍网上一抓一大把,但大多都是大同小异,跟官网文档差不多.自己写了个取加速度传感器的APK,发现数据有点不对劲,原理屏幕一关后 ...

  5. Android--保持加速度传感器在屏幕关闭后运行(收集)

    由于写论文需要,需要用手机加速度采集数据,关于android加速度传感器的介绍网上一抓一大把,但大多都是大同小异,跟官网文档差不多.自己写了个取加速度传感器的APK,发现数据有点不对劲,原理屏幕一关后 ...

  6. 怎样关闭WIN7系统的自动更新

    百度经验 > 游戏/数码 > 电脑 > 电脑软件 怎样关闭WIN7系统的自动更新 听语音 | 浏览:108460 | 更新:2012-07-24 18:03 | 标签:win7 1 ...

  7. android 点击屏幕关闭 软键盘

    //点击屏幕 关闭输入弹出框 @Override public boolean onTouchEvent(MotionEvent event) { InputMethodManager im = (I ...

  8. Microsoft Dynamics CRM4.0 JScript 过滤lookup 出现 Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止。

    一.现象:JScript过滤lookup字段,选择lookup字段出现下图的情况: 出现:Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止.请将这台Micro ...

  9. 怎么关闭win10快速访问功能?关闭Windows10系统快速访问方法

    怎么关闭win10快速访问功能?关闭Windows10系统快速访问方法 Windows10系统的"快速访问"功能很容易泄露电脑中的隐私,用什么方法可以让这个功能消失,避免电脑的个人 ...

随机推荐

  1. shell脚本编程基础之函数

    函数 作用:代码重用 定义函数: 方法1: function FUNCTION_NAME { #函数名和定义变量名一样,只能包含数字字母下划线,并且不能以数字开头 command } 方法2: FUN ...

  2. 在GitHub上使用Hexo 搭建自己的博客

    1.下载Node.js安装文件(现在电脑基本都是64位的,我就放64位的下载地址):https://nodejs.org/dist/v8.9.4/node-v8.9.4-x64.msi 或者自行到官网 ...

  3. Intellij IDEA 智能补全的 10 个姿势,太牛逼了。。

    一年多前,栈长那时候刚从 Eclipse 转型 IDEA 成功,前面转了好多次,都是失败史,都是泪..后面我就在微信公众号 "Java技术栈" 写了这篇文章:Intellij ID ...

  4. hotspot编译

    "AA=="1",==", /usr/bin/make -s VERBOSE="-s" LOG_LEVEL="warn" ...

  5. Linux学习笔记(一)

    操作系统(operation system,os) 主要作用是管理好硬件设备,并为用户和应用程序提供一个简单的接口, 以便于使用,作为中间人,连接软件和硬件 操作系统linux发展历程 unix-&g ...

  6. TTA 方法

    可将准确率提高若干个百分点,它就是测试时增强(test time augmentation, TTA). 这里会为原始图像造出多个不同版本,包括不同区域裁剪和更改缩放程度等,并将它们输入到模型中: 然 ...

  7. MySQL Group By 实例讲解(一)

    MySQL Group By 实例讲解 group by语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表. SELECT子句中的列名必须为分组列或列函数.列函数对于GRO ...

  8. hive中同源多重insert写法

    多重insert: with tmp_a as ( select name from tmp_test3 ) from tmp_a insert overwrite table tmp_test1 s ...

  9. matlab学习笔记11_1低维数组操作

    一起来学matlab-matlab学习笔记11 11_1 低维数组操作repmat函数,cat函数,diag函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab ...

  10. Node.js+Express框架+Mongo学习(一)第一个node.js实例

    1.在桌面新建一个空的文件夹,比如叫node,当然也可以在其它地方新建. 2.命令行进入到所新建的文件夹的目录,下载Express框架,再在这个文件夹里新建一个叫final的项目 3.在项目(fina ...