Les applications qui cassent à la reprise de veille — événements d'alimentation et applications métier qui survivent à la reprise
· Mis à jour le: · Go Komura · Windows, Gestion de l'alimentation, Développement Windows, Applications métier, Contrôle de périphériques, Investigation de bugs, Win32 API
Historique des révisions (première version, publiée le 22 Aug 2026)
- Première publication
Citer cet article(DOI (archive enregistrée): 10.5281/zenodo.22176735)
Les DOI ci-dessous renvoient à des versions déjà archivées et peuvent différer du texte actuel. Pour citer le texte actuel, utilisez l’URL de cette page.
Go Komura (2026). Les applications qui cassent à la reprise de veille — événements d'alimentation et applications métier qui survivent à la reprise. KomuraSoft LLC. https://comcomponent.com/fr/blog/windows-sleep-resume-power-events/
- DOI (archive enregistrée)
- 10.5281/zenodo.22176735
- DOI (dernière version enregistrée)
- 10.5281/zenodo.22176736
Vous fermez le portable, vous l’ouvrez le lendemain matin, et l’application métier est pleine d’erreurs. Une application de surveillance d’équipement perd des données uniquement après la pause déjeuner. Un outil en arrière-plan qui exporte vers Excel s’arrête parfois sur une erreur de connexion. Face à des symptômes de ce genre, la première chose à suspecter est le comportement à travers la veille.
Certaines applications métier traditionnelles ont été écrites en supposant que « le PC reste allumé ». Maintenant que les portables sont au centre du travail quotidien, on ne peut plus ignorer un environnement qui se met en veille en quelques minutes s’il est laissé inactif. De plus, les machines compatibles Modern Standby se mettent en veille par un mécanisme différent du modèle traditionnel.
Cet article s’adresse aux développeurs qui créent des applications métier et des logiciels de contrôle d’équipement sous Windows. Il présente, à partir des sources primaires, les notifications que l’OS délivre, ce qui casse après la reprise, comment concevoir le rétablissement, et comment investiguer sur le terrain, dans cet ordre.
1. La conclusion d’abord
Le centre de la conception n’est pas « tout ranger avant la veille », mais « pouvoir se rétablir après la reprise, peu importe le moment où la machine s’arrête ». Trois points sont à retenir.
- La notification préalable n’est pas une garantie que vous pourrez terminer. La veille ne peut pas être refusée, et le délai de grâce de
PBT_APMSUSPENDest d’environ 2 secondes. Lors d’une suspension d’urgence, la notification n’arrive pas du tout. Même sous Modern Standby, vous ne pouvez pas supposer qu’une application de bureau continue de s’exécuter pendant la veille.123 - Concevez en supposant que les connexions, les handles et la continuité du temps ne sont pas conservés à travers la reprise. Faites converger non seulement la notification de reprise, mais aussi les erreurs de communication, vers le même traitement de reconnexion, et revoyez aussi les planifications de minuteurs et les différences de temps écoulé.
- La suppression de la veille et la préparation à la reprise sont des mesures distinctes. Utilisez
SetThreadExecutionStateou une demande d’alimentation pour les intervalles de travail qui en ont besoin, et levez-la toujours ensuite. Elle ne peut toutefois pas empêcher une action de veille explicite de l’utilisateur, donc ce n’est pas une raison d’omettre la logique de rétablissement.45
Vous pouvez aussi commencer par le chapitre qui correspond à votre objectif.
| Ce que vous voulez savoir | Chapitre à lire |
|---|---|
| Quelles notifications arrivent avant et après la veille | Chapitre 2 : le flux des événements d’alimentation |
| Ce qui change sous Modern Standby | Chapitre 3 : comportement du système et pause de l’application |
| Pourquoi les erreurs de connexion et le décalage d’heure se produisent | Chapitre 4 : symptômes classiques |
| Comment implémenter la reconnexion, la gestion du temps et la suppression de la veille | Chapitre 5 : conception qui survit à la reprise |
| Comment isoler une demande de support | Chapitre 6 : powercfg et le journal d’événements |
2. Ce qui se passe autour de la veille — le flux des événements d’alimentation
L’OS notifie les applications des changements d’état d’alimentation par le message WM_POWERBROADCAST.2 D’abord, les trois événements utilisés autour de la transition de suspension. En quoi le ralenti basse consommation de Modern Standby diffère est complété au chapitre 3.
| Événement | Signification |
|---|---|
| PBT_APMSUSPEND | Sur le point d’entrer en veille (dernière chance de se préparer) |
| PBT_APMRESUMEAUTOMATIC | Reprise (arrive toujours à la reprise) |
| PBT_APMRESUMESUSPEND | Reprise causée par une action de l’utilisateur (celui-ci est conditionnel) |
sequenceDiagram
accTitle: Flux de notification pour la veille et la reprise
accDescr: PBT_APMSUSPEND arrive juste avant la veille avec environ 2 secondes de grâce ; à la reprise, PBT_APMRESUMEAUTOMATIC arrive toujours, et PBT_APMRESUMESUSPEND ne suit que pour une reprise initiée par l'utilisateur
participant OS as OS
participant A as Application
OS->>A: PBT_APMSUSPEND (environ 2 secondes de grâce)
A->>A: Enregistrer l'état et fermer les connexions
Note over OS: Veille (le code ne s'exécute pas)
OS->>A: PBT_APMRESUMEAUTOMATIC (arrive à la reprise)
A->>A: Reconnecter et reconstruire l'état
OS->>A: PBT_APMRESUMESUSPEND (reprise initiée par l'utilisateur seulement)
A->>A: Mises à jour d'écran et autre travail visible par l'utilisateur
Figure 1 : les notifications se réduisent à « un mot juste avant, et un ou deux mots après la reprise ». C’est le traitement côté reprise qui porte le rétablissement.
La notification avant la veille est l’occasion de « se préparer si le temps le permet »
PBT_APMSUSPEND est la notification délivrée juste avant d’entrer en veille. Elle permet de fermer des fichiers et d’enregistrer l’état, mais elle s’accompagne des deux contraintes suivantes.
| Contrainte | Effet sur la conception |
|---|---|
| Le délai de grâce est d’environ 2 secondes par application | Au-delà, le système poursuit sans attendre l’application1 |
| Une suspension d’urgence ne donne aucune notification préalable | Lorsque le niveau de batterie est critique, par exemple, la machine s’arrête sans aucune préparation2 |
Par conséquent, une conception qui « termine toujours l’enregistrement après avoir reçu cette notification » ne tient pas. Utilisez la notification préalable pour préparer ce qui peut encore l’être à temps, et placez le fond du rétablissement du côté de la reprise.
flowchart TB
accTitle: Différence entre veille ordinaire et suspension d'urgence
accDescr: La veille ordinaire délivre PBT_APMSUSPEND juste avant avec environ 2 secondes pour se préparer, mais une suspension d'urgence causée par une batterie critique ou analogue s'arrête sans notification préalable, donc une conception qui dépend de la notification préalable ne tient pas
n2["Veille ordinaire"] --> pre["PBT_APMSUSPEND (environ 2 secondes de grâce)"]
pre --> s1["Se préparer, puis s'arrêter"]
e2["Suspension d'urgence (batterie presque épuisée)"] --> s2["S'arrêter sans notification préalable"]
s2 -.-> l2["Une conception qui suppose que la notification arrivera ne tient pas"]
Figure 2 : une suspension d’urgence arrive sans avertissement. La préparation est donc « un bonus si elle arrive à temps », et le fond va du côté de la reprise.
Les notifications de reprise séparent le rétablissement mécanique et le travail visible par l’utilisateur
À la reprise depuis la suspension, PBT_APMRESUMEAUTOMATIC arrive d’abord. Si la machine a repris à cause du bouton d’alimentation ou d’une touche, ou si la présence de l’utilisateur a été détectée après la reprise, PBT_APMRESUMESUSPEND suit.67
En revanche, lors d’une reprise sans surveillance telle qu’un réveil distant par le réseau ou une reprise pour la maintenance, seul PBT_APMRESUMEAUTOMATIC arrive. Placez le rétablissement requis tel que reconstruire les connexions sur la première, et les actions visibles par l’utilisateur telles que les mises à jour d’écran ou une invite de reconnexion sur la seconde.6
flowchart TB
accTitle: Répartition du travail sur les deux étapes de reprise
accDescr: Placez le rétablissement mécanique tel que la reconnexion sur PBT_APMRESUMEAUTOMATIC, qui arrive à la reprise ; placez le travail visible par l'utilisateur tel que les mises à jour d'écran ou une invite de reconnexion sur PBT_APMRESUMESUSPEND, qui n'arrive que lors d'une reprise initiée par l'utilisateur
ra["PBT_APMRESUMEAUTOMATIC (à la reprise)"] --> m["Rétablissement mécanique"]
rs["PBT_APMRESUMESUSPEND (reprise initiée par l'utilisateur)"] --> u["Travail visible par l'utilisateur"]
m -.-> m1["Reconnecter et rouvrir les handles"]
u -.-> u1["Mises à jour d'écran et invite de reconnexion"]
Figure 3 : la seconde n’arrive pas lors d’une reprise sans surveillance, donc placer le rétablissement requis sur la seconde le fera manquer.
Les applications sans fenêtre peuvent aussi recevoir les notifications
Les services sans fenêtre et les applications console peuvent utiliser RegisterSuspendResumeNotification avec DEVICE_NOTIFY_CALLBACK et recevoir les mêmes notifications via un callback.8
De plus, WM_POWERBROADCAST ne peut pas indiquer si l’état basse consommation était la veille ou la mise en veille prolongée.7 L’application doit concevoir son rétablissement autour de l’événement commun « ça s’est arrêté, et ça est revenu ».
3. Modern Standby — le sens de « veille » a changé
Que le système tourne et que l’application puisse tourner sont deux choses distinctes
La veille S3 traditionnelle est un modèle qui arrête le système entier. Modern Standby, à l’inverse, est un modèle proche du smartphone dans lequel le système continue de tourner par intermittence après l’extinction de l’écran.
Cela ne signifie toutefois pas que les applications de bureau ordinaires continuent de s’exécuter. Au premier stade de l’entrée en veille, elles sont mises en pause par le Desktop Activity Moderator (DAM).3
| Mode | Comportement du système | Hypothèse pour les applications de bureau |
|---|---|---|
| Veille S3 traditionnelle | Le système entier s’arrête | Le code ne s’exécute pas pendant la veille |
| Modern Standby | Tourne par intermittence pour maintenir le réseau, recevoir des notifications, etc. | Mises en pause par le DAM ; le code ordinaire ne s’exécute pas |
Les composants qui bénéficient de l’activité intermittente sont ceux construits pour ce mécanisme. Pour la conception d’une application métier, la conclusion est la même dans les deux cas : « votre propre code ne s’exécute pas pendant la veille ».3
flowchart TB
accTitle: Différence entre veille traditionnelle et Modern Standby
accDescr: La veille S3 traditionnelle arrête le système entier, tandis que sous Modern Standby le système continue de tourner par intermittence après l'extinction de l'écran. Les applications de bureau sont toutefois mises en pause par le DAM, donc le code de l'application ne s'exécute dans aucun des deux cas
s3["Veille S3 traditionnelle : le système entier s'arrête"] --> conc["Le code de l'application ne s'exécute pas"]
ms["Modern Standby : le système tourne par intermittence"] --> dam["Les applications de bureau sont mises en pause par le DAM"]
dam --> conc
Figure 4 : le modèle a changé, mais pour une application de bureau la conclusion est la même : « vous ne pouvez pas tourner pendant la veille ».
Ne faites pas de la notification de reprise le seul déclencheur du rétablissement
L’entrée et la sortie du ralenti basse consommation de Modern Standby ne coïncident pas toujours avec la transition de suspension traditionnelle. Une connexion peut déjà être cassée sans qu’aucune notification n’arrive. Traitez la notification de reprise comme une aide qui accélère le rétablissement, et placez au centre un chemin qui reconnecte à la détection d’une erreur de communication. La structure concrète est expliquée au chapitre 5.
De plus, comme la transition vers l’état basse consommation est progressive, le moment des déconnexions et des arrêts n’est pas aussi net que sous S3. Les utilisateurs aussi ont du mal à distinguer « l’écran vient de s’éteindre » de « ça s’est mis en veille », donc lorsque vous prenez un rapport de symptôme, confirmez si le capot a été fermé et pendant combien de minutes la machine a été laissée inactive.
4. Ce qui casse — symptômes classiques
Les erreurs après la reprise se rangent en connexions, handles de périphériques et continuité du temps. Pour les ressources partagées, vérifiez aussi combien de temps prennent la réauthentification et le rétablissement du réseau.
Une connexion TCP ne remarque la coupure qu’à l’envoi ou à la réception
Pendant la veille, l’autre côté, les équipements NAT et les pare-feu traitent votre silence comme un délai d’expiration et abandonnent la connexion. Votre socket n’en sait rien, cependant, donc elle échoue seulement lorsque vous envoyez ou recevez après la reprise.
Parfois, une réception en attente ne produit jamais d’erreur. C’est pourquoi il faut un keepalive pour vérifier si la connexion est vivante. Les connexions de base de données et les WebSockets suivent le même schéma.
Les ports série et les périphériques USB ont besoin que leurs handles soient rouverts
Un périphérique USB peut, à la reprise, sembler avoir été débranché puis rebranché, et le handle qui était ouvert commence à renvoyer des erreurs. C’est le schéma typique d’une application de contrôle d’équipement qui « n’a une erreur de communication qu’après la pause déjeuner ».
Plutôt que de supposer que le handle reste utilisable, structurez l’application pour qu’elle puisse rouvrir le périphérique. La conception de la reconnexion est aussi traitée dans l’article sur la communication série.
Revoir séparément le travail périodique, le temps écoulé et le travail planifié
Les problèmes liés au temps se divisent en les trois types suivants.
| Travail | Ce qui se produit à travers la veille | Contre-mesure |
|---|---|---|
| Travail périodique tel que « interroger toutes les 10 secondes » | S’arrête pendant la veille. La façon dont il se déclenche après la reprise dépend de l’API et de l’environnement d’exécution | Reconstruire la planification à la reprise |
| Calculs qui utilisent la différence par rapport à l’horodatage précédent | La différence devient soudain « l’équivalent de 8 heures », et les moyennes ou les jugements de délai d’expiration cassent | Protéger contre les différences anormalement grandes |
| Travail planifié tel que « exécuter tous les soirs à 2 h » | Ne s’exécute pas si le PC est en veille à cette heure | Utiliser au besoin la fonction de réveil du Planificateur de tâches |
Le travail périodique en particulier peut se déclencher une fois immédiatement après la reprise pour le tick en retard, ou rien ne se produit jusqu’à la période suivante. Ne laissez pas le traitement des exécutions manquées au comportement implicite du minuteur.
flowchart TB
accTitle: Trois formes dans lesquelles la continuité du temps casse
accDescr: Le travail périodique s'arrête pendant la veille et le déclenchement après la reprise diffère selon l'API, donc reconstruisez la planification à la reprise ; la différence par rapport à l'horodatage précédent devient énorme après la reprise, donc protégez-la ; le travail planifié ne s'exécute pas si la machine est en veille, donc envisagez le réveil depuis la veille du Planificateur de tâches
t1["Travail périodique : s'arrête pendant la veille"] -.-> g1["Reconstruire la planification à la reprise"]
t2["Différence de temps écoulé : explose"] -.-> g2["Protéger contre les différences anormales"]
t3["Travail planifié : en veille, jamais exécuté"] -.-> g3["Réveiller la machine avec un réglage de réveil"]
Figure 5 : écrivez le traitement des minuteurs et de l’horloge en supposant que « le temps saute ». Chacune des trois formes a son propre type de contre-mesure.
flowchart TB
accTitle: Trois choses qui cassent à travers la veille
accDescr: À travers la veille, une connexion TCP est abandonnée par un délai d'expiration côté pair, le handle d'un périphérique USB est invalidé comme s'il avait été reconnecté, et le travail basé sur le temps écoulé observe un énorme saut de temps. Rétablissez chacun par reconnexion, réouverture et protection de différence
sleep["Intervalle de veille"] --> tcp["Connexion TCP : abandonnée côté pair"]
sleep --> usb["Périphérique USB : handle invalidé"]
sleep --> time["Temps écoulé : un énorme saut"]
tcp -.-> r1["Détecter l'erreur et reconnecter"]
usb -.-> r2["Rouvrir le périphérique"]
time -.-> r3["Protéger contre les différences anormales"]
Figure 6 : ce qui casse tombe en trois familles, « connexions », « handles » et « continuité du temps », et chacune a un type de rétablissement établi.
Les lecteurs réseau et les VPN ont une période d’attente juste après la reprise
Les lecteurs réseau et les VPN ont parfois besoin d’une réauthentification et d’un rétablissement après la reprise. Il en résulte une fenêtre de quelques secondes à quelques dizaines de secondes juste après la reprise pendant laquelle l’accès échoue.
Plutôt que de tout réessayer d’un coup au moment où la machine reprend, concevez l’application pour attendre un peu et réessayer par étapes.
5. Construire des applications qui survivent à la reprise
Le principe est de structurer l’application pour qu’elle puisse se rétablir à tout moment, même si les connexions et les handles ne survivent pas à travers la veille. Concevez la reconnexion, le traitement du temps et la suppression de la veille pour les intervalles qui en ont besoin, chacun pour soi.
Faire converger la notification de reprise et les erreurs de communication vers le même traitement de reconnexion
Lorsque le WM_POWERBROADCAST de la fenêtre de premier niveau reçoit PBT_APMRESUMEAUTOMATIC, abandonnez les connexions que vous détenez et reconstruisez-les. Toutefois, ne vous fiez pas à la seule notification de reprise. Des notifications peuvent être manquées, et une communication peut avoir lieu avant que la notification n’arrive.
Fournissez toujours un chemin qui « reconnecte lorsqu’une erreur de communication est détectée », et traitez la notification de reprise comme un déclencheur qui démarre ce travail plus tôt. L’exemple C# suivant est la partie qui demande une reconnexion depuis la notification de reprise. Le côté erreur de communication converge vers le même traitement de reconnexion.
// C# : faire converger la notification de reprise et les erreurs de communication vers le même traitement de reconnexion
protected override void WndProc(ref Message m)
{
const int WM_POWERBROADCAST = 0x0218;
const int PBT_APMRESUMEAUTOMATIC = 0x0012;
if (m.Msg == WM_POWERBROADCAST && (int)m.WParam == PBT_APMRESUMEAUTOMATIC)
{
_connectionManager.RequestReconnect(); // demande de reconnexion idempotente
}
base.WndProc(ref m);
}
La reconnexion combine « idempotence, backoff et keepalive »
Le traitement de reconnexion a besoin des trois éléments suivants ensemble.
| Élément | Rôle |
|---|---|
| Reconnexion idempotente | Se rétablir en toute sécurité, quel que soit le nombre de demandes |
| Nouvelles tentatives avec backoff exponentiel | Allonger l’intervalle avant la tentative suivante après un échec |
| Keepalive en régime établi | Confirmer que la connexion est vivante et détecter une coupure tôt |
Cet ensemble de trois éléments aide non seulement à la reprise de veille, mais tel quel aux coupures réseau brèves et aux redémarrages de périphériques.
flowchart TB
accTitle: Conception de reconnexion qui survit à la reprise
accDescr: La notification de reprise, une erreur de communication et un échec de keepalive convergent tous vers le même traitement de reconnexion idempotent, qui réessaie avec un backoff exponentiel en cas d'échec
e1["Notification de reprise (PBT_APMRESUMEAUTOMATIC)"] --> r["Traitement de reconnexion idempotent"]
e2["Erreur de communication détectée"] --> r
e3["Échec de keepalive"] --> r
r --> ok{"Réussi ?"}
ok -->|"Oui"| run["Retour au fonctionnement normal"]
ok -->|"Non"| back["Réessayer après backoff exponentiel"]
back --> r
Figure 7 : concentrez la reconnexion en un seul chemin idempotent, et entrez sur la même route depuis la notification de reprise, la détection d’erreur ou le keepalive.
Ne mélangez pas un intervalle où le temps a sauté dans vos calculs
Dans le travail qui utilise « le temps écoulé depuis la dernière fois », ajoutez une protection qui invalide l’intervalle lorsqu’elle détecte une différence anormalement grande. Le point est de ne pas la plier dans une moyenne et de ne pas la traiter comme un délai d’expiration ordinaire.
Lorsque vous mesurez le temps à travers la reprise, distinguez l’horloge qui continue d’avancer pendant la veille (temps civil) du temps réellement consacré au travail. La reconstruction de la planification du travail périodique et le traitement du travail planifié qui ne s’est pas exécuté doivent aussi être revus avec les catégories du chapitre 4.
Supprimez explicitement la veille pour le travail qui ne doit pas être interrompu
Pendant qu’un travail qui ne doit pas être interrompu par la veille est en cours, tel qu’une migration de données ou une communication continue avec un périphérique, utilisez SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED). Si vous voulez aussi garder l’affichage allumé, ajoutez ES_DISPLAY_REQUIRED.74
L’autre moyen est une demande d’alimentation via PowerCreateRequest et PowerSetRequest. Comme vous pouvez y joindre une chaîne de raison, powercfg /requests montre « qui bloque la veille, et pourquoi ». Celui-ci est plus aimable en ce que le personnel d’exploitation peut lire la raison.5
| Moyen | Unité de gestion et précautions |
|---|---|
SetThreadExecutionState |
Par thread. Levez-la depuis le même thread que celui qui l’a définie |
Demande d’alimentation (PowerCreateRequest + PowerSetRequest) |
Gérée par un handle. Utilisez celle-ci pour le travail qui change de thread, tel que async/await |
Toutefois, définir la suppression n’empêche pas toute forme d’interruption. Vérifiez les contraintes suivantes séparément de la logique de rétablissement.
| Contrainte | Réponse requise |
|---|---|
| Ce qui est supprimé est la veille automatique d’inactivité | Conservez la logique de reconnexion pour les actions explicites telles que fermer le capot ou choisir Veille dans le menu Démarrer |
| Sur une machine Modern Standby sur batterie, les demandes d’alimentation sont aussi coupées un certain temps après le délai de veille | Garantissez le travail ininterrompable par l’alimentation secteur ou du côté exploitation5 |
| Un oubli de levée empêche le PC de se mettre en veille | Levez-la toujours lorsque le travail se termine |
flowchart TB
accTitle: Deux moyens de supprimer la veille
accDescr: Que vous utilisiez le pratique SetThreadExecutionState ou l'API de demande d'alimentation qui peut joindre une chaîne de raison et est visible pour un administrateur via powercfg, levez-la toujours lorsque le travail se termine
need["Intervalle de travail qui ne doit pas être interrompu par la veille"] --> a["SetThreadExecutionState"]
need --> b["Demande d'alimentation (PowerSetRequest)"]
a -.-> a1["Pratique, drapeaux seulement"]
b -.-> b1["Avec une raison, visible dans powercfg"]
a --> off["Toujours lever à la fin du travail"]
b --> off
Figure 8 : pour les deux moyens, « lever lorsque vous avez terminé » est une condition absolue. Une demande d’alimentation, qui peut rendre la raison visible, est plus aimable pour l’exploitation.
Si le fonctionnement continu est une exigence, revoir l’emplacement et l’exploitation
Les services et les applications sans fenêtre peuvent aussi recevoir les notifications via DEVICE_NOTIFY_CALLBACK avec RegisterSuspendResumeNotification.8
Si le fonctionnement continu est vraiment requis, toutefois, reconsidérez le fait de garder le travail résident sur un PC client qui se met en veille. Déplacer le travail côté serveur ou vers une machine exploitée sans veille est la correction fondamentale.
6. Investigation — powercfg et le journal d’événements
Pour une demande de support, confirmez d’abord si le PC était en veille juste avant l’erreur. Demandez si le capot a été fermé et pendant combien de minutes la machine a été laissée inactive, puis utilisez l’outil qui convient au symptôme.
| Ce qu’il faut découvrir | Outil | Ce qu’il faut vérifier |
|---|---|---|
| Pourquoi elle ne se met pas en veille | powercfg /requests |
Les processus et pilotes qui émettent des demandes d’alimentation. Vérifiez aussi un SetThreadExecutionState jamais levé |
| Pourquoi elle se réveille toute seule | powercfg /lastwake, powercfg /waketimers |
La raison du réveil le plus récent, et les minuteries réservées pour réveiller la machine |
| Qualité de Modern Standby | powercfg /sleepstudy |
Consommation et activité par intervalle de veille9 |
| La chronologie de veille et de reprise | Kernel-Power dans le journal d’événements Système |
Enregistrements de l’entrée en veille et de la reprise |
En rapprochant le journal d’événements du journal de l’application, vous pouvez confirmer objectivement s’il y a eu une reprise juste avant l’erreur. Ne vous arrêtez pas à suspecter la veille ; alignez les horodatages et isolez la cause.
flowchart TB
accTitle: Correspondance entre symptômes d'alimentation et commandes d'investigation
accDescr: Pour un symptôme ne-se-met-pas-en-veille, trouvez qui détient une demande d'alimentation avec powercfg /requests ; pour un symptôme se-réveille-toute-seule, trouvez la raison du réveil avec /lastwake et /waketimers ; pour la chronologie, utilisez Kernel-Power dans le journal d'événements
s1["Elle ne se met pas en veille"] --> c1["powercfg /requests"]
s2["Elle se réveille toute seule"] --> c2["powercfg /lastwake et /waketimers"]
s3["Vouloir vérifier la chronologie"] --> c3["Kernel-Power dans le journal d'événements"]
c1 -.-> note["Une suppression de veille jamais levée apparaît aussi"]
Figure 9 : les symptômes se correspondent aux commandes d’investigation en trois familles. Confirmez d’abord « s’est-elle mise en veille juste avant », puis choisissez l’outil.
7. Résumé
Le traitement de la veille n’est pas terminé du seul fait de recevoir les notifications. Prévoyez que la préparation n’arrive pas à temps et que la notification de reprise n’arrive pas, et répartissez les rôles comme suit.
| Cible de conception ou d’investigation | Points à retenir |
|---|---|
| Avant la veille | Elle ne peut pas être refusée. Préparez-vous dans le délai de grâce d’environ 2 secondes de PBT_APMSUSPEND, mais aucune notification n’arrive en urgence |
| Notifications de reprise | Rétablissement requis sur PBT_APMRESUMEAUTOMATIC, travail visible par l’utilisateur sur PBT_APMRESUMESUSPEND. Ne vous fiez pas aux seules notifications |
| Connexions et handles | Centrez sur la reconnexion depuis les erreurs de communication, et combinez idempotence, backoff exponentiel et keepalive |
| Temps | Protégez contre les différences anormales de temps écoulé et reconstruisez le travail périodique. Le travail planifié ne s’exécute pas pendant que la machine est en veille |
| Suppression de la veille | Définissez-la seulement pour les intervalles qui en ont besoin et levez-la ensuite. Conservez le rétablissement pour les actions de veille explicites et analogues |
| Investigation de cause | Demandez si la machine était en veille juste avant, et rapprochez les enregistrements de powercfg et de Kernel-Power du journal de l’application |
Du point de vue de l’application, la veille est un événement dans lequel « le temps saute sans avertissement, les connexions avec l’entourage sont coupées, puis tout revient ». Que la conception traite cela comme une partie du quotidien plutôt que comme une situation anormale, voilà ce qui sépare les applications métier stables des instables à l’ère du portable.
Articles connexes
- Pièges des applications de communication série — de la reconnexion à la conception des journaux
- L’arrêt de Windows vu depuis l’application — survivre correctement aux notifications de fermeture, aux redémarrages et aux coupures d’alimentation
- Qu’est-ce que le mode Efficacité de Windows ? — L’icône de feuille verte et comment le désactiver
- Pourquoi préférer l’attente sur événement à Sleep(1) sous Windows
- Ce qu’est vraiment « Ne répond pas » — comment Windows juge qu’une application est bloquée, et comment concevoir des applications qui ne le sont pas
Domaines de conseil associés
KomuraSoft LLC prend en charge l’investigation des causes de problèmes tels que « la communication casse après la reprise de veille » et « la connexion avec l’équipement se coupe après la pause déjeuner », l’ajout a posteriori de logique de reconnexion et de traitement des événements d’alimentation à des applications existantes, et les revues de conception d’applications métier et de logiciels de contrôle d’équipement construits pour un fonctionnement sur portable.
- Investigation de bugs et analyse des causes
- Développement d’applications Windows
- Conseil technique et revue de conception
- Contact
Références
-
Microsoft Learn, PBT_APMSUSPEND event. Sur le fait que c’est l’événement délivré juste avant que l’ordinateur n’entre dans l’état de suspension ; sur le fait que l’application est censée terminer le travail nécessaire pour enregistrer ses données ; et sur le fait que le système accorde environ 2 secondes pour traiter cette notification, une application qui continue au-delà pouvant être interrompue. ↩ ↩2
-
Microsoft Learn, System Power Management Events. Sur le système qui diffuse à l’avance les changements de mode de fonctionnement tels que la veille ; sur PBT_APMSUSPEND délivré avant la veille d’inactivité afin que l’application puisse se préparer en fermant des fichiers et en enregistrant des données ; sur une suspension d’urgence (batterie critique et analogue) qui ne donne aucune notification préalable ; sur chaque application qui dispose d’au plus 2 secondes pour traiter ce message et est coupée après le délai ; et sur chaque application notifiée à la reprise. ↩ ↩2 ↩3
-
Microsoft Learn, Prepare software for modern standby. Sur le Desktop Activity Moderator (DAM) qui met en pause les applications de bureau au premier stade de la transition vers Modern Standby ; et sur le système qui passe ensuite par étapes dans la phase basse consommation et la phase de résilience, seuls les composants autorisés tournant par intermittence. ↩ ↩2 ↩3
-
Microsoft Learn, SetThreadExecutionState function (winbase.h). Sur le fait que ES_SYSTEM_REQUIRED et ES_DISPLAY_REQUIRED suppriment la veille d’inactivité du système et l’extinction de l’affichage ; et sur le fait de déclarer une suppression continue avec ES_CONTINUOUS et de la lever, une fois terminé, en appelant avec ES_CONTINUOUS seul. ↩ ↩2
-
Microsoft Learn, PowerSetRequest function (winbase.h). Sur le fait de définir des types de demande tels que maintenir le système ou l’affichage allumés sur un objet de demande d’alimentation créé avec PowerCreateRequest ; sur le fait de joindre une chaîne de raison diagnostique ; et sur le fait que les demandes d’alimentation en cours peuvent être listées avec powercfg /requests. ↩ ↩2 ↩3
-
Microsoft Learn, PBT_APMRESUMESUSPEND event. Sur le fait que cet événement est envoyé après PBT_APMRESUMEAUTOMATIC lors d’une reprise initiée par l’utilisateur ou lorsque une entrée utilisateur est détectée ensuite ; sur le fait que seul PBT_APMRESUMEAUTOMATIC est envoyé pour une reprise d’une cause externe telle qu’un réveil distant ; et sur le fait que l’application est censée rouvrir les fichiers fermés au moment de la veille et se préparer à l’entrée utilisateur. ↩ ↩2
-
Microsoft Learn, WM_POWERBROADCAST message. Sur le fait que PBT_APMRESUMEAUTOMATIC est toujours envoyé à la reprise, avec PBT_APMRESUMESUSPEND envoyé en plus lors d’une reprise depuis une entrée utilisateur ; sur le fait que ce message ne distingue pas le type d’état basse consommation ; sur le fait que les détails des transitions d’état d’alimentation sont enregistrés dans le journal d’événements Système ; et sur le fait d’appeler SetThreadExecutionState pour empêcher le système d’entrer dans un état basse consommation. ↩ ↩2 ↩3
-
Microsoft Learn, RegisterSuspendResumeNotification function (winuser.h). Sur le fait que c’est l’API qui s’enregistre pour recevoir les notifications de suspension et de reprise, et sur le fait de spécifier DEVICE_NOTIFY_CALLBACK afin que, en plus de la livraison de messages à un handle de fenêtre, une application ou un service sans fenêtre puisse recevoir les notifications via un callback. ↩ ↩2
-
Microsoft Learn, Modern standby SleepStudy. Sur le rapport généré par powercfg /sleepstudy qui montre, par intervalle Modern Standby, la consommation, l’activité et la raison du réveil (bouton d’alimentation, entrée utilisateur, minuterie de réveil, etc.). ↩
Articles associés
Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.
DllMain et le verrou du chargeur — la vraie raison pour laquelle on vous dit de « ne rien faire dans l'initialisation d'une DLL »
Pourquoi il ne faut pas appeler LoadLibrary ni synchroniser avec d'autres threads depuis DllMain. À partir des sources primaires, cet art...
Ce qu'est vraiment « Ne répond pas » — comment Windows juge qu'une application est bloquée, et comment concevoir des applications qui ne le sont pas
Le « Ne répond pas » de Windows est un mécanisme dans lequel l'OS juge qu'une fenêtre n'a pas récupéré de message pendant 5 secondes et l...
Ce que le démarrage rapide fait vraiment — pourquoi « Arrêter » sous Windows n'est pas un redémarrage
Un arrêt Windows est par défaut un arrêt hybride, qui enregistre le noyau et les pilotes dans hiberfil.sys. Pourquoi seul un redémarrage ...
Pourquoi les arguments se cassent — Les règles des arguments de ligne de commande Windows
Windows passe à CreateProcess une seule chaîne que le destinataire découpe. Traite les règles de CommandLineToArgvW, du CRT et de .NET, A...
Ce qui reste après la mort du parent — garder les processus enfants dans un Job Object
Pourquoi les aides du SDK survivent à une IU tuée et gardent la caméra ou le port COM. Concevoir la durée de vie des processus enfants av...
Sujets associés
Ces pages replacent le sujet dans un contexte plus large de services et de décisions.
Thèmes techniques Windows
Portail des sujets sur le développement Windows, l'analyse des incidents et la valorisation des actifs existants.
Services liés à ce sujet
Cet article est directement lié aux services suivants.
Développement d'applications Windows
Applications métier, intégration d'équipements et outils de communication, des besoins au développement.
Questions fréquentes
Questions souvent posées lors d’une consultation sur le sujet de cet article.
- Une application peut-elle savoir à l'avance que la machine va se mettre en veille et la refuser ?
- Sous Windows actuel, une application peut recevoir la notification, mais elle ne peut pas la refuser. Juste avant la veille, un message WM_POWERBROADCAST délivre l'événement PBT_APMSUSPEND ; l'application peut se préparer en fermant des fichiers et en enregistrant l'état, mais le temps accordé au traitement est d'environ 2 secondes par application. Au-delà, le système poursuit sans attendre. Lors d'une suspension d'urgence, par exemple une batterie presque épuisée, aucune notification préalable n'arrive. Une conception qui « doit terminer avant la veille » ne tient donc pas ; il faut une conception capable de se rétablir à la reprise, peu importe le moment de la coupure. Pour un intervalle de travail que vous ne voulez vraiment pas interrompre par la veille, supprimez-la explicitement avec SetThreadExecutionState ou une demande d'alimentation (PowerSetRequest).
- Comment détecter que la machine a repris ?
- Si l'application a une fenêtre, gérez WM_POWERBROADCAST. À la reprise depuis la suspension, PBT_APMRESUMEAUTOMATIC arrive, et si la reprise a été causée par une action de l'utilisateur (le bouton d'alimentation ou une touche), PBT_APMRESUMESUSPEND le suit. Une reprise sans surveillance qui se remet en veille immédiatement ne délivre que PBT_APMRESUMEAUTOMATIC, donc la scission de base consiste à placer le travail requis tel que la reconnexion du côté PBT_APMRESUMEAUTOMATIC et le travail visible par l'utilisateur tel que les mises à jour d'écran du côté PBT_APMRESUMESUSPEND. Les services sans fenêtre et les applications console peuvent recevoir les mêmes notifications via un callback en utilisant RegisterSuspendResumeNotification avec DEVICE_NOTIFY_CALLBACK.
- Puis-je garder l'application en cours d'exécution pendant la veille ?
- En règle générale, non. Pendant la veille, l'exécution du CPU elle-même s'arrête (sur une machine Modern Standby, les applications de bureau sont mises en pause par le Desktop Activity Moderator), et le code de l'application ne s'exécute pas. Il y a deux options. L'une consiste à supprimer la veille uniquement pendant que le travail est en cours. Spécifier ES_SYSTEM_REQUIRED avec SetThreadExecutionState, ou émettre une demande d'alimentation avec PowerCreateRequest/PowerSetRequest, supprime la veille automatique d'inactivité pendant cet intervalle (vous pouvez le vérifier avec powercfg /requests). Cela ne peut toujours pas arrêter une action de veille explicite telle que l'utilisateur qui ferme le capot, donc vous devez encore être prêt pour la reprise même pendant que la suppression est active. L'autre consiste à accepter la veille et à concevoir l'application pour « rattraper après la reprise ». Pour un travail planifié tel qu'un lot nocturne, vous pouvez aussi réveiller le PC avec « Réveiller l'ordinateur pour exécuter cette tâche » du Planificateur de tâches. Un travail qui a vraiment besoin de tourner en continu appartient à un serveur ou à un service configuré pour ne pas se mettre en veille.
- Pourquoi les connexions TCP et les ports série cessent-ils de fonctionner après la reprise ?
- Parce que les adaptateurs réseau et les périphériques USB passent aussi dans un état basse consommation pendant la veille. La connexion TCP a déjà été abandonnée par l'autre côté ou par un délai d'expiration NAT ou de pare-feu, donc l'envoi et la réception après la reprise échouent (vous ne le remarquez souvent que lorsqu'ils échouent). Les adaptateurs USB-série et analogues sont parfois traités comme un retrait puis une réinsertion de périphérique à la reprise, et le handle qui était ouvert devient invalide. Dans les deux cas, la bonne hypothèse est que « les handles et les connexions ne survivent pas à travers la reprise », et la bonne réponse est d'implémenter une logique de reconnexion qui reconstruit la connexion à une notification de reprise ou à une erreur de communication. Le schéma établi combine un keepalive périodique avec des nouvelles tentatives qui utilisent un backoff exponentiel en cas d'échec.
- Comment investiguer une machine qui se met en veille toute seule ou se réveille toute seule ?
- La commande powercfg est le premier outil. Dans le sens « elle ne se met pas en veille », powercfg /requests liste quels processus et pilotes ont émis une demande d'alimentation qui bloque la veille. Dans le sens « elle se réveille toute seule », powercfg /lastwake montre la raison du réveil le plus récent et powercfg /waketimers montre les minuteries actuellement réservées pour réveiller la machine. Sur une machine Modern Standby, powercfg /sleepstudy produit un rapport de consommation et d'activité pendant la veille. L'historique de veille et de reprise est aussi enregistré dans le journal d'événements (la source Kernel-Power dans le journal Système), donc vous pouvez vérifier sur une chronologie quand la machine s'est mise en veille, et quand et pourquoi elle s'est réveillée.
Profil de l’auteur
Page de présentation de l’auteur de l’article.
Go Komura
Représentant de KomuraSoft LLC
Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.