Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von c4s »

Im englischen Forum scheint mir leider keiner helfen zu können/wollen (http://www.purebasic.fr/english/viewtop ... 13&t=45691), deswegen stelle ich nun mal hier meine Frage.


Ich will einen Timer starten, wenn der Computer in den Ruhezustand geht und dann nach 30 Sekunden wieder aufwecken.
Blöderweise funktionieren ein paar Sachen noch nicht:
- Computer nach 30 aufwecken (siehe Logfile)
- #WM_POWERBROADCAST abfangen, wenn der Ruhezustand durch das Programm eingeleitet wurde (anstelle von Standby-Buttons des Systems etc.)
- ...

Hier ist der aktuelle Code:

Code: Alles auswählen

EnableExplicit

#Title = "TimerTest"

Enumeration
	#Window
	#Text
	#ButtonSuspend
	#ButtonHibernate
	#FileLog
EndEnumeration

#PBT_APMRESUMESUSPEND = $0007
#PBT_APMSUSPEND = $0004

Structure LogListItem
	Text.s
	Time.l
	Level.l
EndStructure

Global NewList LogList.LogListItem()

Define Logfile.s
Logfile.s = GetPathPart(ProgramFilename()) + #Title + "_LOG.txt"


Procedure LogListAdd(Text.s, Level=0)
	If AddElement(LogList())
		With LogList()
			\Text = Text
			\Time = Date()
			\Level = Level
		EndWith
	EndIf
EndProcedure

Procedure LogListAddError(Text.s, Level=2, Info=#True)
	Protected Error, ErrorInfo.s
	
	If Info = #True
		Error = GetLastError_()
		ErrorInfo = Space(#MAX_PATH)
		FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, Error, 0, @ErrorInfo, Len(ErrorInfo), 0)
		ErrorInfo = " -> (" + RSet(Hex(Error, #PB_Long), 8, "0") + ") " + #DQUOTE$ + ErrorInfo + #DQUOTE$
	EndIf
	
	LogListAdd(Text + ErrorInfo, Level)
EndProcedure

Procedure LogListSave(Filename.s)
	Protected FileNr
	Protected Result = #False
	
	FileNr = CreateFile(#PB_Any, Filename)
	If FileNr
		ForEach LogList()
			WriteStringN(FileNr, FormatDate("%hh:%ii:%ss", LogList()\Time) + #TAB$ + LogList()\Text)
		Next
		
		Result = #True
		CloseFile(FileNr)
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure DateToFiletime(Date, *ft.FILETIME)
	Protected st.SYSTEMTIME
	
	With st
		\wYear = Year(Date)
		\wMonth = Month(Date)
		\wDay = Day(Date)
		\wDayOfWeek = DayOfWeek(Date)
		\wHour = Hour(Date)
		\wMinute = Minute(Date)
		\wSecond = Second(Date)
		\wMilliseconds = 0
	EndWith
	
	SystemTimeToFileTime_(@st, *ft)
	LocalFileTimeToFileTime_(@*ft, *ft)
EndProcedure

Procedure TimerCallback(*ArgToCompletionRoutine, TimerLowValue.l, TimerHighValue.l)
	LogListAdd("Timer: Beendet")
EndProcedure

Procedure TimerStart()
	Protected hTimer
	Protected ft.FILETIME
	
	hTimer = CreateWaitableTimer_(#Null, #False, #Title)
	If hTimer
		LogListAdd("Timer: Erstellt")
		
		DateToFiletime(Date() + 30, @ft)  ; Wait 30 seconds until "waking up"
		
		If SetWaitableTimer_(hTimer, @ft, 0, @TimerCallback(), 0, #True)
			If GetLastError_() <> #ERROR_NOT_SUPPORTED
				LogListAdd("Timer: Gestartet")
				;SleepEx_(#INFINITE, #True)
			Else
				LogListAddError("Timer: Gestartet aber Aufwecken wird nicht unterstützt! (Meldung folgt nun sofort)")
			EndIf
		Else
			LogListAddError("Timer: Nicht gestartet!")
		EndIf
		CloseHandle_(hTimer)
	Else
		LogListAddError("Timer: Nicht erstellt!")
	EndIf
EndProcedure

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
	Select uMsg
		Case #WM_POWERBROADCAST
			Select wParam
				Case #PBT_APMSUSPEND
					LogListAdd("Standby: Aktiviert")
					TimerStart()
				Case #PBT_APMRESUMESUSPEND
					LogListAdd("Standby: Beendet")
			EndSelect
	EndSelect
	
	ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Suspend(Hibernate, ForceCritical=#False, DisableWakeEvent=#False)
	Protected LibraryID
	Protected Result = #False
	
	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "SetSuspendState", Hibernate, ForceCritical, DisableWakeEvent)
		CloseLibrary(LibraryID)
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure SuspendAllowed()
	Protected LibraryID
	Protected Result = #False
	
	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "IsPwrSuspendAllowed")
		CloseLibrary(LibraryID)
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure HibernateAllowed()
	Protected LibraryID
	Protected Result = #False
	
	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "IsPwrHibernateAllowed")
		CloseLibrary(LibraryID)
	EndIf
	
	ProcedureReturn Result
EndProcedure



If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 300, 170, #Title, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_Invisible)
	
	TextGadget(#Text, 10, 10, 280, 70, "Der Timer sollte automatisch starten (für 30 Sec.), wenn auf einen dieser Buttons oder im Startmenü entsprechendes geklickt wird." + #CRLF$ + #CRLF$ + "Hinweis: Die Buttons sollten funktionieren!")
	ButtonGadget(#ButtonSuspend, 10, 90, 280, 30, "Standby-Modus")
	ButtonGadget(#ButtonHibernate, 10, 130, 280, 30, "Ruhezustand")
	
	If SuspendAllowed() = #False : DisableGadget(#ButtonSuspend, #True) : EndIf
	If HibernateAllowed() = #False : DisableGadget(#ButtonHibernate, #True) : EndIf
	
	SetWindowCallback(@WindowCallback())
	
	HideWindow(#Window, #False)
	
	LogListAdd("Programm: Gestartet")
	
	
	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Gadget
				Select EventGadget()
					Case #ButtonSuspend
						LogListAdd("Standby: Starte Standby-Modus")
						TimerStart()  ; <-- Warum wird #WM_POWERBROADCAST nicht abgefangen um das hier zu machen? (siehe WindowCallback())
						Suspend(#False)
					Case #ButtonHibernate
						LogListAdd("Standby: Starte Ruhezustand")
						TimerStart()  ;
						Suspend(#True)
				EndSelect
			Case #PB_Event_CloseWindow
				LogListAdd("Programm: Beendet")
				LogListSave(Logfile) ;: RunProgram(Logfile)
				Break
		EndSelect
	ForEver
EndIf
Hier ist eine Logfile, die mit Windows Vista erstellt wurde. Standby wurde hierbei durch den "Standby-Modus"-Button gestartet:

Code: Alles auswählen

15:25:14   Programm: Gestartet
15:25:20   Standby: Starte Standby-Modus
15:25:20   Timer: Erstellt
15:25:20   Timer: Gestartet
15:25:20   Timer: Beendet  <-- Wo sind die 30 Sec.?
15:26:37   Standby: Beendet
15:26:45   Programm: Beendet

Momentan denke ich, dass es mehrere Probleme geben könnte: DateToFiletime() erstellt aus welchen Gründen auch immer eine Zeit in der Vergangenheit, SleepEx_() wird benötigt, Sicherheitsgründe (Privilegien benötigt?), mein PC unterstützt diese Art von Standby nicht und/oder Konflikte mit dem Message-Handling von PureBasic...

Bitte probiert mal den Code und postet welche Ergebnisse ihr bekommt, damit ich eventuell herausfinden kann, warum es nicht funktioniert. Danke.
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
jpd
Beiträge: 380
Registriert: 14.02.2005 10:33

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von jpd »

Hallo c4s,

habe ein VB beispiel gefunden das genau dass macht was du brauchst.
Habe leider nicht getestet, habe auch leider keine zeit dies in PB zu übersetzen.

Ich gehe aber davon aus das du dich auch mit VB code gut zurecht kommst! :-)


Rechner für bestimmte Zeitspanne schlafen legen...

Viel Spass beim schlafen legen.

Ciao
jpd
PB 5.10 Windows 7 x64
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von c4s »

Das scheint mir tatsächlich genau das zu sein was ich brauche. Ich werde es mir nachher mal anschauen, danke!
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
jpd
Beiträge: 380
Registriert: 14.02.2005 10:33

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von jpd »

Hallo c4s,

habe den VB beispiel unter XP probiert, und funzioniert ohne probleme dein beispiel liefert hingegen die gleiche log-datei wie bei dir und weckt den rechner nicht automatisch.
kurios ist das die VB anwendung unter Win 7 x86/x64 auch nicht funktioniert,also fährt rechner runter und weckt nicht wieder auf.

Bist du weiter gekommen?

Ciao
jpd
PB 5.10 Windows 7 x64
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von c4s »

Danke für das Testen.

Der Timer an sich war z.T. noch fehlerhaft aber das konnte ich hoffentlich reparieren (sind jetzt 60 Sekunden Warten):

Code: Alles auswählen

EnableExplicit

#Title = "TimerTest"

Enumeration
	#Window
	#Text
	#ButtonSuspend
	#ButtonHibernate
EndEnumeration

#PBT_APMRESUMEAUTOMATIC = $0012
#PBT_APMRESUMESUSPEND = $0007
#PBT_APMSUSPEND = $0004

#ES_CONTINUOUS = $80000000
#ES_DISPLAY_REQUIRED = $2
#ES_SYSTEM_REQUIRED = $1

Structure LogListItem
	Text.s
	Time.l
	Level.l
EndStructure

Global NewList LogList.LogListItem()

Define Logfile.s
Logfile.s = GetPathPart(ProgramFilename()) + #Title + "_LOG.txt"


Procedure LogListAdd(Text.s, Level=0)
	If AddElement(LogList())
		With LogList()
			\Text = Text
			\Time = Date()
			\Level = Level
		EndWith
	EndIf
EndProcedure

Procedure LogListAddError(Text.s, Level=2, Info=#True)
	Protected Error, ErrorInfo.s

	If Info = #True
		Error = GetLastError_()
		ErrorInfo = Space(#MAX_PATH)
		FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, Error, 0, @ErrorInfo, Len(ErrorInfo), 0)
		ErrorInfo = " -> (" + RSet(Hex(Error, #PB_Long), 8, "0") + ") " + #DQUOTE$ + ErrorInfo + #DQUOTE$
	EndIf

	LogListAdd(Text + ErrorInfo, Level)
EndProcedure

Procedure LogListSave(Filename.s)
	Protected FileNr
	Protected Result = #False

	FileNr = CreateFile(#PB_Any, Filename)
	If FileNr
		ForEach LogList()
			WriteStringN(FileNr, FormatDate("%hh:%ii:%ss", LogList()\Time) + #TAB$ + LogList()\Text)
		Next

		Result = #True
		CloseFile(FileNr)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure DateToFiletime(Date, *ft.FILETIME)
	Protected st.SYSTEMTIME
	Protected ftTemp.FILETIME

	With st
		\wYear = Year(Date)
		\wMonth = Month(Date)
		\wDay = Day(Date)
		\wHour = Hour(Date)
		\wMinute = Minute(Date)
		\wSecond = Second(Date)
		\wMilliseconds = 0
	EndWith

	SystemTimeToFileTime_(st, ftTemp)
	LocalFileTimeToFileTime_(ftTemp, *ft)
EndProcedure

Procedure TimerCallback(*ArgToCompletionRoutine, TimerLowValue.l, TimerHighValue.l)
	LogListAdd("Timer: Finished successfully")
EndProcedure

Procedure TimerStart()
	Protected hTimer
	Protected ft.FILETIME

	hTimer = CreateWaitableTimer_(#Null, #False, #Title) ;;
	If hTimer
		LogListAdd("Timer: Created")

		DateToFiletime(Date() + 60, @ft)  ; Wait for 60 secs

		If SetWaitableTimer_(hTimer, @ft, 0, @TimerCallback(), 0, #True)
			If GetLastError_() <> #ERROR_NOT_SUPPORTED
				LogListAdd("Timer: Started")
			Else
				LogListAddError("Timer: Started but doesn't support waking up! (Success message will appear now)")
			EndIf
			SleepEx_(#INFINITE, #True) ;;
		Else
			LogListAddError("Timer: Not started!")
		EndIf
		CancelWaitableTimer_(hTimer)
		CloseHandle_(hTimer)
	Else
		LogListAddError("Timer: Not created!")
	EndIf
EndProcedure

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
	Protected Result = #PB_ProcessPureBasicEvents

	Select uMsg
		Case #WM_POWERBROADCAST
			Select wParam
				Case #PBT_APMRESUMEAUTOMATIC  ; Operation is resuming automatically from low-power state. This is sent every time the system resumes.
					LogListAdd("Standby: Finished")
				Case #PBT_APMRESUMESUSPEND  ; Operation is resuming from low-power state. This is sent after PBT_APMRESUMEAUTOMATIC if the resume is triggered by user input.
					LogListAdd("Info: Finished by user input")
				Case #PBT_APMSUSPEND
					LogListAdd("Standby: Activated")
					TimerStart()
			EndSelect
			Result = #True
	EndSelect

	ProcedureReturn Result
EndProcedure

Procedure Suspend(Hibernate, ForceCritical=#False, DisableWakeEvent=#False)
	Protected LibraryID
	Protected Result = #False

	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "SetSuspendState", Hibernate, ForceCritical, DisableWakeEvent)
		CloseLibrary(LibraryID)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure SuspendAllowed()
	Protected LibraryID
	Protected Result = #False

	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "IsPwrSuspendAllowed")
		CloseLibrary(LibraryID)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure HibernateAllowed()
	Protected LibraryID
	Protected Result = #False

	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "IsPwrHibernateAllowed")
		CloseLibrary(LibraryID)
	EndIf

	ProcedureReturn Result
EndProcedure



If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 300, 170, #Title, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_Invisible)

	TextGadget(#Text, 10, 10, 280, 70, "The timer should start automatically (for 60 secs) when clicking on these buttons or the PC's " + #DQUOTE$ + "standby" + #DQUOTE$ + " button." + #CRLF$ + #CRLF$ + "Warning: These buttons do what they say!")
	ButtonGadget(#ButtonSuspend, 10, 90, 280, 30, "Suspend")
	ButtonGadget(#ButtonHibernate, 10, 130, 280, 30, "Hibernate")

	If SuspendAllowed() = #False : DisableGadget(#ButtonSuspend, #True) : EndIf
	If HibernateAllowed() = #False : DisableGadget(#ButtonHibernate, #True) : EndIf

	SetWindowCallback(@WindowCallback())

	HideWindow(#Window, #False)

	LogListAdd("Program: Started")


	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Gadget
				Select EventGadget()
					Case #ButtonSuspend
						LogListAdd("Standby: Start suspending")
						TimerStart()  ; <-- Why isn't #WM_POWERBROADCAST received to do this? (see WindowCallback())
						Suspend(#False)
					Case #ButtonHibernate
						LogListAdd("Standby: Start hibernating")
						TimerStart()  ;
						Suspend(#True)
				EndSelect
			Case #PB_Event_CloseWindow
				LogListAdd("Program: Closed")
				LogListSave(Logfile) ;: RunProgram(Logfile)
				Break
		EndSelect
	ForEver
EndIf
Das eigentliche Herunterfahren habe ich noch nicht getestet. Dazu komme ich wohl erst morgen. Aber wie gesagt: Der Timer sollte nun endlich funktionieren.

Ich bin mir noch nicht ganz sicher, ob nun das Drücken auf Standby/Ruhezustand im Startmenü abgefangen wird. Weiter verstehe ich nicht wie man den Timer im Hintergrund laufen lassen kann, ohne dass die Programmausführung gestoppt wird - SleepEx_() wird ja anscheinend benötigt.
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von c4s »

So, dieser Code funktioniert bestens bei mir. Drückt man Standby im Startmenü oder im Fenster wird automatisch der Timer für 1 Minute gestartet und Das System Heruntergefahren. Ist der Timer abgelaufen, startet der Rechner:

Code: Alles auswählen

EnableExplicit

Enumeration
	#Window
	#Text
	#ButtonSleep
	#ButtonHibernate
EndEnumeration

#PBT_APMRESUMEAUTOMATIC = $0012
#PBT_APMRESUMESUSPEND = $0007
#PBT_APMSUSPEND = $0004

#TIMER_MODIFY_STATE = $0002

Structure LogListItem
	Text.s
	Time.l
	Level.l
EndStructure

Global NewList LogList.LogListItem()

Global Title.s = "TimerTest"
Define Logfile.s = GetPathPart(ProgramFilename()) + Title + "_LOG.txt"


Procedure LogListAdd(Text.s, Level=0)
	If AddElement(LogList())
		With LogList()
			\Text = Text
			\Time = Date()
			\Level = Level
		EndWith
	EndIf
EndProcedure

Procedure LogListAddError(Text.s, Level=2, Info=#True)
	Protected Error, ErrorInfo.s

	If Info = #True
		Error = GetLastError_()
		ErrorInfo = Space(#MAX_PATH)
		FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, Error, 0, @ErrorInfo, Len(ErrorInfo), 0)
		ErrorInfo = " -> (" + RSet(Hex(Error, #PB_Long), 8, "0") + ") " + #DQUOTE$ + ErrorInfo + #DQUOTE$
	EndIf

	LogListAdd(Text + ErrorInfo, Level)
EndProcedure

Procedure LogListSave(Filename.s)
	Protected FileNr
	Protected Result = #False

	FileNr = CreateFile(#PB_Any, Filename)
	If FileNr
		ForEach LogList()
			WriteStringN(FileNr, FormatDate("%hh:%ii:%ss", LogList()\Time) + #TAB$ + LogList()\Text)
		Next

		Result = #True
		CloseFile(FileNr)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure DateToFiletime(Date, *ft.FILETIME)
	Protected st.SYSTEMTIME
	Protected ftTemp.FILETIME

	With st
		\wYear = Year(Date)
		\wMonth = Month(Date)
		\wDay = Day(Date)
		\wHour = Hour(Date)
		\wMinute = Minute(Date)
		\wSecond = Second(Date)
		\wMilliseconds = 0
	EndWith

	SystemTimeToFileTime_(st, ftTemp)
	LocalFileTimeToFileTime_(ftTemp, *ft)
EndProcedure

Procedure TimerCallback(*ArgToCompletionRoutine, TimerLowValue.l, TimerHighValue.l)
	LogListAdd("Timer: Finished successfully")
EndProcedure

Procedure TimerStart(Void)
	Protected hTimer
	Protected ft.FILETIME

	hTimer = CreateWaitableTimer_(#Null, #False, @Title)
	If hTimer
		;hTimer = OpenWaitableTimer_(#TIMER_MODIFY_STATE, #False, @Title)  ; Didn't work with this

		LogListAdd("Timer: Created")

		DateToFiletime(AddDate(Date(), #PB_Date_Minute, 1), @ft)  ; Timer should wait 1 minute

		If SetWaitableTimer_(hTimer, @ft, 0, @TimerCallback(), #Null, #True)
			LogListAdd("Timer: Started")
			If GetLastError_() = #ERROR_NOT_SUPPORTED
				LogListAddError("Info: Waking up not supported")
			EndIf
			SleepEx_(#INFINITE, #True)  ; Wait for timer to finish
		Else
			LogListAddError("Timer: Not started!")
		EndIf

		CloseHandle_(hTimer)
	Else
		LogListAddError("Timer: Not created!")
	EndIf
EndProcedure

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
	Protected Result = #PB_ProcessPureBasicEvents

	Select uMsg
		Case #WM_POWERBROADCAST
			Select wParam
				Case #PBT_APMRESUMEAUTOMATIC  ; Resuming automatically, sent every time the system resumes.
					LogListAdd("Standby: Finished")
				Case #PBT_APMRESUMESUSPEND  ; Resuming, sent after PBT_APMRESUMEAUTOMATIC if the resume is triggered by user (or this timer??)
					LogListAdd("Info: Finished by user input")
				Case #PBT_APMSUSPEND  ; System is suspending (hibernate or standby)
					LogListAdd("Standby: Starting")
					CreateThread(@TimerStart(), 0)
			EndSelect
			Result = #True
	EndSelect

	ProcedureReturn Result
EndProcedure

Procedure Suspend(Hibernate, ForceCritical=#False, DisableWakeEvent=#False)
	Protected LibraryID
	Protected Result = #False

	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "SetSuspendState", Hibernate, ForceCritical, DisableWakeEvent)
		CloseLibrary(LibraryID)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure SuspendAllowed()
	Protected LibraryID
	Protected Result = #False

	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "IsPwrSuspendAllowed")
		CloseLibrary(LibraryID)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure HibernateAllowed()
	Protected LibraryID
	Protected Result = #False

	LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
	If LibraryID
		Result = CallFunction(LibraryID, "IsPwrHibernateAllowed")
		CloseLibrary(LibraryID)
	EndIf

	ProcedureReturn Result
EndProcedure



If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 300, 170, Title, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_Invisible)

	TextGadget(#Text, 10, 10, 280, 70, "Timer should start automatically (for 1 minute) when clicking on these buttons or the system's " + #DQUOTE$ + "standby" + #DQUOTE$ + " button." + #CRLF$ + #CRLF$ + "Info: Close this to create the logfile.")
	ButtonGadget(#ButtonSleep, 10, 90, 280, 30, "Sleep")
	ButtonGadget(#ButtonHibernate, 10, 130, 280, 30, "Hibernate")

	If SuspendAllowed() = #False : DisableGadget(#ButtonSleep, #True) : EndIf
	If HibernateAllowed() = #False : DisableGadget(#ButtonHibernate, #True) : EndIf

	SetWindowCallback(@WindowCallback())

	HideWindow(#Window, #False)

	LogListAdd("Program: Started")


	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Gadget
				Select EventGadget()
					Case #ButtonSleep
						LogListAdd("Standby: Activate sleeping via button")
						CreateThread(@TimerStart(), 0)
						Suspend(#False)
					Case #ButtonHibernate
						LogListAdd("Standby: Activate hibernating via button")
						CreateThread(@TimerStart(), 0)
						Suspend(#True)
				EndSelect
			Case #PB_Event_CloseWindow
				LogListAdd("Program: Closed")
				LogListSave(Logfile) ;: RunProgram(Logfile)
				Break
		EndSelect
	ForEver
EndIf
Nicht wundern, es gibt kein visuelles Feedback. Man muss in die beim schließen des Programms erstellte Logdatei schauen, um zu sehen um alles funktioniert hat.


Der Vollständigkeit halber hier ein paar Logs...

Vista/XP -> Standby im Startmenü:
12:40:53 Program: Started
12:41:00 Standby: Starting
12:41:00 Timer: Created
12:41:00 Timer: Started
12:42:01 Timer: Finished successfully
12:42:01 Standby: Finished
12:42:05 Info: Finished by user input
12:42:28 Program: Closed
Vista -> Standby im Startmenü mit Hochfahren des Rechners bevor der Timer abgelaufen ist:
12:44:37 Program: Started
12:45:01 Standby: Starting
12:45:01 Timer: Created
12:45:01 Timer: Started
12:45:21 Standby: Finished
12:45:24 Info: Finished by user input
12:46:01 Timer: Finished successfully
12:46:33 Program: Closed
Vista -> Hibernate im Startmenü:
12:47:44 Program: Started
12:48:05 Standby: Starting
12:48:05 Timer: Created
12:48:05 Timer: Started
12:49:46 Timer: Finished successfully
12:49:47 Info: Finished by user input
12:49:47 Standby: Finished
12:50:20 Program: Closed
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
Rudi
Beiträge: 143
Registriert: 22.04.2010 18:28
Wohnort: #PB_Any

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von Rudi »

Im Standby-Modus funktioniert der Code bei mir. Aus dem Ruhezustand wird der Rechner aber nicht mehr aufgeweckt - das hat allerdings auch noch kein anderes Tool geschafft.
Ich arbeite mit einem Dell-Notebook.
Log-Datei hat geschrieben:22:09:40 Program: Started
22:09:58 Standby: Activate hibernating via button
22:09:58 Timer: Created
22:09:58 Timer: Started
22:09:59 Standby: Starting
22:09:59 Timer: Created
22:09:59 Timer: Started
22:21:25 Timer: Finished successfully
22:21:28 Standby: Finished
22:21:28 Info: Finished by user input
22:21:43 Program: Closed
Win7 (x64)PB 5.4x (x86)5,7 Windows-LeistungsindexSuche
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von c4s »

Wie ich gerade sehe wird beim Drücken auf einer der Buttons der Timer anscheinend zweimal ausgelöst. Eventuell liegt es daran? Zeile 202 und 206 auskommentieren sollte dies beheben.
Am wichtigsten ist mir sowieso, dass #PBT_APMSUSPEND empfangen wird, um den Timer automatisch zu starten, wenn z.B. im Startmenü auf Standby gedrückt wurde.

Hast du den Rechner aus dem Ruhezustand selber wieder gestartet? Nach 1,26 Min.?
22:09:59 Timer: Started
22:21:25 Timer: Finished successfully
Ich empfehle mal 2 Minuten zu warten, denn der Timer beachtet nicht die Zeit, die der Rechner zum Herunterfahren braucht. Beim Ruhezustand dauert das nämlich immer etwas länger, weil der komplette Arbeitsspeicher erst auf Festplatte gesichert werden muss.
In meinem entsprechenden Log kannst du sehen, dass es hier ungefähr 40 Sekunden länger gedauert hat:
12:48:05 Timer: Started
12:49:46 Timer: Finished successfully
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
Macros
Beiträge: 1361
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von Macros »

Vielen Dank c4s, den Code kann ich gut brauchen.
Normale Wecker wecken mich oft nicht, drum hab ich mir selbst was programmiert ;)
Dafür die ganze Nacht den PC laufen zu lassen ist blöd, drum kommt der Code gerade recht.

Ich werd mich morgen oder übermorgen mal auf die Suche für eine Linux Lösung machen,
das läuft bei mir öfter als Windows.

Edit:
Das ist so einfach, da braucht es keinen Code:
rtcwake -m mem -s 30 = Standby für 30 Sekunden
rtcwake -m mem -t {Unixtime} = Aufwachen wenn Zeit ist gleich {Unixtime}
Kleiner Hinweis: Date gibt eine Unixzeit zurück
was man nach -m angeben kann lest am besten in den manpages eurer Distribution.
Unter Kubuntu ist das Programm standartmäßig installiert. Man benötigt root Rechte zum ausführen.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Timer + autom. Aufwecken des PCs, wenn im Ruhezustand ?

Beitrag von NicTheQuick »

Ich frage mich gerade wie das mit dem Aufwecken aus dem Ruhezustand funktionieren soll. Weil da ist der Rechner ja aus. Da kann man den Akku heraus nehmen und den Stecker ziehen ohne dass Daten verloren gehen. Eigentlich kann nur das BIOS sowas. Also im absolut ausgeschalteten Zustand den Rechner um eine bestimmte Uhrzeit wieder hochfahren.
Antworten