Windows开机和关机慢,很多时候慢得令人抓狂。特别是做嵌入式开发时(如XPE和WinCE),任谁都无法忍受开发出来的设备开关机的蜗牛速度。所以我们得为她加速。采用HORM是不错的方案,因为是直接从休眠文件中恢复系统现场,开机速度快了不少。采用HORM方案后,Windows默认的关机过程中,很多步骤对我们的设备来说,是完全不需要的,我们需要直接断电关机。本文将分析Windows的关机过程,然后介绍如何使用Windows未公开的API实现直接断电关机。

  一、Windows关机过程

  简单地说,在Windows关机时,系统做了以下工作:

  1. 软保护  首先先结束登录用户打开的所有程序,保存用户的设置和系统设置,然后停止系统服务和操作系统大部分进程。

  2. 硬保护 复位硬件,如复位磁盘的磁头、停止硬件驱动程序等。

  3. 断电 断开主板给各硬件设备的电源。当然这步需要主板的电源管理模块支持,一般来说,ATX电源和主板都支持软断电。

  在整个关机过程中,软保护是最耗时的,少则五六秒,多则上分钟。刚安装的操作系统,因为未安装驱动和开启额外的系统服务,关机非常快。开启服务一多,关机就慢下来了,特别是安装了有Bug的驱动,问题可能更糟。

  二、软保护

  为了保证数据的完整性,软保护是必须的,不管是操作系统本身还是第三方的应用程序。

  软保护的步骤有:

  1. 用户发起关机指令以后,发起关机指令的程序会通知Windows子系统CSRSS.EXE,CSRSS.EXE收到通知以后会和Winlogon.EXE做一个数据交换,接着由Winlogon.EXE通知CSRSS.EXE开始关闭系统的流程 。

  2. CSRSS.EXE收到Winlogon.EXE的通知以后,会依次查询拥有顶层窗口的用户进程,让这些用户进程退出。如果某一个用户进程在一个默认的超时时间5000毫秒(可以通过修改注册表键值HKEY_CURRENT_USER/Cont rol Panel/Desktop/ HungAppTimeout设定超时时间)内没有退出的话,Windows会显示一个结束任务对话框用于询问用户是否结束这个任务。默认情况下将显示这个对话框并一直保持而不会自动关闭。对于控制台程序来说,基本情况类似,只不过Windows使用HK EY_CURRENT_USER/Control Panel/Desktop/ WaitToKillAppTimeout值来设置超时时间。

  3. 接着是轮到终止系统进程了。系统进程包括SMSS.EXE、Winlogon.EXE、Lsass.EXE等。Windows在终止系统进程的时候并不像终止用户进程那样如果无法在规定时间内终止则提示用户,而是跳过这个进程,去执行下一个系统 进程的终止操作。使用的超时时间和第2步使用的时间相同。

  三、硬保护和断电

  在完成软保护过程后,Winlogon.EXE调用一个原生API函数ZwShutdownSystem()或NtShutdownSystem()来命令系统执行后面的扫尾工作,包括上面提到的硬保护和ATX断电。

  在ZwShutdownSystem函数调用过程中,Windows执行子系统会完成最后的关机操作,例如:设备驱动在这个阶段里面完成一些驱动设定的特殊操作;也是在这个阶段,配置管理系统将被修改过的注册表数据会写道磁盘里面。等除了电源管理以后的全部子系统完成退出以后,电源管理完成最后的操作,如重启、关机等。

  四、响应关机事件

  不管是直接按机箱上的Power按钮,还是点击开始菜单->关闭计算机(注销、关机、重启),我们的应用程序都可以响应这类事件,那就是窗口消息WM_QUERYENDSESSION和WM_ENDSESSION。

  系统提供了一个常用的API实现系统的注销、关机和重启,它的声明为:
  BOOL ExitWindowsEx(  UINT uFlags,  DWORD dwReason);

  参数uFlags可分为两类,之间可以用“|”合并:

  1. 关闭动作,有以下标志:EWX_LOGOFF(注销)、EWX_SHUTDOWN(关闭系统后不切断电源,即使主板支持ATX电源管理)、EWX_POWEROFF(关机,关闭系统后切断电源,需主板支持)、EWX_REBOOT(重启)。

  2. 关闭强度,有以下标志:数值0(安全关闭,不使用该类标志时默认为该项)、EWX_FORCEIFHUNG(应用程序挂起一段时间后强行关闭)、EWX_FORCE(强行关闭,不管应用程序有没有挂起)。

  如果不使用关闭强度标志(EWX_FORCE或EWX_FORCEIFHUNG),关机是安全的,也就是说,在关机的软保护时,系统将给每个以桌面为顶级的窗口进程发送WM_QUERYENDSESSION消息。如果超过5000毫秒(可以通过修改注册表键值HKEY_CURRENT_USER/Cont rol Panel/Desktop/ HungAppTimeout设定超时时间)仍未有WM_QUERYENDSESSION消息的返回,则弹出结束任务对话框用于询问用户是否结束这个任务。默认情况下将显示这个对话框并一直保持而不会自动关闭;如果设置了自动结束任务(HKEY_CURRENT_USER/Cont rol Panel/Desktop/AutoEndTasks键值改为1),那么超时(HungAppTimeout)后仍未有WM_QUERYENDSESSION消息的返回值时,不再显示结束任务对话框而直接结束这个挂起的任务。如果多个进程响应了WM_QUERYENDSESSION并挂起(如记事本弹出询问是否保存的消息框),那么系统对于每个进程是串行处理的,即等待第一个挂起的进程响应WM_QUERYENDSESSION并返回后(立即发送WM_ENDSESSION通知同一窗口用户的选择<是否确认关闭>),再给下一个进程发送WM_QUERYENDSESSION并等待挂起超时。

  需要注意的是,不管是点击系统弹出的结束任务对话框上的确定按钮,还是系统超时自动结束所有任务(已设置AutoEndTasks),那么挂起后的WM_QUERYENDSESSION和WM_ENDSESSION响应代码不会被执行。

  五、直接断电关机

  如上分析,如果您不在乎应用程序的数据丢失和操作系统的系统文件破坏(可能进不了系统),您完全可以把关机的软保护过程省略,来加快关机的速度。网上已经有许多快速关机软件,就是直接调用ntdll.dll中的ZwShutdownSystem()实现的。当然Windows系统本身也提供了这样的功能让您有选择地快速关机:打开任务管理器,按住键盘的Ctrl键,同时点击菜单“关机”-“关闭(或重启)”,即可在一两秒内立即断电关机。
  程序实现断电关机的代码如下:

const int SE_SHUTDOWN_PRIVILEGE = 0x13;typedef int (__stdcall *PFN_RtlAdjustPrivilege)( INT, BOOL, BOOL, INT*);typedef int (__stdcall *PFN_ZwShutdownSystem)(INT);HMODULE hModule = ::LoadLibrary(_T("ntdll.dll"));// 因为这里涉及到的函数都是微软未公开的,所以只能动态调用if( hModule != NULL){    PFN_RtlAdjustPrivilege pfnRtl = (PFN_RtlAdjustPrivilege)GetProcAddress( hModule, "RtlAdjustPrivilege");    PFN_ZwShutdownSystem pfnShutdown = (PFN_ZwShutdownSystem)GetProcAddress( hModule,"ZwShutdownSystem");if( (pfnRtl != NULL) && (pfnShutdown != NULL ))    {int en = 0;int nRet= pfnRtl( SE_SHUTDOWN_PRIVILEGE, TRUE, TRUE, &en);if( nRet == 0x0C000007C )            nRet = pfnRtl(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &en);//SH_SHUTDOWN = 0; //SH_RESTART = 1; //SH_POWEROFF = 2;         const int SH_POWEROFF = 2;        nRet = pfnShutdown(SH_POWEROFF);    }}

  

  补充,请注意文中提到的两个消息:WM_QUERYENDSESSION 和 WM_ENDSESSION
  今天在测试程序的时候,因为主程序里有一个while(1)循环,最后在关闭电脑的时候就会出现上面提到的情形,出现一个对话框,后来查阅资料发现没有处理到WM_DESTROY消息,后来又发现用自定义消息替换了系统消息之后还是不行,因为我的窗口过程是动态创建的,当没有窗口过程时系统关机还是会弹出一个对话框。最后想到一个办法,创建两个窗口过程,可是在另外一个窗口中捕获不到WM_DESTROY消息,最后分析Windows系统关机过程找到了WM_QUERYENDSESSION消息,于是在非动态创建的窗口过程中添加这个消息的处理就搞定了,系统退出时不会弹出提示框。
  知识就是在发现问题,查阅资料,解决问题,做好记录的情形下学得的。

【参考资料 感谢作者】
1、 Windows关机过程分析与快速关机

[转]Windows关机过程分析与快速关机相关推荐

  1. Windows关机过程分析与快速关机

    Windows开机和关机慢,很多时候慢得令人抓狂.特别是做嵌入式开发时(如XPE和WinCE),任谁都无法忍受开发出来的设备开关机的蜗牛速度.所以我们得为她加速.采用HORM是不错的方案,因为是直接从 ...

  2. 学用计算机 关机,计算机使用快速关机的危害是什么

    计算机使用快速关机的危害是什么 发布时间:2011-06-22 08:45:22   作者:佚名   我要评论 用ctrl+alt+del直接关机对硬盘到底有没有伤害?以前听说过"1秒快速关 ...

  3. 家用计算机如何关机,win7如何快速关机_win7快速关机的方法

    现在阶段随着系统的不断更新,用户们的需求也是越来越多了,我们在追求开机速度的同时,也在追求着快速关机的功能,不然等到别人都走了,而自己的电脑还没有完全关闭的状态,很是烦人.那么win7系统怎么实现快速 ...

  4. w ndows7快速关机,windows7怎么快速关机|win7系统实现快速关机的方法

    windows7系统 怎么快速关机?现如今大家追不仅仅追求开机速度,关机速度也是大家所追求的.要不别人都下班了,你的电脑还在等待关闭是不是很不爽呢?windows7怎么快速关机?可以通过设置注册表来实 ...

  5. 计算机关机速度,win7系统如何加快电脑关机速度|win7快速关机的方法

    相信很多用户都会在意电脑的开机的速度,而对计算机进行各种优化来提高电脑的开机速度.而有些深度技术win7旗舰版用户的电脑关机的速度比开机速度慢很多,这是怎么回事呢?在win7系统如何加快电脑关机速度呢 ...

  6. android 快速关机问题解析

    问题:打开快速关机选项,刚开机,就立即关机,出现快速关机功能失效,直接进入真关机 google default对ordered broadcast的设计原则就是one by one的处理方式,上一个o ...

  7. windows批量关机linux,Windows XP快速关机的三个小窍门--win7w.com

    即使在尝试了各种优化脚本和使用了各种优化软件之后,Windows XP仍然启动缓慢,关闭缓慢,这让人很沮丧.恐怕那些使用旧机器和笔记本电脑的人无法忍受系统启动过程如此缓慢.事实上,Windows XP ...

  8. Windows系统关机及快速关机原理

    总有人在抱怨Windows的关机是如何的缓慢,实际上Windows本身的关机速度已经很快的了.问题主要出在用户安装的程序上面,由于一些设计不好的应用程序或驱动程序的问题,造成了关机上的延迟.针对这个问 ...

  9. 联想服务器如何正确关机,Windows系统如何快速关机

    XP系统: 1.在桌面上点击鼠标右键,弹出快捷菜单,单击"新建 --> 快捷方式: 2.在弹出的"创建快捷方式"窗口,"请输入项目的位置"输入: ...

最新文章

  1. ABP源码分析三十四:ABP.Web.Mvc
  2. 一个http请求发送到后端的详细过程
  3. Linux的cp -a与cp -p
  4. 阳光学院计算机科学与技术需要英语四级,给各位想报阳光的朋友一点建议!来自学长的亲身经历!...
  5. SpringMVC异常处理流程
  6. 人人想健康!但,健康的,最主要因素,是什么?
  7. 21天Jmeter打卡Day19 mysql数据库提取参数化
  8. HttpClient实现通过url下载文件
  9. python3怎么安装mysql_Python3.7安装mysqlclient
  10. oracle禁止访问监听,关于ORACLE数据库监听自动停止解决一例
  11. Java基本数据类型与包装数据类型的使用标准
  12. 微信公众号前端40163解决办法
  13. IoT数据科学与传统数据科学的10个差异
  14. 深拷贝和浅拷贝的区别
  15. CDH5 安装需求和相关软件支持的版本信息
  16. 仿小米官网首页 动态交互(HTML+css+jq)1.通栏以及logo部分
  17. 免登录采集淘宝商品详情的方法
  18. 我的软件开发经历和收获
  19. STM32+Zigbee的使用
  20. PEST分析顺丰服务需求_顺丰快递网络优化与设计

热门文章

  1. 男人要走过几条路才称得上男子汉?
  2. 数据结构上机实践第四周项目4 - 建设双链表算法库
  3. java加载配置文件_java 读取和修改配置文件
  4. 给定奇数、横、竖、斜、总和相等python_第四章练习
  5. python正则表达式提取字符串密码_用python正则表达式提取字符串
  6. python释放变量内存_2020Python面试题:Python是如何进行内存管理的?
  7. Java String to InputStream
  8. java 改变文件权限_Java文件权限
  9. c语言中memset_C中的memset()
  10. sql选择题_SQL选择