While Schleifen

  • Moinsen,
    fühle mich wie ein Dummkopf weil ichs inwie nicht hinbekomme:
    In meinen Skript:

    Spoiler anzeigen
    [autoit]

    $Stunde = 10
    $Minute = 25
    $Sekunde = 30
    $neu = $minute -1
    While 1
    If @Hour = $Stunde And @Min = $Neu And @SEC = $Sekunde Then
    $msgbox = msgbox(1,"Achtung!","Soll der PC wirklich herunterfahren?",30)
    If $msgbox = 1 then
    Sleep(500)
    ContinueLoop
    ElseIf $msgbox = 2 Then
    ExitLoop
    Exit
    ElseIf $msgbox = -1 Then
    ExitLoop
    Sleep(500)
    EndIf
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    If @hour = $Stunde and @Min = $Minute and @SEC = $Sekunde Then
    ;~ Shutdown(1)
    MsgBox(0,"","asd")
    If @error Then
    ConsoleWrite("Error")
    Sleep(60000)
    MsgBox(16,"Error","Die Angegebene Uhrzeit weißt einen Fehler auf!",20)
    _Exit()
    EndIf
    EndIf
    WEnd

    [/autoit]


    geht immer nur eine schleife, ich möchte aber das die erste schleife fragt ob der pc herunterfahren soll, wenn ja gedrückt wird dann soll das skript weiter laufen und in der 2ten while sollte er dann herunterfahren, es funzt aber nicht ._.

    Es gibt 102
    Arten von Menschen:
    Jene, die Binärcode verstehen
    und jene, die es nicht tun.

    Einmal editiert, zuletzt von Darnas (18. März 2015 um 11:37)

  • Ähm du bekommt doch den Fehler ausgegeben:

    Zitat

    "C:\Users\foka0001\Desktop\AutoIt v3 Script (neu) (2).au3" (8) : ==> Variable used without being declared.:
    If $msgbox = 1 Then
    If ^ ERROR

    Die Variable für die Messagebox heißt bei dir nicht $msgbox sondern $norm. Der Rest geht Problemlos.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • ähm hatte ich vergessen vorm posten zu ändern :D
    also wenn üvberall die variable $msgbox wäre geht das bei mir immernoch nicht ..
    es kommt auch keine fehlermeldung es läuft einfach unendlich lange weiter

    Es gibt 102
    Arten von Menschen:
    Jene, die Binärcode verstehen
    und jene, die es nicht tun.

  • Wenn du OK drückst in deiner MsgBox wird eine 1 zurück gegeben. Sprich ist dann klar, dass es weiter läuft weil du bei der Prüfung auf 1 die Schleife ja nicht verlässt.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Also, ich schildere mal meine Gedanken dabei :D
    Mein Ziel dabei ist ja, das zu der Uhrzeit $Stunde $minute $Sekunde der PC herunterfährt
    ich möchte das eine Minute bevor der PC herunterfährt noch eine abfrage kommt in der gefragt wird ob der PC wirklich herunterfahren soll - falls ihn noch jemand bedient.
    Wenn er herunterfahren soll oder die msgbox einen Timeout bekommt weil niemand mehr an dem PC ist soll er herunterfahren und die andere While weiterlaufen sodass nach der genannten Minute der Rechner aus geht.
    Falls gesagt wird der Rechner soll nicht herunterfahren soll das Skript beendet werden - wie hier durch den Continue Loop
    Jetzt ist aber das Problem bei mir, dass wenn ich sage ja - herunterfahren - das der PC nicht herunterfährt bzw momentan die msgbox(0,"","asd") kommt statdessen passiert garnichts und das skript läuft bis zum tag des Jüngsten gerichts ^^
    Das die Obere Schleife durch den Continue Loop nicht beendet wird ist ja auch weiter nicht schlimm, schließlich sollte der Rechner ja auch herunterfahren

    Es gibt 102
    Arten von Menschen:
    Jene, die Binärcode verstehen
    und jene, die es nicht tun.

  • Dann vergiss die erste Schleife mit der Zeitabfrage und richte stattdessen in der Windows-Aufgabenplanung (Task Sheduler) dein Programm zur entsprechenden Zeit ein.
    Das besteht dann nur noch aus der 1-Minute-Abfrage und gegebenenfalls Herunterfahren.

    Das ist deutlich besser als das Skript die ganze Zeit laufen zu lassen. Was passiert z.B. wenn der Nutzer mal rebootet - dann ist das Skript auch wieder geschlossen.
    Mit dem Task-Sheduler ist es deutlich sicherer und ressourcenschonender.

  • Das Skript kommt später in den autostart :D der user kann so oft rebooten wie er lustig ist :D
    @AspirinJunke mag zwar sein, aber ich bin ja anfänger und würde gerne ein wenig lernen und ich bin mir ziemlich sicher das man das auch gut lösen kann ^^

    Es gibt 102
    Arten von Menschen:
    Jene, die Binärcode verstehen
    und jene, die es nicht tun.

  • und ich bin mir ziemlich sicher das man das auch gut lösen kann

    Das Skript in einer Dauerschleife die Uhrzeit abfragen zu lassen ist aber keine gute Lösung.
    Eine gute Lösung ist Event-basiert.
    Wenn dein Skript beendet wird (z.B. durch einen Fehler oder dem Nutzer selber) kann es so oft im Autostart stehen wie es will - da kommt einfach keine Meldung mehr.

    Warum willst du überhaupt alle 500ms die Zeit abfragen?
    Du weißt doch wie lange es noch bis zum Auslösen dauert - warte einfach solange:

    Spoiler anzeigen
    [autoit]

    #include <Date.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $Stunde = 9
    $Minute = 21
    $Sekunde = 20

    [/autoit] [autoit][/autoit] [autoit]

    ; Wieviel Sekunden sind es noch bis zur angegebenen Uhrzeit?
    Global $d_DiffSeconds = _DateDiff('s', _NowCalc(), StringFormat("%4d/%02d/%02d %02d:%02d:02d", @YEAR, @MON, @MDAY, $Stunde, $Minute -1, $Sekunde))

    [/autoit] [autoit][/autoit] [autoit]

    ; Solange warten
    Sleep($d_DiffSeconds * 1000)

    [/autoit] [autoit][/autoit] [autoit]

    If MsgBox(36, "Runterfahren", "Runterfahren?", 60) = 6 Then
    Shutdown(1+4+8+16)
    Else
    Exit
    EndIf

    [/autoit]
  • Auf die Idee hätte ich auch kommen können :D naja aber mit StringFormat usw kenne ich moch so gut wie gar nicht aus :D
    jetzt besteht immernoch ein Problem: Meine Funktion läuft soweit - gut - aber wenn die msgbox kommt die abfragt ob heruntergefahren werden soll und diese bestätigt wird, möchte ich das erst um $Stunde $sekunde $min heruntergefahren wird und nicht direkt, vllt muss man ja noch programme schließen etc, ich habe erstmal einene sleep von 60sek eingebaut.
    du hast zwar die 60sek als msgbox timeout angegeben aber man kann sie ja auch vorher betätigen :D
    aufjeden dickes danke von mir :D denke das ich das selber hinbekomme :D

    €dit: Noch ein fehler im system :D wenn die niemand am rechner ist und die box ausläuft, sollte der PC auch herunterfahren. :D

    Es gibt 102
    Arten von Menschen:
    Jene, die Binärcode verstehen
    und jene, die es nicht tun.

    Einmal editiert, zuletzt von Darnas (19. März 2015 um 10:08)

  • [autoit]

    #include <Date.au3>

    [/autoit][autoit][/autoit][autoit]

    Global $Stunde = 10, $Minute = 38, $Sekunde = 20

    [/autoit][autoit][/autoit][autoit]

    ; Wieviel Sekunden sind es noch bis zur angegebenen Uhrzeit?
    Global $d_DiffSeconds = _DateDiff('s', _NowCalc(), StringFormat("%4d/%02d/%02d %02d:%02d:02d", @YEAR, @MON, @MDAY, $Stunde, $Minute -1, $Sekunde))

    [/autoit][autoit][/autoit][autoit]

    ; Solange warten
    Sleep($d_DiffSeconds * 1000)

    [/autoit][autoit][/autoit][autoit]

    $iT = TimerInit()
    $d_MsgReturn = MsgBox(36, "Runterfahren", "Runterfahren?", 60)
    If $d_MsgReturn = 6 Then Sleep(6e4 - TimerDiff($iT)) ; Falls ja gedrückt wurde - bis zu den vollen 60s warten
    If $d_MsgReturn = 6 Or $d_MsgReturn = -1 Then Shutdown(1+4+8+16)
    Exit

    [/autoit]
  • Habs schon selber gemacht, finde meins für mich selber schöner :D
    trd danke danke :D

    hier meine lösung( sind ziemlich ähnlich):

    [autoit]


    Global $d_DiffSeconds = _DateDiff('s', _NowCalc(), StringFormat("%4d/%02d/%02d %02d:%02d:02d", @YEAR, @MON, @MDAY, $Stunde, $Minute -1 , $Sekunde))
    Global $d_DiffSeconds2 = _DateDiff('s', _NowCalc(), StringFormat("%4d/%02d/%02d %02d:%02d:02d", @YEAR, @MON, @MDAY, $Stunde, $Minute, $Sekunde))

    [/autoit][autoit][/autoit][autoit]

    Sleep($d_DiffSeconds * 1000)
    $chk = MsgBox(36, "Runterfahren", "Runterfahren?", 30)
    If $chk = 6 or $chk = -1 Then
    Sleep($d_DiffSeconds2 * 1000)
    Shutdown(1+4+8+16)
    Else
    Exit
    EndIf

    [/autoit]

    Es gibt 102
    Arten von Menschen:
    Jene, die Binärcode verstehen
    und jene, die es nicht tun.

  • Dann wartet er aber nicht nur 60s sondern nochmal so lange + 60s.
    Das ist irgendwie nicht das was du wolltest...

    Wenn es dir kürzer gefällt kannst du es auch so schreiben:

    [autoit]

    #include <Date.au3>

    [/autoit][autoit][/autoit][autoit]

    Global $Stunde = 10, $Minute = 38, $Sekunde = 20

    [/autoit][autoit][/autoit][autoit]

    ; Wieviel Sekunden sind es noch bis zur angegebenen Uhrzeit?
    Global $d_DiffSeconds = _DateDiff('s', _NowCalc(), StringFormat("%4d/%02d/%02d %02d:%02d:02d", @YEAR, @MON, @MDAY, $Stunde, $Minute - 1, $Sekunde))

    [/autoit][autoit][/autoit][autoit]

    ; Solange warten
    Sleep($d_DiffSeconds * 1000)

    [/autoit][autoit][/autoit][autoit]

    $iT = TimerInit()
    If MsgBox(36, "Runterfahren", "Runterfahren?", 60) = 7 Then Exit
    Sleep(6e4 - TimerDiff($iT)) ; bis zu den vollen 60s warten
    Shutdown(1 + 4 + 8 + 16)

    [/autoit]
  • Kann sein das ich mich grade verschaut habe, aber bei meinen test war das skript bis auf die sekunde genau.^^
    naja ob der PC eine min oder 2min nach der meldung runterfährt is letzten endes egal , der user weiß er fährt runter :D
    der nächste step wäre jetzt n tray icon zu machen :D aber das mache ich später

    Es gibt 102
    Arten von Menschen:
    Jene, die Binärcode verstehen
    und jene, die es nicht tun.

  • naja ob der PC eine min oder 2min nach der meldung runterfährt is letzten endes egal , der user weiß er fährt runter

    Es geht nicht nur um zwei Minuten.
    Bei deinem Skript verhält es sich so: Wenn das Skript früh gestartet wird und es noch 8h bis zum Shutdown sind wartet es 8h bis die Msgbox kommt.
    Wenn der User dann ja drückt (oder auch gar nix macht - worauf ein Warten dann sowieso sinnlos wäre) wartet das Skript nocheinmal 8h + 60s bis es dann endlich runterfährt.

    Gib dir einfach mal den Wert von d_DiffSeconds2 aus - dann siehst du wieviel ms er beim zweiten Sleep noch wartet.

  • Probier es aus, bei mir geht es doch 8o
    €dit: entweder ich habs falsch vertanden oder der sucht doch sowieso nicht nach den wert an stunden oder? :D ansonsten hätte man doch einfach angeben können der sleep soll zb 80000ms gehen oder so, dafür brauchte man kein datum etc

    Es gibt 102
    Arten von Menschen:
    Jene, die Binärcode verstehen
    und jene, die es nicht tun.

  • Es geht nur wenn die Shutdown-Zeit in etwa einer Minute ist.
    Dann ist die zweite Wartezeit auch so lange.

    Wenn ich es ausprobiere ist das Ergebnis wie erwartet:

    • $d_DiffSeconds bekommt in meinem Fall den Wert 6
    • $d_DiffSeconds2 dann logischerweise 66
    • Es dauert tatsächlich 6s bis die Msgbox erscheint
    • Dann warte ich 5s bis ich ja drücke (nun sollte das Skript noch 55s laufen)
    • Es dauert noch 66s ($d_DiffSeconds2) bis das Skript herunterfährt.

    So weit so schlecht.
    Jetzt probiere dein Skript mal aus, wenn der Shutdown-Zeitpunkt erst in einer Stunde kommen soll.
    Viel Spaß beim Warten...

    Edit:

    ansonsten hätte man doch einfach angeben können der sleep soll zb 80000ms gehen oder so, dafür brauchte man kein datum etc

    Deine Aufgabenstellung war das Skript zu einem bestimmten Zeitpunkt herunterfahren zu lassen.
    Wenn du ein Sleep mit einem festen Wert schreibst hat das mit dem Zielzeitpunkt nicht mehr zu tun, da das Ende von der Uhrzeit zum Start der Sleep-Funktion abhängt.

    Einmal editiert, zuletzt von AspirinJunkie (19. März 2015 um 11:37)

  • _DateDiff gibt dir die Differenz zwischen zwei Daten/Uhrzeiten aus... Dadurch das als erster Parameter 's' übergeben wird, wird die Differenz in Sekunden übergeben.
    Nun wird die dort gegebene Sekudnenzahl gewartet. Dein zweiter berechneter Wert liegt bei der selben Zeit -1Minute, wie du oben angegeben hast.
    Da es bei dir funktioniert würd ich mal sagen: $Minute ist bei dir exakt 2. Wenn du nämlich 3 einsetzen würdest dauert es nach der MsgBox nämlich noch 2 Minuten ($Minute-1), bis dein PC herunterfährt.