参考链接

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. How To Make A Swipeable Table View Cell With Actions – Without Going Nuts With Scroll Views

    How To Make A Swipeable Table View Cell With Actions – Without Going Nuts With Scroll Views  Ellen S ...

  2. 12集合(2)-----Set

    一.总体分类 Collection(包括方法add,remove,contains,clear,size) List(接口) LinkedList ArrayList Vector---Stack 2 ...

  3. JVM垃圾收集器-ParNew收集器

    今天我给大家讲讲ParNew收集器. ParNew收集器 ParNew收集器收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参 ...

  4. 今天在2cto网站看到一个有关try{}catch(){}finally{}语句中含有return的讲解,理解很透彻。

    publicclassTrycatchTest{ publicstaticvoidmain(String[]args){ System.out.println("x:"+newTr ...

  5. java中二维数组内存分配

    区分三种初始化方式: 格式一: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的元素有多少个. //例:int arr[] ...

  6. Kali Linux系统的安装、配置、使用

    这个随便写的,随便看看就好,主要给讲一下安装过程 这里因为我物理机装的本来就是kali.所以懒得重装了,直接拿虚拟机演示一下 物理机安装kali的话,推荐使用rufus使用dd模式刻盘,不会造成之后的 ...

  7. 决策树(Decision Tree

    转化自:https://trainings.analyticsvidhya.com/courses/course-v1:AnalyticsVidhya+LPDS2019+LPDS2019_T1/cou ...

  8. ios-Nav右上角按钮

    右上角的设置按钮 //****************** 右上角保存按钮 ****************** UIButton *rightBtn = [UIButton buttonWithTy ...

  9. uclibc,eglibc,glibc,Musl-libc之间的区别和联系

    转自:https://www.sohu.com/a/164202127_424963 1.Glibc glibc = GNU C Library 是GNU项(GNU Project)目,所实现的 C语 ...

  10. linux下突破10万高并发的nginx性能优化经验

    一.这里的优化主要是指对nginx的配置优化,一般来说nginx配置文件中对优化比较有作用的主要有以下几项:1)nginx进程数,建议按照cpu数目来指定,一般跟cpu核数相同或为它的倍数.worke ...