.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/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
.NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态的更多相关文章
- 阻止系统自动睡眠的小软件,附C#制作过程
原文 http://www.cnblogs.com/h46incon/p/SleepPreventer.html 因为有时下载东西的时候,不想让电脑自动深入睡眠,所以就开启了离开模式.这样不但不节能环 ...
- 阻止系统自动睡眠的小软件,附C#制作过程(执行SetThreadExecutionState API函数,让系统误判)
因为有时下载东西的时候,不想让电脑自动深入睡眠,所以就开启了离开模式.这样不但不节能环保,而且到真正想要睡眠的时候就是一翻蛋疼. 改过自新,关闭了离开模式,同时无操作30分钟后也会进入睡眠模式.但是在 ...
- AlertDialog通过反射机制阻止Dialog关闭
在开发Android应用程序时,我们可能会用到需要用户输入的Dialog,如登录对话框等.这时候,如果用户没有输入登录信息而点击<确定>按钮时,我们并不希望登录Dialog消失,而是采用一 ...
- Android--保持加速度传感器在屏幕关闭后运行
由于写论文需要,需要用手机加速度采集数据,关于android加速度传感器的介绍网上一抓一大把,但大多都是大同小异,跟官网文档差不多.自己写了个取加速度传感器的APK,发现数据有点不对劲,原理屏幕一关后 ...
- Android--保持加速度传感器在屏幕关闭后运行(收集)
由于写论文需要,需要用手机加速度采集数据,关于android加速度传感器的介绍网上一抓一大把,但大多都是大同小异,跟官网文档差不多.自己写了个取加速度传感器的APK,发现数据有点不对劲,原理屏幕一关后 ...
- 怎样关闭WIN7系统的自动更新
百度经验 > 游戏/数码 > 电脑 > 电脑软件 怎样关闭WIN7系统的自动更新 听语音 | 浏览:108460 | 更新:2012-07-24 18:03 | 标签:win7 1 ...
- android 点击屏幕关闭 软键盘
//点击屏幕 关闭输入弹出框 @Override public boolean onTouchEvent(MotionEvent event) { InputMethodManager im = (I ...
- Microsoft Dynamics CRM4.0 JScript 过滤lookup 出现 Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止。
一.现象:JScript过滤lookup字段,选择lookup字段出现下图的情况: 出现:Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止.请将这台Micro ...
- 怎么关闭win10快速访问功能?关闭Windows10系统快速访问方法
怎么关闭win10快速访问功能?关闭Windows10系统快速访问方法 Windows10系统的"快速访问"功能很容易泄露电脑中的隐私,用什么方法可以让这个功能消失,避免电脑的个人 ...
随机推荐
- Codeforces Round #595 (Div. 3)
A - Yet Another Dividing into Teams 题意:n个不同数,分尽可能少的组,要求组内没有两个人的差恰为1. 题解:奇偶分组. int a[200005]; void te ...
- PhpStorm 设置自动FTP同步文件
1.添加一个FTP服务器 ① 首先在这里打开添加FTP的页面,步骤,工具栏 -> Tools -> Deployment -> Configuration . ②添加服务器 ...
- js中判断变量不为空或null
var content=$("content").val(); if(!content){ alert("请输出内容!"); return; ...
- centos7---mysql5.7主从复制读写分离
1 分别在两台centos 7系统上安装mysql 5.7 具体的安装步骤可以见此链接,https://blog.csdn.net/qq_15092079/article/details/816292 ...
- 腾讯云手动搭建nginx+php-fpm并自启动
自己一点小爱好,搭建了一个小网站植物大战僵尸百科, 使用的是腾讯云,市场里的镜像不好用,所以自己手动搭建一波. centos 7 编译安装 php-7.2.11的步骤 在官网下载php-7.2.11的 ...
- 【软工实践】Alpha冲刺(4/6)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 学习调用中国天气网API,接近实现天气推送功能 对天气推送的形式进行讨论及重确 ...
- rk3288 usb无线网卡支持 8188eu
第一部分是kernel 内核配置参考rk文档,把device driver 下wireless相关的先勾选上. 编译到buildin有问题,识别不到,所以打算编译成ko cd kernel/driv ...
- presto 日期函数和操作
https://prestodb.github.io/docs/current/functions/datetime.html date '2012-08-08' + interval '2' day ...
- Microsoft SQL Server 2008 R2 安装遇到的问题
SQL Server 安装过很多次了,第一次遇见这样的问题: TITLE: Microsoft SQL Server 2008 R2 安装程序----------------------------- ...
- java查看线程的堆栈信息
通过使用jps 命令获取需要监控的进程的pid,然后使用jstack pid 命令查看线程的堆栈信息. 通过jstack 命令可以获取当前进程的所有线程信息. 每个线程堆中信息中,都可以查看到线程ID ...