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

如何在Windows Service中检测Modern Standby/S0状态?

检测Modern Standby (S0) 状态的有效方案

方法1:通过PowerGetEffectiveOverlayScheme与PowerDeterminePlatformRoleEx API判断

Modern Standby分为Connected Standby和Disconnected Standby两种模式,可通过这两个API组合检测设备是否处于该状态:

C#/.NET 实现代码

using System;
using System.Runtime.InteropServices;

public static class ModernStandbyDetector
{
    private const int POWER_PLATFORM_ROLE_MOBILE = 2;
    private const int POWER_PLATFORM_ROLE_TABLET = 8;

    // Connected/Disconnected Standby的GUID
    private static readonly Guid GUID_CONNECTED_STANDBY = Guid.Parse("96996BC0-922D-4BB3-AE1E-1E468F6C4500");
    private static readonly Guid GUID_DISCONNECTED_STANDBY = Guid.Parse("96996BC1-922D-4BB3-AE1E-1E468F6C4500");

    [DllImport("powrprof.dll", SetLastError = true)]
    private static extern uint PowerDeterminePlatformRoleEx(out int pRole);

    [DllImport("powrprof.dll", SetLastError = true)]
    private static extern uint PowerGetEffectiveOverlayScheme(out IntPtr pOverlaySchemeGuid);

    public static bool IsInModernStandby()
    {
        // 先判断设备类型:仅移动/平板设备支持Modern Standby
        if (PowerDeterminePlatformRoleEx(out int deviceRole) != 0)
            return false;

        bool isEligibleDevice = deviceRole == POWER_PLATFORM_ROLE_MOBILE || deviceRole == POWER_PLATFORM_ROLE_TABLET;
        if (!isEligibleDevice)
            return false;

        // 获取当前生效的电源覆盖方案
        if (PowerGetEffectiveOverlayScheme(out IntPtr overlayGuidPtr) != 0)
            return false;

        try
        {
            Guid overlayGuid = Marshal.PtrToStructure<Guid>(overlayGuidPtr);
            return overlayGuid == GUID_CONNECTED_STANDBY || overlayGuid == GUID_DISCONNECTED_STANDBY;
        }
        finally
        {
            Marshal.FreeHGlobal(overlayGuidPtr);
        }
    }
}

应用逻辑

在服务的核心循环或网络操作前调用IsInModernStandby():

  • 返回true时:禁用看门狗、暂停所有网络请求、跳过登录重试逻辑
  • 返回false时:恢复正常服务行为

方法2:监听PowerSettingNotification 电源状态变更通知

通过注册特定电源设置的通知,实时捕获Modern Standby的进入/退出事件:

C#/.NET 实现代码

using System;
using System.ServiceProcess;
using System.Runtime.InteropServices;

public class NetworkService : ServiceBase
{
    private IntPtr _powerNotifyHandle;
    private const int WM_POWERBROADCAST = 0x0218;
    private const int PBT_POWERSETTINGCHANGE = 0x8013;
    private static readonly Guid GUID_SYSTEM_AWAYMODE = Guid.Parse("98a7f580-01f7-48aa-9c0f-44352c29e5C0");

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr RegisterPowerSettingNotification(IntPtr hWnd, ref Guid PowerSettingGuid, uint Flags);

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

    protected override void OnStart(string[] args)
    {
        // 注册Modern Standby状态变更通知
        _powerNotifyHandle = RegisterPowerSettingNotification(this.ServiceHandle, ref GUID_SYSTEM_AWAYMODE, 0);
        base.OnStart(args);
    }

    protected override void OnStop()
    {
        if (_powerNotifyHandle != IntPtr.Zero)
        {
            UnregisterPowerSettingNotification(_powerNotifyHandle);
        }
        base.OnStop();
    }

    protected override void OnCustomCommand(int command)
    {
        if (command == WM_POWERBROADCAST)
        {
            bool inStandby = ModernStandbyDetector.IsInModernStandby();
            if (inStandby)
            {
                DisableWatchdog();
                PauseNetworkTasks();
            }
            else
            {
                EnableWatchdog();
                ResumeNetworkTasks();
                // 可选:退出Standby后重新执行登录逻辑
            }
        }
        base.OnCustomCommand(command);
    }

    // 以下为自定义业务逻辑示例
    private void DisableWatchdog() => /* 禁用看门狗定时器或终止检测逻辑 */;
    private void PauseNetworkTasks() => /* 暂停网络请求、关闭Socket连接、停止定时任务 */;
    private void EnableWatchdog() => /* 恢复看门狗逻辑 */;
    private void ResumeNetworkTasks() => /* 重启网络任务、重建连接 */;
}

关键说明

  • GUID_SYSTEM_AWAYMODE对应Modern Standby的状态变更事件,设备进入/退出S0时会触发该广播
  • 结合方法1的主动检测,可避免通知遗漏,确保状态判断准确

注意事项

  • 服务需运行在Local System账户下,否则可能无权限调用电源相关API
  • 蜂窝网络设备在S0状态下可能保留有限网络连接,但稳定性不可靠,建议统一暂停网络操作
  • 需在支持Modern Standby的设备上测试,传统桌面设备不具备该状态

内容的提问来源于stack exchange,提问作者Linus Dillon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:02:47