参考链接

https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby

https://blogs.msdn.microsoft.com/winsdk/2014/12/02/how-to-get-notified-when-going-in-and-out-of-connected-standby-from-a-windows-service/

一 介绍

  低功耗联网状态, win8 win8.1叫connected standby, win10 对win8的connected standby 进行了扩展, 并起了一个新名字,叫modern-standby

  进入这种状态时,Windows Store Applications以及传统桌面程序会被暂停, session 0中的服务程序不会被暂停, 但是会受到一些限制(目前没有详细测试, 会受到哪些限制)

  只有硬件跟系统都支持的时候, 这台机器才支持这种状态

二 查看是否支持这种状态

  以win10为例, 使用命令powercfg /a之后, 如果有 so 低电量待机字样的说明当前机器支持这种状态

  

三 查看当前系统何时进入这种状态

还是以win10为例, 使用命令 powercfg /batteryreport, 成功执行后会在当前目录生成一份电池使用报告, 部分报告如下所示

四 程序感知系统进入跟离开这种状态

在第二个url中有详细的方法, 测试服务通知的时候发现有一些细节需要注意, 参见代码中的注释, 关键代码如下:

 #include <PowrProf.h>
#pragma comment(lib,"PowrProf.lib")
#include <WinNT.h>
 SERVICE_STATUS_HANDLE hStatus = NULL;
VOID WINAPI ServiceMain(DWORD dwNumServicesArgs, LPWSTR *lpServiceArgVectors)
{
//省略的代码 //为服务注册控制处理器
hStatus = RegisterServiceCtrlHandlerEx(L"aaa", Ctrlhandler, NULL);//服务名,指向controlhandlefunction指针
if (!hStatus)
{
return;
} //省略的代码 WriteLog("service start");
// 针对connected standby的特殊处理
HPOWERNOTIFY hNotify = NULL;
if (IsSupportConnectedStandby())
{
hNotify =RegisterPowerSettingNotification(hStatus, &GUID_MONITOR_POWER_ON, DEVICE_NOTIFY_SERVICE_HANDLE);
if (!hNotify)
WriteLog("register err!!!!");
else
WriteLog("register success");
} //省略的代码 // 服务主线程结束时, 要取消掉通知回调
if (hNotify)
UnregisterPowerSettingNotification(hNotify);
35 }
 bool IsSupportConnectedStandby()//S0 low power idle
{
bool result = false;
do
{
SYSTEM_POWER_CAPABILITIES info = { };
NTSTATUS ret = CallNtPowerInformation(SystemPowerCapabilities, NULL, , &info, sizeof(info));
if (ret != )//STATUS_SUCCESS 用户层没有这个宏, 所以直接用数值进行比较
{
printf("get info error: %x\n", ret);
break;
}
if (info.AoAc == TRUE)
result = true;
} while (false); return result;
}
 DWORD WINAPI Ctrlhandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
brun = false;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
WriteLog("SERVICE_CONTROL_STOP");
break;
case SERVICE_CONTROL_SHUTDOWN:
brun = false;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
WriteLog("SERVICE_CONTROL_SHUTDOWN");
break;
case SERVICE_CONTROL_PAUSE:
brun = false;
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
WriteLog("SERVICE_CONTROL_SHUTDOWN");
break;
case SERVICE_CONTROL_CONTINUE:
brun = false;
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_POWEREVENT:
switch (dwEventType)
{
case PBT_APMRESUMEAUTOMATIC:
{
WriteLog("PBT_APMRESUMEAUTOMATIC");
break;
}
case PBT_APMRESUMESUSPEND:
{
WriteLog("PBT_APMRESUMESUSPEND");
break;
}
case PBT_APMSUSPEND:
{
WriteLog("PBT_APMSUSPEND");
break;
}
case PBT_APMPOWERSTATUSCHANGE: // 交流变电池 或者电池变交流
{
WriteLog("PBT_APMPOWERSTATUSCHANGE");
break;
}
case PBT_POWERSETTINGCHANGE:
{
WriteLog("PBT_POWERSETTINGCHANGE");
PPOWERBROADCAST_SETTING setting = (PPOWERBROADCAST_SETTING)lpEventData;
if(setting->PowerSetting == GUID_MONITOR_POWER_ON)
{
std::string str("GUID_MONITOR_POWER_ON "); if(setting->DataLength == )
{
// MONITOR_POWER_OFF(data ==0)-->进入 connected standby状态
// MONITOR_POWER_ON(data ==1)-->进入 active状态
// MONITOR_POWER_OFF对应于设置里面睡眠进入的时间, 而不是根据字面意思对应设置里面的屏幕关闭时间, 这个要注意!!!
// 刚刚注册GUID_MONITOR_POWER_ON成功后会立刻收到一次该事件, 报告data ==1
DWORD data = *(DWORD*)(setting->Data);
str += std::to_string(data);
}
else
{
str += "len: ";
str += std::to_string(setting->DataLength);
}
WriteLog(str);
}
break;
} default:
break;
}
break;
case SERVICE_CONTROL_SESSIONCHANGE:
{
std::string str("SERVICE_CONTROL_SESSIONCHANGE: ");
str+= std::to_string(dwEventType); PWTSSESSION_NOTIFICATION Notification = (PWTSSESSION_NOTIFICATION)lpEventData;
str += " ";
str += std::to_string(Notification->dwSessionId);
WriteLog(str.c_str()); switch (dwEventType)
{
case WTS_CONSOLE_CONNECT:
break;
case WTS_CONSOLE_DISCONNECT:
break;
case WTS_SESSION_LOGON:
break;
case WTS_SESSION_LOGOFF:
break;
case WTS_SESSION_LOCK:
break;
case WTS_SESSION_UNLOCK:
break;
default:
;
}
}
break;
default:
break;
}
//向SCM报告“SERVICE_STOPPED”状态
SetServiceStatus(hStatus, &ServiceStatus);
return NO_ERROR;
}

connected standby的更多相关文章

  1. Mode Standby

    Modern Standby 1.Connected Standby和 Connected Standby是Windows 8全新的电源管理系统,即当系统进入休眠状态时,应用程式虽处於暂停(suspe ...

  2. Windows操作系统

    Microsoft Windows,是美国微软公司研发的一套操作系统,它问世于1985年,起初仅仅是Microsoft-DOS模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家 ...

  3. Win8 WinRT将替换Win32 API程序员何去何从?

    win8 新引入了称为WinRT的核心API.支持使用C/C++..NET或JavaScript来开发Metro风格的应用.这些应用自动获得硬件加速和高级电源管理的功能.现有的Silverlight和 ...

  4. 盘点Windows 8.1中隐藏着的25个秘密功能

    Windows 8.1正式版问世,带来了众多大家早已耳熟能详的“开始按钮”.“分屏显示”等功能.事实上,Windows 8.1贴心的设计细节有很多,多数细节隐藏于系统中某个不起眼的角落,科技网站PC ...

  5. Windows8 各种版本区别对比详解

    微软的 Windows8 操作系统提供了4个不同的版本,分别是 Windows RT.Windows 8 标准版.Windows 8 Pro 专业版 以及 Windows 8 Enterprise 企 ...

  6. Windows 8.1 Preview的新功能和新API

    http://msdn.microsoft.com/en-us/library/windows/apps/bg182410 App打包 新的App程序包将使App的提交更简单.资源包可以让你提供附加的 ...

  7. Windows Server 2016-Hyper-V 2016新增功能

    本文解释了Windows Server 2016和Microsoft Hyper-V Server 2016上Hyper-V的新增功能和变更功能. 与Connected Standby兼容(新) 在使 ...

  8. Windows 操作系统

    Microsoft Windows,是美国微软公司研发的一套操作系统,它问世于1985年,起初仅仅是Microsoft-DOS模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家 ...

  9. 9. Oracle DataGuard的介绍

    一. Oracle DataGuard简介 Oracle DataGuard:简称DG.是由一个Primary Database(主库)和一个或者多个Standby Database(备库)组成.对O ...

随机推荐

  1. 浅谈ES6新增数据类型:Symbol

    面试中喜闻乐见的问题就是问我们的ES6新增了哪些个新特性 这篇文章一起学习一下新增的数据类型:Symbol JS的原始数据类型:6种Boolean,String,Undefined,NULL,Numb ...

  2. 浅析 java ArrayList

    浅析 java ArrayList 简介 容器是java提供的一些列的数据结构,也可以叫语法糖.容器就是用来装在其他类型数据的数据结构. ArrayList是数组列表所以他继承了数组的优缺点.同时他也 ...

  3. hive -e执行出现「cannot recognize input near '<EOF>' in select clause」问题

    问题现象 写了一个简单的shell脚本调用hive执行组装的sql,在执行时总是报cannot recognize input near '<EOF>' in select clause错 ...

  4. sqlalchemy执行sql语句

    #删除user表中的所有数据,表中的自增字段又从默认值开始 session.execute("truncate table user")

  5. cocos2dx-lua中handler解析

    先看一段代码: local c=c or {} function c:onTouch() print "test in onTouch" end function handler( ...

  6. s21day19 python笔记

    s21day19 python笔记 一.面向对象的基本知识 1.1 基本格式 # 定义类 class 类名: def 方法名(self,name): print(name) return 123 de ...

  7. log4net使用中loginfo.IsInfoEnabled=false问题解决方法

    引用了其他项目中的日志组件,调试时发现IsInfoEnabled属性一直为false 找了很多的解决办法,都不行 program.cs里面也不用添加 log4net.Config.XmlConfigu ...

  8. 选择器与I/O多路复用

    Selector选择器是NIO技术中的核心组件,可以将通道注册进选择器中,其主要作用是使用1个线程来对多个通道中的已就绪通道进行选择,然后就可以对选择的通道进行数据处理,属于一对多的关系,也就是使用1 ...

  9. localStore的storage事件

    两个浏览器窗口间通信   两个浏览器窗口间通信 补充一下,这里的通讯指遵守同源策略情况下. 为了吸引读者的兴趣,先把demo放到前面:下面有几个我自己写的演示多页面通讯的demo, 为了正常运行,请用 ...

  10. nginx日志分割

    mark 参考文章: https://blog.csdn.net/molaifeng/article/details/82667158