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

如何阻止Windows系统服务在Modern Standby模式下运行?

解决Topshelf部署的服务在Modern Standby模式下运行导致文件损坏的问题

方案1:通过系统PowerCfg命令配置服务在Modern Standby时暂停

无需修改代码,直接让Windows在设备进入Modern Standby时暂停你的服务:

  • 第一步:获取服务的GUID
    打开管理员权限的命令提示符,执行:
    sc queryex "你的服务名称" | findstr "GUID"
    
    复制输出中的GUID(格式类似 {12345678-1234-1234-1234-1234567890AB})。
  • 第二步:配置电源计划禁用该服务在Modern Standby期间运行
    替换<服务GUID>为你复制的内容,执行以下命令:
    powercfg /setdcvalueindex SCHEME_CURRENT SUB_SERVICES <服务GUID> 0
    powercfg /setacvalueindex SCHEME_CURRENT SUB_SERVICES <服务GUID> 0
    powercfg /setactive SCHEME_CURRENT
    
    这会分别设置电池、交流电模式下,服务在Modern Standby时停止运行。

方案2:代码层面监听系统电源事件,主动暂停服务

如果系统配置方案不生效,可在Topshelf服务代码中手动监听电源状态变化,在进入Standby时暂停文件写入等操作:

使用SystemEvents.PowerModeChanged事件

using Microsoft.Win32;
using Topshelf;

public class YourService : ServiceControl
{
    private bool _inStandby = false;
    private System.Timers.Timer _workTimer;

    public bool Start(HostControl hostControl)
    {
        SystemEvents.PowerModeChanged += OnPowerModeChanged;
        // 初始化定时任务(示例为1分钟间隔)
        _workTimer = new System.Timers.Timer(60000);
        _workTimer.Elapsed += DoWork;
        _workTimer.Start();
        return true;
    }

    public bool Stop(HostControl hostControl)
    {
        SystemEvents.PowerModeChanged -= OnPowerModeChanged;
        _workTimer.Stop();
        _workTimer.Dispose();
        CleanupResources();
        return true;
    }

    private void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
    {
        if (e.Mode == PowerModes.Suspend)
        {
            _inStandby = true;
            PauseCriticalOperations();
        }
        else if (e.Mode == PowerModes.Resume)
        {
            _inStandby = false;
            ResumeCriticalOperations();
        }
    }

    private void DoWork(object sender, System.Timers.ElapsedEventArgs e)
    {
        if (_inStandby) return;
        PerformFileOperations();
    }

    private void PauseCriticalOperations()
    {
        _workTimer.Stop();
        CloseOpenResources();
    }

    private void ResumeCriticalOperations()
    {
        InitializeResources();
        _workTimer.Start();
    }

    // 业务相关方法,根据实际需求实现
    private void PerformFileOperations() { /* ... */ }
    private void CleanupResources() { /* ... */ }
    private void CloseOpenResources() { /* ... */ }
    private void InitializeResources() { /* ... */ }
}

注意事项

SystemEvents.PowerModeChanged需要STA线程环境,若事件不触发,可在Topshelf配置中指定STA线程:

HostFactory.Run(x =>
{
    x.Service<YourService>(s =>
    {
        s.ConstructUsing(name => new YourService());
        s.WhenStarted(tc => tc.Start(null));
        s.WhenStopped(tc => tc.Stop(null));
    });
    x.UseStaThread();
    x.RunAsLocalSystem();
    x.SetServiceName("YourServiceName");
});

方案3:通过WMI监听电源事件

如果SystemEvents方案不适用,可通过WMI监听底层电源管理事件:

using System.Management;
using Topshelf;

public class YourService : ServiceControl
{
    private bool _inStandby = false;
    private ManagementEventWatcher _powerWatcher;
    private System.Timers.Timer _workTimer;

    public bool Start(HostControl hostControl)
    {
        var query = new WqlEventQuery("SELECT * FROM Win32_PowerManagementEvent");
        _powerWatcher = new ManagementEventWatcher(query);
        _powerWatcher.EventArrived += OnPowerEventReceived;
        _powerWatcher.Start();

        _workTimer = new System.Timers.Timer(60000);
        _workTimer.Elapsed += DoWork;
        _workTimer.Start();
        return true;
    }

    public bool Stop(HostControl hostControl)
    {
        _powerWatcher.Stop();
        _powerWatcher.Dispose();
        _workTimer.Stop();
        _workTimer.Dispose();
        CleanupResources();
        return true;
    }

    private void OnPowerEventReceived(object sender, EventArrivedEventArgs e)
    {
        var eventType = (uint)e.NewEvent["EventType"];
        // EventType=4:进入Standby;EventType=7:从Standby恢复
        if (eventType == 4)
        {
            _inStandby = true;
            PauseCriticalOperations();
        }
        else if (eventType == 7)
        {
            _inStandby = false;
            ResumeCriticalOperations();
        }
    }

    // 其余方法同方案2的DoWork、PauseCriticalOperations等
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:35:33