日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

c# 监听 Modern Standby 下的电源状态(Sleep mode)

發布時間:2023/12/20 C# 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c# 监听 Modern Standby 下的电源状态(Sleep mode) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Windows 8.1之后,winows系統引入一種叫Connected Standby power model。其目的在于模擬手機關屏后能夠省電,而開屏時又能快速響應的特點。在windows 10中,又擴展了這種模式。有了conneted standby mode 和DisConnected standby mode.(https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby)

最主要的意思是睡眠的時候仍然聯網,比如:收郵件。進入CS 之后后臺仍然能夠收郵件,conneted standby 最主要的意思是睡眠的時候仍然聯網,比如:收郵件。進入CS 之后后臺仍然能夠收郵件,喚醒之后馬上就能看到新郵件。還有一種是 Disconnected Standby,就是睡眠的時候斷網(Modern Standby簡介 - WWW.LAB-Z.COM (lab-z.com))。

聽起來這都是windows的改善行為。但是對于傳統的windows api,或者從windows 7遷移過來的app,這是有影響。很多程序在用戶進入sleep的時候,會監聽 SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged 做一些保存的動作。但是在windows 10中,如果電源模式為Modern standby 的話,那么這個事件失效的。

?

原來windows OS 引入 Desktop Activity Moderator? PowerRegisterSuspendResumeNotification 這個API來處理這個問題。

https://docs.microsoft.com/en-us/windows/win32/w8cookbook/desktop-activity-moderator? 來處理這個問題。

以下演示在代碼展示c#程序中如何使用這種方法。

using System; using System.Runtime.InteropServices; namespace PowerStatusChanged {class Program{static void Main(string[] args){IntPtr registrationHandle = new IntPtr();DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient = new DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS();recipient.Callback = new DeviceNotifyCallbackRoutine(DeviceNotifyCallback);recipient.Context = IntPtr.Zero;IntPtr pRecipient = Marshal.AllocHGlobal(Marshal.SizeOf(recipient));Marshal.StructureToPtr(recipient, pRecipient, false);uint result = PowerRegisterSuspendResumeNotification(DEVICE_NOTIFY_CALLBACK, ref recipient, ref registrationHandle);if (result != 0)Console.WriteLine("Error registering for power notifications: " + Marshal.GetLastWin32Error());elseConsole.WriteLine("Successfully Registered for power notifications!");Console.ReadKey();}private static int DeviceNotifyCallback(IntPtr context, int type, IntPtr setting){Console.WriteLine("Device notify callback called: ");switch (type){case PBT_APMPOWERSTATUSCHANGE:Console.WriteLine("\tPower status has changed.");break;case PBT_APMRESUMEAUTOMATIC:Console.WriteLine("\tOperation is resuming automatically from a low-power state.This message is sent every time the system resumes.");break;case PBT_APMRESUMESUSPEND:Console.WriteLine("\tOperation is resuming from a low-power state.This message is sent after PBT_APMRESUMEAUTOMATIC if the resume is triggered by user input, such as pressing a key.");break;case PBT_APMSUSPEND:Console.WriteLine("\tSystem is suspending operation.");break;case PBT_POWERSETTINGCHANGE:Console.WriteLine("\tA power setting change event has been received. ");break;default:Console.WriteLine("unknown");break;}// do something herereturn 0;}private const int WM_POWERBROADCAST = 536; // (0x218)private const int PBT_APMPOWERSTATUSCHANGE = 10; // (0xA) - Power status has changed.private const int PBT_APMRESUMEAUTOMATIC = 18; // (0x12) - Operation is resuming automatically from a low-power state.This message is sent every time the system resumes.private const int PBT_APMRESUMESUSPEND = 7; // (0x7) - Operation is resuming from a low-power state.This message is sent after PBT_APMRESUMEAUTOMATIC if the resume is triggered by user input, such as pressing a key.private const int PBT_APMSUSPEND = 4; // (0x4) - System is suspending operation.private const int PBT_POWERSETTINGCHANGE = 32787; // (0x8013) - A power setting change event has been received.private const int DEVICE_NOTIFY_CALLBACK = 2;/// <summary>/// OS callback delegate definition/// </summary>/// <param name="context">The context for the callback</param>/// <param name="type">The type of the callback...for power notifcation it's a PBT_ message</param>/// <param name="setting">A structure related to the notification, depends on type parameter</param>/// <returns></returns>public delegate int DeviceNotifyCallbackRoutine(IntPtr context, int type, IntPtr setting);/// <summary>/// A callback definition/// </summary>[StructLayout(LayoutKind.Sequential)]public struct DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS{public DeviceNotifyCallbackRoutine Callback;public IntPtr Context;}[DllImport("Powrprof.dll", SetLastError = true)]static extern uint PowerRegisterSuspendResumeNotification(uint flags, ref DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS receipient, ref IntPtr registrationHandle);} }

源碼下載

https://download.csdn.net/download/mochounv/15728042

運行以上程序,點擊開始-->休眠,喚醒回來后,可以看到以下結果:

?

以上代碼方案參考

ModernStandby下獲取系統電源消息_wayyt_新浪博客 (sina.com.cn)

pinvoke.net: PowerRegisterSuspendResumeNotification (powrprof)

值得分享的是:

1)以上程序在傳統的S3, S4電源模式下,也能響應系統Sleep事件。當將這代碼移到GUI程序(如wpf winform等程序時,需要將 registrationHandle,recipient 和 pRecipient 設置為 static 的成員,否則因為生命周期的問題,回調會找不到部分數據,而導致程序在OS resume 回來時掛掉)

2)這里想強調的時,雖然這里監聽的是PBT_APMSUSPEND事件,但是千萬不要在桌面程序的窗口事件WndindowProc來監聽,盡管有這樣一套接口官網有這樣一套接口

?https://docs.microsoft.com/en-us/windows/win32/power/wm-powerbroadcast#:~:text=WM_POWERBROADCAST%20messages%20do%20not%20distinguish%20between%20different%20low-power,state%20transitions%20in%20the%20Windows%20System%20event%20log.

但是我測下來,只能收到插播電源的事件。從以上鏈接看不出來為什么不行。

?

?

?

一點擴展:

如何查看系統的電源模式呢,在cmd窗口中,使用powercfg -a 可以查看。

比如以下模式,就是一個傳統的電源模式, S3 (Sleep), S4(Hibernate).

而以下模式

S0 Low Power Idle表示 Modern standby 模式。

?

?

至于什么是Modern standby 模式以及它跟傳統的 S3(Sleep), S4(Hibernate)有的區別可以查看

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

?

?

總結

以上是生活随笔為你收集整理的c# 监听 Modern Standby 下的电源状态(Sleep mode)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。