C# 从windows服务调用SetThreadExecutionState时,SetThreadExecutionState不工作
我希望防止系统从windows服务进入睡眠/休眠状态。 我正在调用C# 从windows服务调用SetThreadExecutionState时,SetThreadExecutionState不工作,c#,windows,windows-services,C#,Windows,Windows Services,我希望防止系统从windows服务进入睡眠/休眠状态。 我正在调用SetThreadExecutionState函数来完成此操作。 但似乎没有效果。 我只想知道函数SetThreadExecutionState是否适用于windows服务。如果没有,还有什么替代方法 下面是我正在使用的C代码。我在Onstart服务方法上调用它 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] static exter
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)
}
调用SetThreadExecutionState而不使用ES_CONTINUOUS只会重置空闲计时器;要使显示器或系统保持工作状态,线程必须定期调用SetThreadExecutionState
()
你需要时不时地调用这个函数。这不是一个“即发即忘”的问题。SetThreadExecutionState仅对调用它的线程有效。如果在工作线程中调用,即使使用ES_CONTINUOUS,一旦工作线程死机,设置将不再有效,然后屏幕保护程序将再次打开 从计时器调用此API将在前一个线程死亡之前唤醒工作线程,从而使其工作
因此,如果您在主线程中调用SetThreadExecutionState,就像在客户端应用程序中调用UI线程一样,您不需要计时器。这是我的解决方案,希望能有所帮助。似乎在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();
}
}
}
它是否返回0?如果是这样,GetLastError()返回什么?@Tony Lee它返回一个非零值。您使用的是什么Windows系统?我正在使用ES_CONTINUOUS标志calling@Prasad是的,你是。每5分钟使用该标志调用一次,它就会工作。因此,如果需要定期调用,这意味着MSDN文档是错误的?或者这种奇怪的5分钟现象只发生在服务上?这个答案中的引语意味着使用
ES_CONTINUOUS
,SetThreadExecutionState()
只需要调用一次。OP正确地做到了这一点。但是,他在OnStart
中调用它,我假设它运行在一个短期线程上,当线程结束时,状态将过期。计时器解决方案使用的线程池线程寿命很长,但这是一个糟糕的解决方案。@KayZed这是一个有趣的理论。你说的是对的;看起来即使只打一次电话也能用,对。最好是在OnStart
中启动一个新线程,并让它调用SetThreadExecutionState()
。然后线程应该保持活动状态;为此,可以使用EventWaitHandle
。在顶部的中设置它。