Empecher le programme de s'eteindre

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Empecher le programme de s'eteindre

Message par ChaudEf »

Bonsoir, j'ai remarque quelque chose d'interressant.
Lorsque on eteinds l'ordinateur, windows ferme tout les programmes actifs.
Cependant, un programme peut empecher cette fermeture automatique, comme par exemple Microsoft Word, qui empeche l'ordinateur de s'eteindre si on n'a pas sauvgarde les fichiers.

Je me suis demande si c'etait possible de programmer un truc comme ca, j'ai un programme qui joue de la musique, et je veux qu'il la joue tout le temps que l'ordinateur est allume, et pourtant, ca m'est arrive plusieurs fois d'eteindre l'ordinateur en oubliant de sauvgarder un document word, mon programme de musique a ete eteint automatiquement par windows, mais l'ordinateur ne s'est pas eteint, je suis revenu sur word pour sauvgarder et du coup j'ai fait encore quelquue petits changements sur mon document, et je me suis demande comment refuser l'extincsion automatique de windows, de facon a ce que mon programme soit le dernier eteint, une fois que tout les autres programmes soient eteint (ou mieux encore, ca ne me derange pas qu'il soit eteint en dur par windows).

J'ai commence un petit code, je recupere le signal de windows, mais je ne sais pas comment le continuer, comment refuser ce signal. pour l'instant j'arrive a bipper juste avant de s'eteindre, mais pas plus.

Si quelqu'un a une idee, je le remercie d'avance.

Code : Tout sélectionner

Procedure RefuserFinDeSession(hWnd, uMsg, wParam, lParam) 
	Result = #PB_ProcessPureBasicEvents 
	
	Select uMsg
		Case #WM_QUERYENDSESSION : Beep_(100,1000)
	EndSelect
	ProcedureReturn Result
EndProcedure


OpenWindow(0, 0, 0, 90, 90, "RefuserFinDeSession", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowCallback(@RefuserFinDeSession())

Repeat
	Select WaitWindowEvent()
	EndSelect
	
ForEver
Windows 10 x64 -- Purebasic 5.70 LTS x86
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Empecher le programme de s'eteindre

Message par falsam »

Essayes ce code

Code : Tout sélectionner

Procedure WindowsCallback(WindowID,Message,wParam,lParam)
  If Message=#WM_QUERYENDSESSION
    ProcedureReturn 0 ; Aborts shutdown.
  Else
    ProcedureReturn #PB_ProcessPureBasicEvents
  EndIf
EndProcedure

OpenWindow(0,200,200,300,100, "Prevent Shutdown", #PB_Window_SystemMenu)
SetWindowCallback(@WindowsCallback())

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Re: Empecher le programme de s'eteindre

Message par ChaudEf »

Merci beaucoup falsam, tu m'a mit sur une bonne piste.
J'ai fouine sur le MDSN de Microsoft, et il y a en fait deux options, WM_QUERYENDSESSION et WM_ENDSESSION .
La premiere est une alerte que le programme doit se fermer, et a laquelle on peut repondre par 0 pour dire que le programme n'est pas pret, et la deuxieme est une alerte que le programme se ferme tout de suite, et ne peut pas y refuser.

D'ailleurs, si on refuse le shutdown lors du WM_QUERYENDSESSION , on recoit un WM_ENDSESSION bien que la machine ne s'eteint pas, mais on le wParam sera False.

En fin de compte, maintenant je me retrouve avec le probleme inverse. Je peut empecher la fermeture de mon programme, mais il refuse toujours de se fermer, meme si aucun autre programme ne bloque. Ce qu'il faudrait soit qu'il n'affiche pas d'objection a la fermeture, simplement que je sache quand exactement il se ferme, grace a WM_ENDSESSION, mais pas qu'il affiche que le windows ne peut pas se fermer a cause de lui, en tout les cas pas quand il n'y a aucun autre programme qui bloque.

J'ai pense a verifier dans la liste des process, si il y a une fenetre qui ne se ferme pas, mais il doit surement y avoir un moyen plus propre de le faire.

Code : Tout sélectionner

Procedure RefuserFinDeSession(hWnd, uMsg, wParam, lParam) 
	Result = #PB_ProcessPureBasicEvents 
	
	Select uMsg
		Case #WM_QUERYENDSESSION : ProcedureReturn 0
		Case #WM_ENDSESSION : If wParam <> #False : Beep_(1300, 1000) : EndIf
			ProcedureReturn Result
	EndSelect
	ProcedureReturn Result
EndProcedure

Procedure bip(null.l)
	Repeat

	Beep_(1000,100)
	Delay(1000)
ForEver
EndProcedure

OpenWindow(0, 0, 0, 90, 90, "RefuserFinDeSession", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowCallback(@RefuserFinDeSession())
CreateThread(@bip(), 0)
Repeat
	Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			End
	EndSelect
ForEver
 
Windows 10 x64 -- Purebasic 5.70 LTS x86
Avatar de l’utilisateur
celtic88
Messages : 309
Inscription : sam. 12/sept./2015 14:31
Localisation : Alger

Re: Empecher le programme de s'eteindre

Message par celtic88 »

:D re bonjour
essayé ça

Code : Tout sélectionner

; Import "user32.lib"
;   ShutdownBlockReasonCreate(hwnd.i,*pwszReason)
; EndImport

;By celtic88 Dz(c)
;*******Require Windows Vista Or later.

OpenLibrary(0,"user32.dll")
Prototype.b ShutdownBlockReasonCreate(hwnd.i,pwszReason.p-unicode)
Global ShutdownBlockReasonCreate_.ShutdownBlockReasonCreate = GetFunction(0,"ShutdownBlockReasonCreate")
Prototype.l ShutdownBlockReasonQuery(hwnd.i,*pwszBuff,*pcchBuff)
Global ShutdownBlockReasonQuery_.ShutdownBlockReasonQuery = GetFunction(0,"ShutdownBlockReasonQuery")
Prototype.b ShutdownBlockReasonDestroy(hwnd.i)
Global ShutdownBlockReasonDestroy_.ShutdownBlockReasonDestroy = GetFunction(0,"ShutdownBlockReasonDestroy")

Procedure WindowsCallback(WindowID,Message,wParam,lParam)
  If Message=#WM_QUERYENDSESSION
    If ShutdownBlockReasonQuery_(WindowID,0,0);The Block Shutdown is on?
      ProcedureReturn 0
    EndIf
  Else
    ProcedureReturn #PB_ProcessPureBasicEvents
  EndIf
EndProcedure

OpenWindow(0,200,200,300,100, "Prevent Shutdown", #PB_Window_SystemMenu)
SetWindowCallback(@WindowsCallback())

SetProcessShutdownParameters_($03FF,0);Application reserved first shutdown range.
ShutdownBlockReasonCreate_(WindowID(0), "cette application empêche l'arrêt de système.");Indicates that the system cannot be shut down and sets a reason string to be displayed to the user if system shutdown is initiated

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow

ShutdownBlockReasonDestroy_(WindowID(0)); Indicates that the system can be shut down and frees the reason string

.....i Love Pb :)
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Empecher le programme de s'eteindre

Message par nico »

Salut celtic88,

code intéressant mais j'ai relevé des problèmes, ShutdownBlockReasonQuery_(WindowID,0,0) renvoie toujours faux, sans doute parce qu'il faudrait mettre des pointeurs valides, mais même dans ce cas, à quoi ça sert puisque la fonction renverra 0 ou 1 suivant l'utilisation ou non de la fonction ShutdownBlockReasonCreate_(WindowID(0), "cette application empêche l'arrêt de système.").

le deuxième point concerne la valeur appliquée à la fonction SetProcessShutdownParameters_($03FF,0), soit $03FF, il apparaît dans mes essais que si la valeur est basse, alors dans ce cas le programme est en bas de la liste lors du listage des programmes qui bloque window, ce que l'on veut obtenir si j'ai bien tout compris.

Donc en résumé un seul appel à la fonction SetProcessShutdownParameters_(0, 0) avec pour les deux arguments 0 devrait suffire pour le résultat voulu.

A confirmer par d'autres.
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Re: Empecher le programme de s'eteindre

Message par ChaudEf »

Je confirme ce que dit nico, la fonction "If ShutdownBlockReasonQuery_(WindowID,0,0)" retourne toujours 1, et donc si on veut ensuite checker les autres fenetres qui empechent le shutdown, et des qu'elles se ferment, autoriser le programe a s'eteindre, on n'a pas de moyen de lui faire ce changement.

A part ca, la valeur 0 parait plus adapte pour la fonction "SetProcessShutdownParameters", comme explique sur la mdsn.
Windows 10 x64 -- Purebasic 5.70 LTS x86
Répondre