此文已由作者王荣涛授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

首先XP系统和Vista以后的系统,这两个消息的处理方式是不同的。

XP系统

系统发送WM_QUERYENDSESSION,如果你返回FALSE,那么大多数情况下,系统的注销操作会被终止,并且接下来收到的WM_ENDSESSION的wParam参数值为FALSE。按照微软的应用程序设计指导,这个时候你需要出UI告诉用户被终止的原因。

应用程序可以暂时不响应这个消息,比如先不会返回,而是在处理这个消息的代码中弹出一个模态对话框提示用户选择。

默认情况下,你有5秒的时间来处理这个事情。超过5秒后系统出一个对话框提示该应用程序无响应。

如果任意顶层窗口在处理WM_QUERYENDSESSION的时候返回了FASLE,那么注销过程会被取消,之前收到这个消息的窗口又会收到一条WM_ENDSESSION消息,并且它的wParam将为FALSE。

只有当所有顶层窗口收到WM_QUERYENDSESSION之后都返回TRUE,它们才会被一次发送WM_ENDSESSION并且wParam消息为TRUE。一旦进入这一步,注销过程无法撤销。

处理WM_ENDSESSION的时间也是5秒,超过后系统也会弹窗提示。一旦应用程序响应了WM_ENDSESSION消息,Windows会关闭它。接下来,Windows会继续逐个向剩下的应用程序发送WM_ENDSESSION。

Vista以后的系统

相对于XP系统,Vista系统在以下一些方面进行了修改:

  • 未响应应用程序提示的UI方面的改进

  • 允许强制关闭

  • 无法悄悄撤销注销过程(WM_QUERYENDSESSION返回FALSE)

  • 提供阻止关机的API,不使用这些API而仅仅对WM_QUERYENDSESSION返回FALSE是不行的

  • 某些类型的应用程序(比如控制台程序和无可见顶层窗口的程序)将不再被允许阻止关机操作;5秒内对任何消息无响应的程序在关机过程中会被终止

  • 默认超时值修改(主要是减少)

Vista以后系统处理关机的最佳做法

  • 尽量不要阻止关机,这样给用户的体验是最好的

  • 那些必须要阻止关机的应用必须使用新的API:

  • 在系统关机前提前知道需要阻止关机的应用需要在关键代码之前调用ShutdownBlockReasonCreate(),在这块代码后调用ShutdownBlockReasonDestroy();如果在收到WM_QUERYENDSESSION时操作尚未完成,那么返回FALSE

  • 在收到WM_QUERYENDSESSION的时候才知道自己是否要阻止关机的应用程序需要在该消息的处理函数里面调用ShutdownBlockReasonCreate()并返回FALSE,然后在关键工作完成之后调用ShutdownBlockReasonDestroy()

  • 没有可见顶层窗口的应用程序需要使用超过30秒的时间来处理WM_ENDSESSION时需要在收到WM_QUERYENDSESSION的时候调用ShutdownBlockReasonCreate()然后返回TRUE。

网易云免费体验馆,0成本体验20+款云产品!

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 【RabbitMQ学习记录】-消息队列存储机制源码分析
【推荐】 Puppeteer入门初探

WM_QUERYENDSESSION与WM_ENDSESSION的更多相关文章

  1. windows C++实现注销、重启、关机 logoff reboot shutdown

    实现这一功能很简单,主要需要调用一个系统API ExitWindowsEx 功能就是,注销当前用户,关闭系统,或者重新启动系统. 它会发送一个WM_QUERYENDSESSION消息给所有的应用程序, ...

  2. windows提权操作以及系统开机关机重启代码(用到了LookupPrivilegeValue和AdjustTokenPrivileges调整进程的Token权限)

    对于UAC提权操作,一般在编译期间,如果程序有需求要提权,会在编译器里设置,vs2010比较简单,在工程属性里可以直接设置,vs2005稍微有点儿麻烦,参考这篇文章: http://www.seany ...

  3. 深入windows的关机消息截获-从XP到Win7的变化

    之前写了一个软件用于实验室的打卡提醒,其中一个重要的功能是在关机之前提醒当天晚上是否已经打卡.之前我是在WM_ENDSESSION中弹出一个模态对话框来提醒,在XP中基本工作正常,在Win7中大多数时 ...

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

    原文链接:http://blog.csdn.net/flyoxs/article/details/3710367 Windows开机和关机慢,很多时候慢得令人抓狂.特别是做嵌入式开发时(如XPE和Wi ...

  5. 深入windows的关机消息截获-从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可Block的时间从1秒调到了5秒) good

    之前写了一个软件用于实验室的打卡提醒,其中一个重要的功能是在关机之前提醒当天晚上是否已经打卡.之前我是在WM_ENDSESSION中弹出一个模态对话框来提醒,在XP中基本工作正常,在Win7中大多数时 ...

  6. 系统休眠消息PBT_APMSUSPEND

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa372721(v=vs.85).aspx https://msdn.microso ...

  7. 关于 OnCloseQuery: 顺序、不能关机等(所有的windows的广播消息都是逐窗口传递的)——如果一个窗体的OnCloseQuery事件中如果写了代码那么WM_QUERYENDSESSION消息就传不过去了msg.result会返回0,关机事件也就停止了

    系统关闭窗体的事件顺序为: OnCloseQuery ----> OnClose ----> OnDestroy 下面的代码说明问题: unit Unit3; interface uses ...

  8. 程序缩小到托盘后系统就无法关机(解决方案)——处理WM_QUERYENDSESSION消息,并把它标识为处理过了

    程序缩小到托盘后系统就无法关机(解决方案)                       老帅    程序最小化到托盘后,会出现系统无法关闭的问题,常见于WinXP系统中,这里提供一个解决方案!一.解决 ...

  9. C#调用SendMessage 用法

    函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.该函数是应用程序和应用程序之间进行消息传递的主要手段之一.    函数原型:LRESUL ...

随机推荐

  1. 1073 Scientific Notation

    题意: 给出科学计数法的形式,转化成常规的表示,要求保留所有的有效位数 思路:纯粹的字符串处理问题,注意边界条件即可.如+1.23E+02这种,转化后是123,既不需要补0,也不需要添加小数点. 代码 ...

  2. 接口规范,js处理json,php返回给ajax的数据格式

    ajax异步获取php数据. 一般php会在后台处理请求,并返回结果给前端. 必须是echo的方式,不然ajax获取不到. 返回的类型包括,字符串,数字,json. 最常用的就是json. 返回后,前 ...

  3. linux lcd设备驱动剖析三

    上一节文章中详细地剖析了probe函数,但是从始至终都没有看到打开读写文件接口的操作函数,只看到了下面这个操作结构体 [cpp] view plain? static struct fb_ops s3 ...

  4. 使用Docker模拟ansible集群环境

     /etc/ansible/hosts 192.168.99.100 ansible_ssh_port=8081 ansible_ssh_user=root 配置容器免密码SSH登录

  5. java - 只输出中文, 包含中文标点符号

    在 Java 中直接使用Unicode 转码时会按照UTF-16LE 的方式拆分,并加上 BOM. 如果采用 UTF-16 拆分,在 Java 中默认采用带有 BOM 的 UTF-16BE 拆分. S ...

  6. chrome启动参数设置

    chrome禁止本地浏览时加载本地其他文件,可以采用添加启动参数的方式来支持 添加参数为 --allow-file-access-from-files  或者 --disable-web-securi ...

  7. 2014.9.30 Double转字符

    (57.0/60.0).ToString("f2")="0.95" 等于 string.Format("{0:F2}",57.0/60)=& ...

  8. Asp.Net framework 类库 自带的缓存 HttpRuntime.Cache HttpContext.Cache

    两个Cache 在.NET运用中经常用到缓存(Cache)对象.有HttpContext.Current.Cache以及HttpRuntime.Cache,HttpRuntime.Cache是应用程序 ...

  9. 12-EasyNetQ之消息版本控制

    为了能够支持消息版本控制,你需要确保这个必要的组件已配置.最简单的实现是这样的: var bus = RabbitHutch.CreateBus("host=localhost", ...

  10. fpga中wire和reg的区别

    wire表示直通,即只要输入有变化,输出马上无条件地反映:reg表示一定要有触发,输出才会反映输入.wire表示直通,即只要输入有变化,输出马上无条件地反映:reg表示一定要有触发,输出才会反映输入. ...