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

时间:2021-05-17 07:14:52

I have to stop windows from going into sleep when my program is running.

我的程序运行时,我必须阻止窗口进入睡眠状态。

And I don't only want to prevent the sleep-timer, I also want to cancel the sleep-event if I press the sleep-button or in any other way actively tell the computer to sleep. Therefore SetThreadExecutionState is not enough.

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

Or...I don't actually have to prevent the sleep completely, only delay it 5-10sec to allow my program to finish a task.

或者......我实际上不必完全阻止睡眠,只需要将其延迟5-10秒以允许我的程序完成任务。

(I know that this is bad program behavior but it's only for personal use.)

(我知道这是一个糟糕的程序行为,但它仅供个人使用。)

5 个解决方案

#1


I had a problem like this with a hardware device connected via usb. XP /Vista would sleep/hibernate right in the middle of ... Great you say, when it resumes it can just continue. If the hardware is still connected!!! Users have the habit of pulling cables out whenever they feel like it.

我有一个像这样的问题,通过USB连接硬件设备。 XP / Vista会在中间睡觉/休眠......很棒的你说,当它恢复时它可以继续。如果硬件仍然连接!!!用户有习惯在他们感觉到的时候拉出电缆。

You need to handle XP and Vista

你需要处理XP和Vista

Under XP trap the WM_POWERBROADCAST and look for the PBT_APMQUERYSUSPEND wparam.

在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

Under Vista use SetThreadExecutionState like this

在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 

and when you app has finished set it back to normal

当你的应用程序完成后,将其恢复正常

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

#2


After considering vim's answer

在考虑了vim的答案之后

"Using PowerCreateRequest, PowerSetRequest, and PowerClearRequest functions is the preferred method."

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

with the linked AvailabilityRequests.docx on msdn which is exhausting to get into it (too much to read), I have searched the web for a concrete example in that is based on the PowerCreateRequest and found http://go4answers.webhost4life.com/Example/problem-monitor-wakeup-service-windows7-12092.aspx [EDIT 2016 - isn't available anymore]

使用msdn上的链接的AvailabilityRequests.docx进入它是太累了(太多无法阅读),我在网上搜索了一个基于PowerCreateRequest的c#中的具体示例,并找到了http://go4answers.webhost4life.com /Example/problem-monitor-wakeup-service-windows7-12092.aspx [编辑2016 - 不再可用]

Copied and adapted it to my needs (PInvoke of CloseHandle copied from msdn):

根据我的需要复制并调整它(从msdn复制的CloseHandle的PInvoke):

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);
        }
    }

#3


Using PowerCreateRequest, PowerSetRequest, and PowerClearRequest functions is the preferred method. Details and sample code (C/C#) are inside http://msdn.microsoft.com/en-us/library/windows/hardware/gg463205.aspx

使用PowerCreateRequest,PowerSetRequest和PowerClearRequest函数是首选方法。详细信息和示例代码(C / C#)位于http://msdn.microsoft.com/en-us/library/windows/hardware/gg463205.aspx内

#4


How about waking it back up if it goes to sleep?

如果它进入睡眠状态唤醒它怎么样?

http://www.enterprisenetworksandservers.com/monthly/art.php?1049

#5


The same technique applies as for preventing the screensaver should be used. See Programmatically prevent Windows screensaver from starting.

应用相同的技术以防止应该使用屏幕保护程序。请参阅以编程方式阻止Windows屏幕保护程序启动。

Note that some security settings can override this (forcing computers to lock after a certain time is one).

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

#1


I had a problem like this with a hardware device connected via usb. XP /Vista would sleep/hibernate right in the middle of ... Great you say, when it resumes it can just continue. If the hardware is still connected!!! Users have the habit of pulling cables out whenever they feel like it.

我有一个像这样的问题,通过USB连接硬件设备。 XP / Vista会在中间睡觉/休眠......很棒的你说,当它恢复时它可以继续。如果硬件仍然连接!!!用户有习惯在他们感觉到的时候拉出电缆。

You need to handle XP and Vista

你需要处理XP和Vista

Under XP trap the WM_POWERBROADCAST and look for the PBT_APMQUERYSUSPEND wparam.

在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

Under Vista use SetThreadExecutionState like this

在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 

and when you app has finished set it back to normal

当你的应用程序完成后,将其恢复正常

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

#2


After considering vim's answer

在考虑了vim的答案之后

"Using PowerCreateRequest, PowerSetRequest, and PowerClearRequest functions is the preferred method."

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

with the linked AvailabilityRequests.docx on msdn which is exhausting to get into it (too much to read), I have searched the web for a concrete example in that is based on the PowerCreateRequest and found http://go4answers.webhost4life.com/Example/problem-monitor-wakeup-service-windows7-12092.aspx [EDIT 2016 - isn't available anymore]

使用msdn上的链接的AvailabilityRequests.docx进入它是太累了(太多无法阅读),我在网上搜索了一个基于PowerCreateRequest的c#中的具体示例,并找到了http://go4answers.webhost4life.com /Example/problem-monitor-wakeup-service-windows7-12092.aspx [编辑2016 - 不再可用]

Copied and adapted it to my needs (PInvoke of CloseHandle copied from msdn):

根据我的需要复制并调整它(从msdn复制的CloseHandle的PInvoke):

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);
        }
    }

#3


Using PowerCreateRequest, PowerSetRequest, and PowerClearRequest functions is the preferred method. Details and sample code (C/C#) are inside http://msdn.microsoft.com/en-us/library/windows/hardware/gg463205.aspx

使用PowerCreateRequest,PowerSetRequest和PowerClearRequest函数是首选方法。详细信息和示例代码(C / C#)位于http://msdn.microsoft.com/en-us/library/windows/hardware/gg463205.aspx内

#4


How about waking it back up if it goes to sleep?

如果它进入睡眠状态唤醒它怎么样?

http://www.enterprisenetworksandservers.com/monthly/art.php?1049

#5


The same technique applies as for preventing the screensaver should be used. See Programmatically prevent Windows screensaver from starting.

应用相同的技术以防止应该使用屏幕保护程序。请参阅以编程方式阻止Windows屏幕保护程序启动。

Note that some security settings can override this (forcing computers to lock after a certain time is one).

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