You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Windows Forms应用无法检测系统睡眠/待机状态求助

解决Windows Forms中Modern Standby睡眠状态检测问题

针对你遇到的PowerModeChanged事件无法检测Modern Standby(Connected/Disconnected Standby)状态的问题,可以通过调用Windows原生Win32 API实现准确检测,该方案不依赖系统锁屏设置,兼容Windows 10及以后的现代设备(包括Surface平板)。

核心方案:注册电源设置通知并处理WM_POWERBROADCAST消息

通过PowerSettingRegisterNotificationAPI注册Modern Standby状态变化监听,并重写窗体的WndProc方法处理电源广播消息,直接捕获底层电源事件。

完整代码示例

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;

public partial class MainForm : Form
{
    // Win32消息与常量定义
    private const int WM_POWERBROADCAST = 0x0218;
    private const int PBT_POWERSETTINGCHANGE = 0x8013;
    private const int PBT_APMSUSPEND = 0x0004;          // 传统睡眠事件
    private const int PBT_APMRESUMEAUTOMATIC = 0x0007;  // 传统睡眠自动唤醒事件

    // Modern Standby状态变化的GUID标识
    private static readonly Guid GUID_CONNECTED_STANDBY_STATE_CHANGE = new Guid("98a7f580-01f7-48aa-9c0f-44352c29e5C0");

    // Win32 API声明
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr PowerSettingRegisterNotification(IntPtr hWnd, ref Guid PowerSettingGuid, uint Flags);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool PowerSettingUnregisterNotification(IntPtr Handle);

    private IntPtr _powerNotificationHandle;

    public MainForm()
    {
        InitializeComponent();
        // 注册Modern Standby状态监听
        _powerNotificationHandle = PowerSettingRegisterNotification(this.Handle, ref GUID_CONNECTED_STANDBY_STATE_CHANGE, 0);
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        // 处理电源广播消息
        if (m.Msg == WM_POWERBROADCAST)
        {
            switch (m.WParam.ToInt32())
            {
                // 处理Modern Standby状态变化
                case PBT_POWERSETTINGCHANGE:
                    POWERBROADCAST_SETTING setting = (POWERBROADCAST_SETTING)Marshal.PtrToStructure(m.LParam, typeof(POWERBROADCAST_SETTING));
                    if (setting.PowerSetting == GUID_CONNECTED_STANDBY_STATE_CHANGE)
                    {
                        int standbyState = Marshal.ReadInt32(setting.Data);
                        if (standbyState == 1)
                        {
                            Trace.WriteLine("进入Modern Standby睡眠");
                            // 执行你的特定逻辑
                        }
                        else if (standbyState == 0)
                        {
                            Trace.WriteLine("退出Modern Standby睡眠");
                        }
                    }
                    break;

                // 处理传统睡眠事件
                case PBT_APMSUSPEND:
                    Trace.WriteLine("进入传统睡眠");
                    // 执行你的特定逻辑
                    break;

                // 处理传统睡眠自动唤醒
                case PBT_APMRESUMEAUTOMATIC:
                    Trace.WriteLine("从传统睡眠自动唤醒");
                    break;
            }
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        // 注销电源监听,避免内存泄漏
        if (_powerNotificationHandle != IntPtr.Zero)
        {
            PowerSettingUnregisterNotification(_powerNotificationHandle);
        }
        base.Dispose(disposing);
    }

    // 电源设置变化的结构体定义
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct POWERBROADCAST_SETTING
    {
        public Guid PowerSetting;
        public uint DataLength;
        public byte Data;
    }
}

方案说明

  1. Modern Standby检测:通过注册GUID_CONNECTED_STANDBY_STATE_CHANGE标识,捕获设备进入/退出Modern Standby的状态(1=进入,0=退出)。
  2. 传统睡眠兼容:同时处理PBT_APMSUSPEND事件,覆盖传统Suspend睡眠场景,保证全设备兼容。
  3. 无依赖特性:直接监听底层电源事件,不依赖系统“睡眠时锁屏”的设置,稳定性更高。

内容的提问来源于stack exchange,提问作者Cameron Costa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:10:28