[C#]偵測系統Power狀態的改變以及是否進入Sleep mode

来源:互联网 发布:网络新书排行榜2016 编辑:程序博客网 时间:2024/05/07 03:30

[C#]偵測系統Power狀態的改變以及是否進入Sleep mode

https://dotblogs.com.tw/larrynung/archive/2012/05/29/72469.aspx

筆者之前在[C#]使用GetSystemPowerStatus API查看目前電源使用狀態與[C#][VB.NET]使用SystemInformation.PowerStatus查看目前電源使用狀態這兩篇文章中介紹過了如何偵測電源使用狀態,當時年紀小是用Timer定時去Pooling更新狀態,這樣作法是不好的,應該避免使用Pooling,改用系統主動通知的方式下去更新。

 

要讓系統主動通知電源狀態變更,我們可以很簡單的繫結SystemEvents.PowerModeChanged事件,透過事件處理常式回傳的參數我們可以很容易的判斷出是目前系統是發生了怎樣的電源狀態改變。電源狀態的對應值可參閱PowerModes 列舉型別。

image

 

這邊來看個簡單的範例:

using System.Windows.Forms;using Microsoft.Win32;namespace WindowsFormsApplication15{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);}void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e){textBox1.Text += e.Mode.ToString() + Environment.NewLine;}}}

 

這邊將程式運行起來,拔掉筆電的電源線再插上,系統會告知我們目前為StatusChange狀態,表示從充電狀態與電池模式之間的切換。若是將電腦切換至睡眠模式,系統會告知我們目前為Suspend狀態。再將電腦從睡眠模式中喚醒,則會收到Resume的狀態變更。

image

 

除了透過.NET BCL內建的SystemEvents外,我們也可以直接攔截系統發送的訊息。當電源狀態改變時,作業系統會發送WM_POWERBROADCAST (0x218)給所有的程式,我們可以直接攔截該訊息,找出wParam所代表的狀態改變為何就可以了。(wParam的定義可參閱WM_POWERBROADCAST message文章中的對照表)

image

 

image

 

這邊一樣附上個簡單的使用範例:

using System.Windows.Forms;namespace WindowsFormsApplication15{public partial class Form1 : Form{private const int WM_POWERBROADCAST = 0x218;private const int PBT_APMSUSPEND = 0x4;private const int PBT_APMRESUMESUSPEND = 0x7;private const int PBT_APMRESUMEAUTOMATIC = 0x12;public Form1(){InitializeComponent();}protected override void WndProc(ref Message m){if(m.Msg == WM_POWERBROADCAST){switch ((int)m.WParam){case PBT_APMSUSPEND:textBox1.Text += "PBT_APMSUSPEND" + Environment.NewLine;break;case PBT_APMRESUMEAUTOMATIC:textBox1.Text += "PBT_APMRESUMEAUTOMATIC" + Environment.NewLine;break;case PBT_APMRESUMESUSPEND:textBox1.Text += "PBT_APMRESUMESUSPEND" + Environment.NewLine;break;}}base.WndProc(ref m);}}}

 

image


为什么这个event 'SystemEvents_PowerModeChanged'在Windwos Service 里面不响应


SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
}


private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
if (e.Mode == PowerModes.Suspend)
{
................ 
}
if (e.Mode == PowerModes.Resume)
{


}
}
在WindForm下好用,可以监测到 本地机器的standby resume 状态。
但是将这段 代码 移植到 Windows Service后 根本不会响应这个事件'SystemEvents_PowerModeChanged'。
请知道的给解惑一下。如何修改 Windows Service下的代码 可以监测到 pc standby 的状态呢。


1\这个事件是无法通知到服务程序的,你可以换用
System.Management.ManagementEventWatcher 
Win32_PowerManagementEvent 事件


2\public partial class Service1 : ServiceBase
{
    public Service1()
    {
        InitializeComponent();
    }
 
    protected override void OnStart(string[] args)
    {
        this.CanHandlePowerEvent = true;
    }
    protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
    {
        switch (powerStatus)
        {
            case PowerBroadcastStatus.QuerySuspend: break;
            case PowerBroadcastStatus.PowerStatusChange: break;
        }
        return base.OnPowerEvent(powerStatus);
    }
    ...
}

原创粉丝点击