Empêcher Windows 10 de redémarrer automatiquement après une mise à jour par programme

QUESTION: Existe-t-il un moyen programmatique d’empêcher Windows 10 de redémarrer automatiquement après une mise à jour?

Nous travaillons sur des logiciels “critiques” fonctionnant sous Windows. En général, il est mauvais qu’une mise à jour automatique de Windows interrompe notre processus, car cela peut entraîner une perte d’argent dans le matériel mis au rebut (vous ne pouvez pas vous arrêter et reprendre plus tard, le travail doit se terminer sans interruption).

Par le passé, nous avons pu contourner ce problème en demandant à notre installateur de logiciel de définir un paramètre dans le registre Windows (avec le consentement de l’installateur) qui empêcherait le redémarrage automatique après une mise à jour automatique lorsqu’un utilisateur est connecté. d’une mise à jour automatique, l’utilisateur serait averti qu’il y a une mise à jour nécessitant un redémarrage et de cliquer sur un bouton lorsqu’ils étaient prêts. Cela a fonctionné pour Windows Vista, 7 et 8 / 8.1. Cependant, pour le dernier Windows 10 (je travaille avec la mise à jour des créateurs), le paramètre ne semble plus avoir d’effet, car j’ai pu constater que mon ordinateur était automatiquement mis à jour.

Dans mes recherches, j’ai trouvé ce qui semble être un lieu d’espoir où un paramètre peut être sélectionné où Windows offrira à l’utilisateur la possibilité de planifier la mise à jour au lieu de le faire automatiquement au moment où Windows le juge approprié (informations ici ) . Cependant, je ne sais pas comment procéder pour configurer Windows par programmation afin que l’option de planification d’une mise à jour devienne la valeur par défaut.

Existe-t-il un moyen programmatique de configurer Windows 10 (de manière conviviale, de préférence) pour qu’il ne redémarre pas automatiquement?

Essayez les API de raison de blocage d’arrêt. ShutdownBlockReasonCreate

La documentation de l’API cite la gravure de CD comme exemple, mais la même chose s’appliquerait à votre processus “critique”.

Les applications doivent appeler cette fonction lorsqu’elles commencent une opération qui ne peut pas être interrompue, par exemple graver un CD ou un DVD. Lorsque l’opération est terminée, appelez la fonction ShutdownBlockReasonDestroy pour indiquer que le système peut être arrêté.

Notez que la documentation fait spécifiquement référence à la fermeture de l’utilisateur, mais je ne vois pas pourquoi elle ne devrait pas s’appliquer également au redémarrage de la mise à jour.

NB : N’oubliez pas de vérifier que la fonction est réussie; et pour détruire la raison d’arrêt à la fin du processus.


D’après votre commentaire, il semble que vous ayez besoin d’aide avec les routines de l’API Windows. Je vous suggère de déclarer les fonctions externes dans une bibliothèque appropriée. (Mais vous pouvez tester dans la même unité sans souci.)

 function ShutdownBlockReasonCreate(hWnd: HWND; Reason: LPCWSTR): BOOL; stdcall; external user32; function ShutdownBlockReasonDestroy(hWnd: HWND): BOOL; stdcall; external user32; 

Ce qui suit montre comment utiliser l’API. NB: Faites attention à la vérification des erreurs. J’ai démontré comment obtenir des informations sur les erreurs. Ce que vous en faites est à vous.

L’autre chose importante à souligner (répétée dans les commentaires) est que vous ne devez pas bloquer le thread principal. Pour plus d’informations, reportez-vous à la documentation Microsoft à partir de laquelle ces modifications ont été introduites dans Vista ici .

 procedure TForm1.JobStartClick(Sender: TObject); var LErr: Cardinal; begin ListBox1.Items.Add('Attempting to block shutdown:'); if (not ShutdownBlockReasonCreate(Application.MainForm.Handle, 'Super Critical Job')) then begin LErr := GetLastError; ListBox1.Items.Add('... failed: ' + SysErrorMessage(LErr)); //Probably not safe to start your job in this case, but perhaps you //choose to give it a shot anyway. Exit; end; ListBox1.Items.Add('... success'); FJobRunning := True; //Start the job. //However, NB do not run the job here. //If it takes a long time and is not asynchronous, you should probably //run your job on a separate thread. ***Do not block the main thread // otherwise Windows will still kill your app for not responding*** end; procedure TForm1.JobEndClick(Sender: TObject); var LErr: Cardinal; begin if (not FJobRunning) then Exit; //End the job. //Again, do not block the main thread, so perhaps this is rather something //to do after you already know the job is done. FJobRunning := False; ListBox1.Items.Add('Allow shutdown'); if (not ShutdownBlockReasonDestroy(Application.MainForm.Handle)) then begin LErr := GetLastError; ListBox1.Items.Add('... failed: ' + SysErrorMessage(LErr)); end; end; //Declare the handler for the WM_QUERYENDSESSION message as follows. //procedure WMQueryEndSession(var AMsg : TWMQueryEndSession); message WM_QUERYENDSESSION; procedure TForm1.WMQueryEndSession(var AMsg: TWMQueryEndSession); begin ListBox1.Items.Add('WMQueryEndSession'); if (FJobRunning) then //NB: This is very important. //You still need to confirm that your application wants to block //shutdown whenever you receive this message. AMsg.Result := 0 else inherited; end; 

La clé de Registre HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings contient deux entrées: ActiveHoursStart et ActiveHoursEnd . Modifiez ces entrées si nécessaire dans votre programme pour empêcher un redémarrage. De cette façon, vous pouvez contrôler le redémarrage pour ne pas avoir lieu pendant que votre programme s’exécute. Notez que vous devez disposer de privilèges élevés pour modifier ces parameters.