Предотвращение перехода окон в спящий режим при запуске моей программы? - PullRequest
34 голосов
/ 10 марта 2009

Мне нужно, чтобы окна не переходили в спящий режим во время работы моей программы.

И я не только хочу отключить таймер сна, я также хочу отменить событие сна, если я нажму кнопку сна или каким-либо другим способом активно скажу компьютеру, чтобы он спал. Поэтому SetThreadExecutionState недостаточно.

Или ... На самом деле мне не нужно полностью запрещать сон, просто отложите его на 5-10 секунд, чтобы позволить моей программе завершить задачу.

(я знаю, что это плохое поведение программы, но это только для личного использования.)

Ответы [ 5 ]

21 голосов
/ 10 марта 2009

У меня была такая проблема с аппаратным устройством, подключенным через USB. XP / Vista будет находиться в спящем / спящем режиме прямо в середине ... Отлично, вы говорите, когда он возобновляется, он может просто продолжаться. Если оборудование все еще подключено !!! Пользователи имеют привычку вытаскивать кабели, когда им так хочется.

Вам нужно работать с XP и Vista

Под XP перехватывает WM_POWERBROADCAST и ищет wparam PBT_APMQUERYSUSPEND.

   // 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);
19 голосов
/ 08 января 2014

После рассмотрения ответа vim

"Использование PowerCreateRequest, PowerSetRequest и PowerClearRequest функции является предпочтительным методом. "

с привязкой AvailabilityRequests.docx на msdn , который утомляет, чтобы попасть в него (слишком много для чтения), я искал в Интернете конкретный пример в , который основан на PowerCreateRequest и найден http://go4answers.webhost4life.com/Example/problem-monitor-wakeup-service-windows7-12092.aspx [РЕДАКТИРОВАТЬ 2016 - больше не доступен]

Скопировал и адаптировал его к моим потребностям (PInvoke of CloseHandle скопирован с msdn ):

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);
        }
    }
6 голосов
/ 18 апреля 2013

Использование функций PowerCreateRequest, PowerSetRequest и PowerClearRequest является предпочтительным методом. Подробности и пример кода (C / C #) находятся внутри http://msdn.microsoft.com/en-us/library/windows/hardware/gg463205.aspx

0 голосов
/ 10 марта 2009

Применяется та же техника, что и для предотвращения заставки. См. Программно предотвратить запуск заставки Windows .

Обратите внимание, что некоторые параметры безопасности могут переопределить это (принудительная блокировка компьютеров после определенного времени).

0 голосов
/ 10 марта 2009

Как насчет того, чтобы снова разбудить его, если он идет спать?

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

...