2009-03-10 6 views
33

Je dois empêcher les fenêtres de s'endormir lorsque mon programme est en cours d'exécution. Et je ne veux pas seulement empêcher le sleep-timer, je veux aussi annuler l'événement de sommeil si j'appuie sur le bouton de veille ou de toute autre manière dire activement à l'ordinateur de dormir. Par conséquent, SetThreadExecutionState n'est pas suffisant.Empêche les fenêtres de se mettre en veille lorsque mon programme est en cours d'exécution?

Ou ... Je n'ai pas besoin d'empêcher le sommeil complètement, seulement le retarder 5-10sec pour permettre à mon programme de finir une tâche.

(Je sais que cela est mauvais comportement du programme, mais il est seulement pour un usage personnel.)

Répondre

21

J'ai eu un problème comme celui-ci avec un périphérique matériel connecté via USB. XP/Vista dormirait/hibernerait juste au milieu de ... C'est génial de dire que quand il reprend, il peut simplement continuer. Si le matériel est encore connecté !!! Les utilisateurs ont l'habitude de tirer les câbles quand ils en ont envie.

Vous devez gérer XP et Vista

Sous piège XP, le WM_POWERBROADCAST et recherchez le wparam de 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 

Sous Vista utilisent SetThreadExecutionState comme celui-ci

// 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 

et quand vous a app terminé le remettre à la normale

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

Hmm, je me suis trompé, SetThreadExecutionState a effectivement fonctionné, il a juste fallu aussi paramétrer le ES_AWAYMODE_REQUIRED Ce qui est étrange, c'est que mon moniteur devient noir mais le système ne se met jamais complètement en veille –

+1

L'idée est que l'ordinateur dort normalement, donc il a l'air de dormir, puis lorsque la tâche d'arrière-plan est terminée (par exemple enregistrer une émission de télévision), l'application éteint le système requis et –

+0

> La chose étrange est que mon moniteur devient noir mais le système ne se met jamais complètement en veille --- c'est peut-être juste l'économiseur d'écran vide par défaut? – himself

0

Qu'en est-il se réveiller si elle remonter va dormir?

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

+0

pas possible, je dois désactiver une connexion Wi-Fi périphérique _avant_ l'ordinateur va dormir.Sinon, l'appareil deviendra inutilisable lorsque j'aurai réveillé l'ordinateur. Intel est lent avec win7 drivers :( –

0

La même technique est appliquée que pour la prévention de l'économiseur d'écran doit être utilisé. Voir Programmatically prevent Windows screensaver from starting.

Notez que certains paramètres de sécurité peuvent remplacer ce paramètre (en forçant les ordinateurs à se verrouiller après un certain temps).

17

Après avoir examiné la réponse de vim

"Utilisation PowerCreateRequest, PowerSetRequest et PowerClearRequest fonctions est la méthode préférée."

avec le AvailabilityRequests.docx lié sur msdn qui est épuisant pour y entrer (trop à lire), j'ai cherché sur le web pour un exemple concret dans qui est basé sur la PowerCreateRequest et trouvé http://go4answers.webhost4life.com/Example/problem-monitor-wakeup-service-windows7-12092.aspx [EDIT 2016 - n'est plus disponible]

et adapté copié à mes besoins (PInvoke de CloseHandle copié à partir 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

Cette méthode est intéressante car les raisons que vous donnez pour que le système ne dorme pas etc. s'afficheront lorsque vous lancerez powercfg/requests. Cela aidera les utilisateurs à diagnostiquer les problèmes de sommeil – Schneider

Questions connexes