防止windows在我的程序运行时进入睡眠状态?

防止windows在我的程序运行时进入睡眠状态?,windows,winapi,sleep,c#,Windows,Winapi,Sleep,C#,当我的程序运行时,我必须阻止windows进入睡眠状态 我不仅想阻止睡眠计时器,我还想取消睡眠事件,如果我按下睡眠按钮或以任何其他方式主动告诉计算机睡眠。因此,SetThreadExecutionState是不够的 或者…我实际上不必完全阻止睡眠,只需延迟5-10秒就可以让我的程序完成任务 (我知道这是一种不好的程序行为,但只供个人使用。)如果它睡着了,把它叫醒怎么样 应使用与防止屏幕保护程序相同的技术。看 请注意,某些安全设置可以覆盖此设置(强制计算机在特定时间后锁定是一个)。我在通过usb连

当我的程序运行时,我必须阻止windows进入睡眠状态

我不仅想阻止睡眠计时器,我还想取消睡眠事件,如果我按下睡眠按钮或以任何其他方式主动告诉计算机睡眠。因此,SetThreadExecutionState是不够的

或者…我实际上不必完全阻止睡眠,只需延迟5-10秒就可以让我的程序完成任务


(我知道这是一种不好的程序行为,但只供个人使用。)

如果它睡着了,把它叫醒怎么样


应使用与防止屏幕保护程序相同的技术。看


请注意,某些安全设置可以覆盖此设置(强制计算机在特定时间后锁定是一个)。

我在通过usb连接的硬件设备上遇到了类似的问题。XP/Vista将在……中间休眠/休眠。很好,你说,当它恢复时,它可以继续。如果硬件仍然连接!!! 用户有一个习惯,只要他们愿意,就把电缆拔出来

你需要处理XP和Vista

在XP下捕获WM_POWERBROADCAST并查找PBT_APMQUERYSUSPEND wparam

   // See if bit 1 is set, this means that you can send a deny while we are busy
   if (message.LParam & 0x1)
   {
      // send the deny message
      return BROADCAST_QUERY_DENY;
   } // if
   else
   {
      return TRUE;
   } // else
在Vista下,像这样使用SetThreadExecutionState

// try this for vista, it will fail on XP
if (SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED) == NULL)
{
   // try XP variant as well just to make sure 
   SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
}  // if 
当您的应用程序完成后,将其设置回正常状态

// set state back to normal
SetThreadExecutionState(ES_CONTINUOUS);

使用PowerCreateRequest、PowerSetRequest和PowerClearRequest函数是首选方法。详细信息和示例代码(C/C#)在考虑后在

使用PowerCreateRequest、PowerSetRequest和PowerClearRequest 函数是首选方法。”

通过链接的AvailabilityRequests.docx,我在网上搜索了一个基于PowerCreateRequest的具体示例,发现[EDIT 2016-不再可用]

复制并根据我的需要进行调整(CloseHandle的PInvoke复制自):

使用System.Runtime.InteropServices;
#区域防止屏幕保护程序、显示变暗和自动休眠
POWER\u REQUEST\u CONTEXT\u PowerRequestContext;
IntPtr_PowerRequest//手柄
//可用性请求功能
[DllImport(“kernel32.dll”)]
静态外部IntPtr PowerCreateRequest(参考电源请求上下文);
[DllImport(“kernel32.dll”)]
静态外部bool PowerSetRequest(IntPtr PowerRequestHandle,PowerRequestType RequestType);
[DllImport(“kernel32.dll”)]
静态外部布尔PowerClearRequest(IntPtr PowerRequestHandle,PowerRequestType RequestType);
[DllImport(“kernel32.dll”,CharSet=CharSet.Auto,SetLastError=true,ExactSpelling=true)]
内部静态外部内部闭合手柄(IntPtr hObject);
//可用性请求枚举和常量
枚举PowerRequestType
{
PowerRequestDisplayRequired=0,
PowerRequestSystemRequired,
电力需求,
功率请求最大值
}
const int POWER\u REQUEST\u CONTEXT\u VERSION=0;
const int POWER\u REQUEST\u CONTEXT\u SIMPLE\u STRING=0x1;
const int POWER\u REQUEST\u CONTEXT\u DETAILED\u STRING=0x2;
//可用性请求结构
//注意:Windows使用
//SimpleRasInstance和详细信息的内部联合。
//为避免运行时互操作问题,此版本的
//POWER\u请求\u上下文仅支持SimpleRasInstalling。
//要使用详细信息,
//使用第一个
//类型为POWER\u REQUEST\u CONTEXT\u的参数详细说明。
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
公共结构POWER\u请求\u上下文
{
公共UInt32版本;
32面国旗;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串
简单论证;
}
[StructLayout(LayoutKind.Sequential)]
公共结构PowerRequestContextDetailedInformation
{
公共IntPtr本地化音频模块;
公共部门UInt32本地化德雷索尼;
公共UInt32计数;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串[]个字符串;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
公共结构权限\u请求\u上下文\u详细信息
{
公共UInt32版本;
32面国旗;
公共权力请求上下文详细信息详细信息;
}
#端区
/// 
///防止屏幕保护、显示器变暗和省电。此函数在Win32 API上包装PInvokes。
/// 
///如果为True,则显示恒定;如果为False,则清除设置
私有无效启用ConstantDisplayandPower(布尔启用ConstantDisplayandPower)
{
如果(启用ConstantDisplayandPower)
{
//设置诊断字符串
_Version=POWER\u REQUEST\u CONTEXT\u Version;
_Flags=POWER\u REQUEST\u CONTEXT\u SIMPLE\u STRING;
_PowerRequestContext.SimpleReasonString=“连续测量”//更改电源设置的原因;
//创建请求,获取句柄
_PowerRequest=PowerCreateRequest(参考PowerRequestContext);
//设置请求
PowerSetRequest(_PowerRequest,PowerRequestType.PowerRequestSystemRequired);
PowerSetRequest(_PowerRequest,PowerRequestType.PowerRequestDisplayRequired);
}
其他的
{
//清除请求
PowerClearRequest(_PowerRequest,PowerRequestType.PowerRequestSystemRequired);
PowerClearRequest(_PowerRequest,PowerRequestType.PowerRequestDisplayRequired);
CloseHandle(_PowerRequest);
}
}

以下是我尝试使用现代电源可用性请求API(取代
SetThreadExecutionState
)的尝试,如下所示

我使用了一个很好的p/NuGe
using System.Runtime.InteropServices;

    #region prevent screensaver, display dimming and automatically sleeping
    POWER_REQUEST_CONTEXT _PowerRequestContext;
    IntPtr _PowerRequest; //HANDLE

    // Availability Request Functions
    [DllImport("kernel32.dll")]
    static extern IntPtr PowerCreateRequest(ref POWER_REQUEST_CONTEXT Context);

    [DllImport("kernel32.dll")]
    static extern bool PowerSetRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);

    [DllImport("kernel32.dll")]
    static extern bool PowerClearRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
    internal static extern int CloseHandle(IntPtr hObject);

    // Availablity Request Enumerations and Constants
    enum PowerRequestType
    {
        PowerRequestDisplayRequired = 0,
        PowerRequestSystemRequired,
        PowerRequestAwayModeRequired,
        PowerRequestMaximum
    }

    const int POWER_REQUEST_CONTEXT_VERSION = 0;
    const int POWER_REQUEST_CONTEXT_SIMPLE_STRING = 0x1;
    const int POWER_REQUEST_CONTEXT_DETAILED_STRING = 0x2;

    // Availablity Request Structures
    // Note:  Windows defines the POWER_REQUEST_CONTEXT structure with an
    // internal union of SimpleReasonString and Detailed information.
    // To avoid runtime interop issues, this version of 
    // POWER_REQUEST_CONTEXT only supports SimpleReasonString.  
    // To use the detailed information,
    // define the PowerCreateRequest function with the first 
    // parameter of type POWER_REQUEST_CONTEXT_DETAILED.
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct POWER_REQUEST_CONTEXT
    {
        public UInt32 Version;
        public UInt32 Flags;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string
            SimpleReasonString;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct PowerRequestContextDetailedInformation
    {
        public IntPtr LocalizedReasonModule;
        public UInt32 LocalizedReasonId;
        public UInt32 ReasonStringCount;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string[] ReasonStrings;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct POWER_REQUEST_CONTEXT_DETAILED
    {
        public UInt32 Version;
        public UInt32 Flags;
        public PowerRequestContextDetailedInformation DetailedInformation;
    }
    #endregion



    /// <summary>
    /// Prevent screensaver, display dimming and power saving. This function wraps PInvokes on Win32 API. 
    /// </summary>
    /// <param name="enableConstantDisplayAndPower">True to get a constant display and power - False to clear the settings</param>
    private void EnableConstantDisplayAndPower(bool enableConstantDisplayAndPower)
    {
        if (enableConstantDisplayAndPower)
        {
            // Set up the diagnostic string
            _PowerRequestContext.Version = POWER_REQUEST_CONTEXT_VERSION;
            _PowerRequestContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
            _PowerRequestContext.SimpleReasonString = "Continuous measurement"; // your reason for changing the power settings;

            // Create the request, get a handle
            _PowerRequest = PowerCreateRequest(ref _PowerRequestContext);

            // Set the request
            PowerSetRequest(_PowerRequest, PowerRequestType.PowerRequestSystemRequired);
            PowerSetRequest(_PowerRequest, PowerRequestType.PowerRequestDisplayRequired);
        }
        else
        {
            // Clear the request
            PowerClearRequest(_PowerRequest, PowerRequestType.PowerRequestSystemRequired);
            PowerClearRequest(_PowerRequest, PowerRequestType.PowerRequestDisplayRequired);

            CloseHandle(_PowerRequest);
        }
    }
using Vanara.PInvoke;
using static Vanara.PInvoke.Kernel32;

// create request object
using var request = PowerCreateRequest(new REASON_CONTEXT("App FOO is working"));
if (request.IsInvalid)
{
    throw new InvalidOperationException(
       $"Could not create power availability request: {Win32Error.GetLastError()}");
}

// send request
if (!PowerSetRequest(request, POWER_REQUEST_TYPE.PowerRequestSystemRequired))
{
    throw new InvalidOperationException(
       $"Could not send power availability request: {Win32Error.GetLastError()}");
}
    
// do stuff that required the machine to be up
Console.WriteLine("Doing stuff...");
await Task.Delay(5000);

// clear request
if (!PowerClearRequest(request, POWER_REQUEST_TYPE.PowerRequestSystemRequired))
{
    Console.WriteLine(
      "WARNING: Could not clear power availability request: {0}",
      Win32Error.GetLastError());
}