从Windows服务调用时,SetThreadExecutionState不起作用

时间:2011-05-03 13:35:32

标签: c# windows windows-services

我希望防止系统从Windows服务进入睡眠/休眠状态。 我正在调用SetThreadExecutionState函数来执行此操作。 但似乎没有效果。 我只是想知道函数SetThreadExecutionState是否适用于Windows服务。如果不是,那将是替代方法。

以下是我正在使用的C#代码。我在Onstart服务方式上调用它。

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern uint SetThreadExecutionState(EXECUTION_STATE esFlags);
private void KeepAlive() 
{
     SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS)
}

3 个答案:

答案 0 :(得分:10)

  

在没有ES_CONTINUOUS的情况下调用SetThreadExecutionState只是重置空闲计时器;为了使显示器或系统保持工作状态,线程必须定期调用SetThreadExecutionState。

source

您需要时不时地调用此函数。这不是一场“一劳永逸”。

答案 1 :(得分:7)

SetThreadExecutionState仅对调用它的线程有效。如果在工作线程中调用它,即使使用ES_CONTINUOUS,一旦工作线程死了,该设置就不再有效,然后屏幕保护程序将再次打开。

从Timer调用此API将在前一个线程死亡之前唤醒一个工作线程,从而使其工作。

因此,如果您在主线程中调用SetThreadExecutionState,如客户端应用程序中的UI线程,则不需要计时器。

答案 2 :(得分:0)

这是我的解决方案,希望对您有所帮助。似乎可以在Windows 10上使用。

PowerUtilities.PreventPowerSave();

...然后稍后

PowerUtilities.Shutdown();

不可以被调用。

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;

namespace KeepAlive
{
    public static class PowerUtilities
    {
        [Flags]
        public enum EXECUTION_STATE : uint
        {
            ES_AWAYMODE_REQUIRED = 0x00000040,
            ES_CONTINUOUS = 0x80000000,
            ES_DISPLAY_REQUIRED = 0x00000002,
            ES_SYSTEM_REQUIRED = 0x00000001
            // Legacy flag, should not be used.
            // ES_USER_PRESENT = 0x00000004
        }
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern uint SetThreadExecutionState(EXECUTION_STATE esFlags);

        private static AutoResetEvent _event = new AutoResetEvent(false);

        public static void PreventPowerSave()
        {
            (new TaskFactory()).StartNew(() =>
                {
                    SetThreadExecutionState(
                        EXECUTION_STATE.ES_CONTINUOUS
                        | EXECUTION_STATE.ES_DISPLAY_REQUIRED
                        | EXECUTION_STATE.ES_SYSTEM_REQUIRED);
                    _event.WaitOne();

                },
                TaskCreationOptions.LongRunning);
        }

        public static void Shutdown()
        {
            _event.Set();
        }
    }
}