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

时间:2022-08-31 20:44:45

原文 http://www.cnblogs.com/h46incon/p/SleepPreventer.html

因为有时下载东西的时候,不想让电脑自动深入睡眠,所以就开启了离开模式。这样不但不节能环保,而且到真正想要睡眠的时候就是一翻蛋疼。

改过自新,关闭了离开模式,同时无操作30分钟后也会进入睡眠模式。但是在下载的时候怎么办呢?反正也是闲着,就写了这东西:

增加了合上盖子时保持唤醒功能,截图懒得换了。

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

第一张是主界面,最小化时会隐藏窗口。后面的是托盘的菜单,托盘会根据不同的设置选择不同的图标。

其中,开启离开模式不需要修改注册表,自然的,也就在软件开着的时候有效。监控模式则是每隔半分钟,就将本次设置告知系统。为啥需要这个选项呢?往后看看实现就知道了。(嗯,发现其实不用这个选项的)

程序在最后面。


下面是实现(其实写这个程序的目的之一就是为了学习C#……):

(所谓的)核心代码是调用这个API ( MSDN的介绍) :

1
2
3
EXECUTION_STATE WINAPI SetThreadExecutionState(
  _In_  EXECUTION_STATE esFlags
);

这个API作用是允许程序通知系统在使用某些资源,以阻止系统进入睡眠或关闭显示器。

参数esFlags是以下选项的组合:ES_AWAYMODE_REQUIREDES_CONTINUOUSES_DISPLAY_REQUIREDES_SYSTEM_REQUIRED

按字面意思理解选项即可。其中ES_CONTINUOUS表示在下一次调用该API前,本次设置会一直生效。所以在大部分情况下,加上这个选项的话,只需调用一次API即可。但考虑到可能有别的程序也在调用这个API,因而让本程序的设置失效,所以有了监控模式:每隔一断时间就将设置通知系统。(这个API是针对每个线程而言的,只要这个线程不退出,和CONTINUOUS一起设置的选项就会一直生效)。

若是单独使用ES_CONTINUOUS选项,则会恢复睡眠策略。

C# 怎么使用Win32API呢?

1
2
3
4
5
6
7
8
9
using System.Runtime.InteropServices;
// 按照API原型,将类型转换C#的类型声明即可
[DllImport("kernel32.dll")]
static extern uint SetThreadExecutionState(uint esFlags);
// 选项所用到的常数
const uint ES_AWAYMODE_REQUIRED = 0x00000040;
const uint ES_CONTINUOUS = 0x80000000;
const uint ES_DISPLAY_REQUIRED = 0x00000002;
const uint ES_SYSTEM_REQUIRED = 0x00000001;

C#所有的方法变量都必须声明在一个类里。我把这些东西声明到一个叫Public的类。声明后,就可以直接调用该方法了。

(不知道起什么子标题……)

该程序可以通过主界面以及托盘弹出的菜单进行选择的设置,所以需要同步这两个地方的状态,Checkbox该自动打钩时打钩,该取消时取消等等。为了写代码时,不需要考虑这些东西,就抽象出了一个Option类(每次起名的时候就痛恨自己英文太差)。通过该类可以设置选项,同时也可以在里面注册一个委托,当选项有变时,会调用这些委托。同时,该类也会负责在设置选项时自动通知系统。注:在析构函数中,以参数ES_CONTINUOUS调用一次该API恢复原来的休眠配置。

主界面:

主界面就是拉拉控件,处理下事件。注意,Checkbox的选项值可能会因为鼠标点击以外的原因改变,所以选择监听鼠标点击事件。为了处理事件时少粘贴点代码,我用一个Dictionary将 每个CheckBox和一个选项值绑定在一起。然后使用同一个事件处理函数,在函数里,根据sender确定是哪个Checkbox发送的,再根据那个 Dictionary确定需要设置什么样的值。 然后向Option类注册一个委托,在选项有变时改变Checkbox到正确的状态。

最小化时直接隐藏窗口,而不是缩小的任务栏:可以选择监听Resize事件,在事件中判断窗体是不是处于最小化的状态,是的话就隐藏窗体。更彻底的是重载窗体类的消息处理函数,并自己处理最小化消息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected override void WndProc(ref Message m)
{
    const int WM_SYSCOMMAND = 0x112;
    const int SC_CLOSE = 0xF060;
    const int SC_MINIMIZE = 0xF020;
    const int SC_MAXIMIZE = 0xF030;
    if (m.Msg == WM_SYSCOMMAND)
    {
        if (m.WParam.ToInt32() == SC_MINIMIZE)
        {
            this.Hide();
            return;
        }
    }
    base.WndProc(ref m);
}

托盘部分:

托盘:使用NotifyIcon控件。注意,这个控件必须设置ICON才能显示。添加一个ContextMenuStrip对 象作为右键点击时的弹出菜单。为了让点击托盘时能弹出这个菜单,可以将托盘控件的ContextMenuStrip属性设置为该菜单即可。在这里因为我需 要监听鼠标事件,让左键点击时显示主窗口,我就在事件处理函数中顺便处理右键点击了。如果是右键点击,则调用该菜单的Show方法就可以了。

然后是菜单的内容。新建若干ToolStripMenuItem对象,并用ContextMenuStrip.Items.Add(…)方法将这些Item添加进菜单即可。每个Item可以监听鼠标点击事件,同时也可以通过设置它的Checked属性来显示item文本前的小钩钩。需要分割线的话添加ToolStripSeparator对象就可以了。

动态的托盘图标:为了少写点什么读取文件之类的代码,就直接把托盘图标添加进程序的资源文件里了。方法是在项目的属性里选择资源,然后就可以添加想要的资源了。需要访问这些资源时,在myProject.Properties.Resources里就可以访问了。如:System.Drawing.Bitmap bitmap1 = myProject.Properties.Resources.Image01(参考MSDN)。最后再根据选项的状态选择相应的图标即可。

托盘消失:直接执行Application.Exit()的话,托盘不会自动消失,得鼠标从托盘上面滑过才可以。为了让托盘显示,执行NotifyIcon对象的Dispose( )方法就好了。

让程序开始运行时只显示托盘,而不显示主窗体。放狗搜索的时候发现这个问题让很多新手喝了一壶。我的解决方法是:让程序开始是不运行主窗体的代码,只运行托盘控件的代码。转到Main函数,发现Main函数最后执行的是 Application.Run(…) 这个方法。最开始尝试在这个方法的参数里填入一个NotifyIcon对象,但是不行。然后试着直接用new新建一个NotifyIcon对象,这个时候托盘是会显示出来,但是程序马上就会退出了。最后发现这个方法有个无参重载版本,执行后程序就不会退出了……

生成的EXE的图标:在项目的属性里,选择应用程序选项卡,就可以设置图标了。


睡眠终结者:http://files.cnblogs.com/h46incon/SleepPreventer.zip

阻止系统自动睡眠的小软件,附C#制作过程的更多相关文章

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

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

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

    原文:.NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态 在 Windows 系统中,一段时间不操作键盘和鼠标,屏幕便会关闭,系统会进入睡眠状态.但有些程序(比如游戏.视频和演示文稿)在运行过程中应该 ...

  3. 编译udf小软件(附视频教程)

    小软件下载地址(不仅支持Visual Studio并且打包gcc,解压即可编译): https://pan.baidu.com/s/1XPfjfY8DC2KKS8gj1KhutQ 提取码: 6kju ...

  4. 今天在Mac机器上使用了Flex Builder编辑了一个源代码文件,保存后使用vim命令去打开时发现系统自动在每一行的结尾添加了^M符号,其实^M在Linux/Unix中是非常常见的,也就是我们在Win中见过的/r回车符号。由于编辑软件的编码问题,某些IDE的编辑器在编辑完文件之后会自动加上这个^M符号。看起来对我们的源代码没有任何影响,其实并不然,当我们把源代码文件Check In到svn之类

    今天在Mac机器上使用了Flex Builder编辑了一个源代码文件,保存后使用vim命令去打开时发现系统自动在每一行的结尾添加了^M符号,其实^M在Linux/Unix中是非常常见的,也就是我们在W ...

  5. win10总是2分钟就自动睡眠怎么办 win10系统自动休眠bug怎么解决(转)

        解决方法如下: 1.右键点击开始图标,选择[运行],或者利用快捷键“win+R”打开运行窗口,win键是ctrl和alt键中间的徽标键:

  6. Mac 上有哪些比较有意思的小软件?

    文章素材来源:微博.新浪看点 收录于:风云社区(SCOEE)[提供mac软件下载] 更多专题,可关注小编[磨人的小妖精],查看我的文章,也可上[风云社区 SCOEE],查找和下载相关软件资源. (一) ...

  7. win10系统如何关掉系统自动更新

    越来越多的电脑使用者都在使用Windows10系统,尽管系统是一代代更新的,但难免有槽点,Windows10系统也不例外,最大的槽点就是“自动更新”的功能.当然,“自动更新”的功能也是相当有用处的.  ...

  8. 【开源小软件 】Bing每日壁纸 V1.2.1

    Bing每日壁纸发布V1.2版本,下载地址Release V1.2.1 该小软件可以自动获取Bing的精美图片设置为壁纸,并且支持随机切换历史壁纸,查看壁纸故事. 本次新增国际化支持,以及桌面widg ...

  9. 如何在Windows系统上用抓包软件Wireshark截获iPhone等网络通讯数据

    http://www.jb51.net/os/windows/189090.html 今天给大家介绍一种如何在Windows操作系统上使用著名的抓包工具软件Wireshark来截获iPhone.iPa ...

随机推荐

  1. Javascript学习记录——原生JS实现旋转木马特效

    昨天学习到了JS特效部分,然后老师讲了旋转木马特效的实现,如上图.不过只是讲了通过点击箭头实现图片的切换,对于点击图片本身以及二者联动却是没有讲解. 本着一颗追求完美的心,今天花费了一个中午终于将整个 ...

  2. java基础知识(二)字符串处理

    字符串是程序开发中使用最为频繁,因此为了工作的高效和作为一名想进阶的程序员,了解并掌握字符串的处理显得尤为重要.java为我们提供了String.StringBuffer.StringBuilde三个 ...

  3. Sublime Text 之 Package Control 镜像

    本文同步自我的个人博客:http://www.52cik.com/2015/11/24/Package-Control.html 这阵子经常有朋友跟我说 Sublime Text 下的 Package ...

  4. sql查询数据库表中重复记录方法

    1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 代码如下: select * from people where peopleId in (select peopleId ...

  5. 利用cookies+requests包登陆微博,使用xpath抓取目标用户的用户信息、微博以及对应评论

    本文目的:介绍如何抓取微博内容,利用requests包+cookies实现登陆微博,lxml包的xpath语法解析网页,抓取目标内容. 所需python包:requests.lxml 皆使用pip安装 ...

  6. grub2与grub区别

    关于版本: GRUB2 使之版本号为1.98之后的grub:GRUB legacy(版本为0.97)是指GRUB,而非GRUB2,grub是指 grub1.97 和以前的,grub 2 指的是 gru ...

  7. SQL 常用语法记录

    SQL语法 注意:SQL 对大小写不敏感 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). 数据操作语言 (DML) SQL (结构化查询语言)是用于执行查询的语 ...

  8. ueditor 百度编辑器 解决表格没有边框

    因为项目需要,发现直接从word和excel复制粘贴以后,居然在禅道上表格没有边框了,故查了一下 这里从word,以及excel粘贴复制,都能直接有边框了,同时在编辑器里面新增表格,也能直接显示边框了 ...

  9. php.ini中的pcre

    当页面代码没有任何问题,也没有报错.但是页面的循环很多,请求导致开销很大的时候,有可能要改php.ini中的pcre部分. [Pcre]pcre.recursion_limit=-1pcre.back ...

  10. Lua 基础总结

    lua 数组下标从 1 开始, 不是 0 lua 逻辑运算符  与 或 非  就是英文  and  or  not local  局部变量 数据类型:lua是一门动态类型语言,变量没有类型,只有值才有 ...