Comment détecter par programmation lorsque le système d’exploitation (Windows) se réveille ou se couche

Contexte

Mon fils aime utiliser son ordinateur portable quand il n’est pas censé le faire et j’ai pensé que ce serait pratique si je pouvais écrire une application qui m’enverrait un email chaque fois qu’il ouvrait / fermait son ordinateur portable.

(Je me contenterais même de quelque chose qui me préviendrait quand il y avait du trafic réseau sur la machine)

Question

Comment détectez-vous par programme lorsqu’un système d’exploitation se réveille ou se couche? J’ai trouvé ce lien depuis cet article . Mais cela couvre OS X. Je cherche la même chose pour Windows 7.

(Je voudrais faire cela en Java, si possible, mais je me contenterais de C # / C ++)

Le plus simple est de ne pas écrire de code du tout, même s’il s’agit d’un dépassement de stack. Cliquez sur Démarrer, tapez Planifier et choisissez Tâches planifiées. Définissez-en une (cliquez sur Créer une tâche) et définissez un déclencheur lorsque la machine est déverrouillée. Pour l’action, faites-le vous envoyer un email.

nouveau déclencheurnouvelle action

Répétez l’opération pour le démarrage et lorsqu’un utilisateur se connecte, si vous le souhaitez. Terminé.

Vous allez vouloir créer une fenêtre et rechercher le message WM_POWERBROADCAST ( http://msdn.microsoft.com/en-us/library/aa373248%28v=vs.85%29.aspx ) et vérifier le wParam pour votre action désirée. Par exemple, votre fenêtre doit recevoir un WM_POWERBROADCAST avec PBT_APMSUSPEND en tant que wParam lorsque le système est sur le point d’entrer dans un état suspendu (fermeture d’un ordinateur portable). La reprise semble avoir quelques valeurs wParam différentes: PBT_APMRESUMESUSPEND, PBT_APMRESUMECRITICAL et PBT_APMRESUMEAUTOMATIC

J’ai cherché longtemps et j’ai trouvé que c’était la meilleure façon, l’événement ‘Sleep’ ne fonctionnait jamais auparavant:

private ManagementEventWatcher managementEventWatcher; private readonly Dictionary powerValues = new Dictionary { {"4", "Entering Suspend"}, {"7", "Resume from Suspend"}, {"10", "Power Status Change"}, {"11", "OEM Event"}, {"18", "Resume Automatic"} }; public void InitPowerEvents() { var q = new WqlEventQuery(); var scope = new ManagementScope("root\\CIMV2"); q.EventClassName = "Win32_PowerManagementEvent"; managementEventWatcher = new ManagementEventWatcher(scope, q); managementEventWatcher.EventArrived += PowerEventArrive; managementEventWatcher.Start(); } private void PowerEventArrive(object sender, EventArrivedEventArgs e) { foreach (PropertyData pd in e.NewEvent.Properties) { if (pd == null || pd.Value == null) continue; var name = powerValues.ContainsKey(pd.Value.ToSsortingng()) ? powerValues[pd.Value.ToSsortingng()] : pd.Value.ToSsortingng(); Console.WriteLine("PowerEvent:"+name); } } public void Stop() { managementEventWatcher.Stop(); } 

Un moyen très simple, peut-être grossier, mais efficace peut être d’avoir un programme avec une timer qui se déclenche chaque minute. Si le minuteur se déclenche et qu’il a fallu, par exemple, 5 minutes de temps réel depuis sa dernière exécution, vous pouvez probablement supposer que l’ordinateur était en veille car il est peu probable que votre thread ne puisse pas être programmé aussi longtemps.

L’autre raison de la différence peut être un ajustement de l’horloge, comme l’heure d’été ou un changement manuel, mais ce genre de “bruit” devrait être très faible, dans votre scénario.

Vous pouvez écrire une application simple et l’enregistrer en tant que service Windows pour être lancée automatiquement au démarrage du système. Cette application pourrait alors faire ce que vous voulez quand elle démarre. Et s’il s’agit d’une application Windows appropriée, elle peut également s’enregistrer pour être informée de l’arrêt imminent du système (je ne me souviens pas des détails, mais je l’ai implémenté dans une application C ++ MFC il y a plusieurs années).

Si vous préférez Java, vous pouvez enregistrer votre application en tant que service via un wrapper de service approprié tel que Tanuki (il semble que cette option soit gratuite pour la communauté). Bien que cela puisse être excessif. Et il peut être possible de recevoir une notification à propos de l’arrêt de la JVM lorsque le système se ferme (mais je n’ai aucune expérience concrète avec cela).

http://www.pinvoke.net/default.aspx/powrprof.CallNtPowerInformation – Découvrez le lien. Il a presque tous les win32api pour toutes les fonctions Windows. Vous pouvez appeler la fonction de gestion de l’alimentation directement dans votre ordinateur portable Windows 7. Pour cela, créez un service Windows qui utilisera ces API spécifiques pour notifier l’état de la machine.