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

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

首先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. datatables ajax异步分页

    $('#sample_1').dataTable({ "sAjaxSource": "../table/data", // "bProcessing& ...

  2. Unity Shader入门精要读书笔记(三)Shader必须的数学基础

    Xyz三维坐标系如下:左手坐标系 但是摄像机观察空间则是采用右手系: 右手法则判断叉乘的结果的方向: 正交矩阵(单位互相垂直的基矢量构成正交矩阵)具有逆与转置一致性: 列矩阵运算CBAv和行矩阵的运算 ...

  3. PL/SQL 训练11--包

    --所谓包,就是把一组PL/SQL的代码元素组织在一个命名空间下.--一种可以把程序或者其他的PL/SQL元素比如游标.类型.变量的组织结构在一起的结构(包括逻辑结构和物理结构)--包提供了非常重要的 ...

  4. Cassandra学习六 一些知识点

    http://www.flyml.net/2016/09/08/cassandra-tutorial-java-api-example/ Cassandra对查询的支持很弱,只支持主键列及索引列的查询 ...

  5. Linux平台总线驱动设备模型

    platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为pl ...

  6. 第二章 MySQL的安装与配置(待续)

    ·······

  7. Windows访问Linux下的共享目录的配置方法

    user安全级别 第一步:安装samba3(如果已经安装就跳过这一步)  [root@rhce2 /]# yum groupinstall "CIFS file server" 第 ...

  8. 14-jQuery的ajax

    什么是ajax AJAX  =  异步的JavaScript 和 XML (Asynchronous Javascript and XML) 简言之,在不重载整个网页的情况下,AJAX通过后台加载数据 ...

  9. IdentityHashMap

    区别与其他的键不能重复的容器,IdentityHashMap允许key值重复,但是——key必须是两个不同的对象,即对于k1和k2,当k1==k2时,IdentityHashMap认为两个key相等, ...

  10. C++数组与指针回顾总结

    //数组名是常量指针, //a+1 是相对数组起始地址偏移了sizeof(int)字节 //&a+1 是相对于数组起始地址偏移了sizeof(a)字节 , , , }; cout <&l ...