1

Batch Zeiteingabe

Frage von abbrechen abbrechen

Hi,

ich bekomme es einfach nicht hin, eine Zeiteingabe bei Batch zu coden.

Wie ihr wisst, wird wenn man eine Uhrzeit eingibt) z.B. 17:50) und danach shutdown -s -t xx (z.B. -t 60), die shutdown Zeile um 17:50 Uhr gelesen und der Rechner bei -t 60 um 17:51 Uhr heruntergefahren.

Doch wie bekomme ich es hin, dass der Benutzer eine Uhrzeit eingibt und diese dann gelesen wird.

Meine Versuch sieht bisher wie folgt aus:

 

@echo off
echo Wann wollen sie Ihren Rechner herunterfahren lassen?
set /p eingabe= Eingabe:

for /L %%i IN (1 1 %eingabe%)

:%eingabe%
shutdown -s -t 60

pause

Fragen zu gleichen Themen finden

Antworten (1)

  • 3
    Antwort von bendebass bendebass

    Hallo.

    Wenn ich eine Zeit eingebe und dann den shutdown-Befehl, kommt nur eine Fehlermeldung, da er mit der einfachen Angabe der Zeit nichts anfangen kann.

    Die Lösung für dein Problem ist aber trotzdem sehr einfach.

    Der Benutzer gibt einfach eine Uhrzeit an wie z.B: 17:50:00.

    Das ist nun in der Variable "eingabe" gespeichert.

     

    @echo off
    cls
    echo Wann wollen sie Ihren Rechner herunterfahren lassen?
    set /p eingabe= Eingabe:

    Soweit warst du auch schon. Du musst nun nur noch diese Eingabe in einer Schleife mit der momentanen Zeit vergleichen. Wenn sich diese Werte gleichen, dann kannst du wieder aus der Schleife springen und den shutdown-Befehl geben.

     

    Eine kleine Schwierigkeit gibt es hier allerdings doch noch.

    Die Variable %time% enthält zwar immer die momentane Uhrzeit, allerdings leider immer mit den Millisekunden.

    Hier kommt nun ein Trick zum Zug, den ich selbst erst seit kurzem kenne.

    Ich hole mal ein wenig aus, damit es verständlich wird.

    Eine Variable lässt sich sehr einfach beschneiden, indem man hinter dem Variablennamen ":~" und danach 2 Zahlen schreibt. Die erste gibt an wieviele Zeichen am Anfang der Variable weggeschnitten werden sollen. (in unserem Fall 0, sonst wären die Stunden weg) Die zweite Zahl gibt an, wieviel Zeichen die Variable noch insgesamt haben soll. Dabei werden gegebenfalls Zeichen vom hinteren Ende abgeschnitten, bis die Variable die entsprechende Anzahl an Zeichen enthält. Stunden, Minuten, Sekunden und die Zwei Trennungszeichen ergeben bei uns 8 Zeichen die wir haben möchten.

    Daher sieht es dann so aus: %time:~0,8%

    Nun einfach die %eingabe% mit dem %time:0,8% vergleichen und dann bist du schon fertig.

    Hier nochmal der gesamte Code, der auch genau so funktionieren sollte.

     

     

    @echo off
    cls
    echo Wann wollen sie Ihren Rechner herunterfahren lassen?
    set /p eingabe= Eingabe:
    :schleifenstart
    IF %eingabe%==%time:~0,8% goto schleifenende
    goto schleifenstart
    :schleifenende
    shutdown -f -s

    -t 60 hab ich beim shutdown weggelassen, da der PC sonst 1 Minute später runterfahren würde, als der Benutzer es angegeben hatte.

    Wenn du noch Fragen hast, dann frag mich einfach.

    Kommentar von abbrechen abbrechenabbrechen

    Vielen Dank für deinen Tipp, auf die Idee mit der %time~ ..." bin ich gar nicht gekommen.

    Dabei stellt sich nur ein Problem und zwar hatte ich vor per vbs-Datei  das Fenster nach der Eingabe der Uhrzeit zu minimieren. (Ich habe nämlich den Batch Befehl zur Fensterverbergung vergessen)

    Doch friert sich die Batchzeile nach if %eingabe% ... doch ein, wodurch erst ab der Uhrzeit die nächste Zeile gelesen wird und dadurch auch erst das Fenster minimiert wird.

     

    Der Rest meines geplanten Kindersicherungsprogrammes ist soweit ganz einfach.

    Kommentar von bendebass bendebassbendebass

    Kindersicherungsprogramm?

    Hm. So eine Batchdatei lässt sich jedoch äußerst einfach schließen bzw. spätestens durch das Bedienen von [Strg] + C abbrechen.

    Vielleicht solltest du doch auf ein vollwertiges Programm setzen, das speziell für solch ein Zweck gemacht worden ist?

     

    Aber nun gut, das steht ja wahrscheinlich nicht zur Debatte.

    Übrigens, das mit der minimierten Batch, geht meines Erachtens nach nur direkt beim Start der Batch. Nicht aber, mittendrin.

    Man müsste das Menü (also die Zeiteingabe) und die Schleife mit dem shutdown Befehl jeweils in eine eigene Datei stecken.

    Eine Batch kann minimiert gestartet werden in dem man sie mit "start /min" aufruft.

    Hinter den Dateinamen kommen sogenannte Argumente, die der Datei mitgeschickt werden können.

    Zum Beispiel kann der shutdown.exe das Argument "-t 60" mitgegeben werden, damit es weiss, dass es erst nach 60 Sekunden runterfahren soll.

    So ein Argument, kannst du auch selbst erstellen. Logischerweise in unserem Fall ist dies dann die Uhrzeit (%eingabe%), die du der schleife.bat einfach mitschickst.

    So entsteht die Zeile: start /min schleife.bat %eingabe%

    start.bat

     

    @echo off
    cls
    echo Wann wollen sie Ihren Rechner herunterfahren lassen?
    set /p eingabe= Eingabe:
    start /min schleife.bat %eingabe%

    Die mitgegebenen Argumente werden (automatisch) durchnummeriert und in Variablen gesteckt, denen nur ein einzelnes Prozentzeichen vorangeht. Da wir nur ein Argument haben, heisst es bei uns nun "%1"

    schleife.bat

     

    @echo off
    cls
    :schleifenstart
    IF %1==%time:~0,8% goto schleifenende
    goto schleifenstart
    :schleifenende
    shutdown -f -s

    So. Habe es getestet und funktioniert wunderbar. Man könnte meinen, dass die Batch sich selbst minimiert.

    Kommentar von abbrechen abbrechenabbrechen

    Vor weg, die Kindersicherung soll ja nicht einfach eine für mich persönlich sein, dann könnte ich auch eine entsprechende Software benutzen.

    Meine erfüllt ungefähr den selben Zweck, hat aber den Vorteil, dass sie schlichter, aber fast genauso effektiv ist.

     

    Ich habe mir erhofft, dass ich das noch irgendwie in eine Datei packen kann, schade.

    Das Problem ist nicht einmal, dass das Fenster miniert ist, sondern wie ich erwähnt habe, soll die Datei verborgen sein, sprich mittels dieser VBS-Datei wäre sie aus der Taskleiste verschwunden:

    WScript.CreateObject( "WScript.Shell" ).Run "schleife.bat",0,0

    Doch wenn ich die vbs-Datei starte und ihr sage, sie solle die start.bat ausführen, so ist das Fenster nicht mehr für die Einhabe der Uhrzeit sichtbar und vermerke ich in der start.bat, dass die vbs Datei die schleife.bat ausführen soll, so geht die %eingabe% Zeile verloren.

    Da es aber auch ein Kindersicherungsprogramm werden soll und die Eltern sicher nicht die große Lust haben, das immer wieder manuell einzustellen, würde ich die Datei per iexpress im Autostart installieren lassen.

    Das darauf folgende Problem ist widerum: Die Uhrzeit ist einmalig und wird nicht auf Dauer abgespeichert.

    Kommentar von bendebass bendebassbendebass

    Das %eingabe%-Argument ist auch mittels vbs einsetzbar.
     

    echo>openloop.vbs WScript.CreateObject( "WScript.Shell" ).Run "schleife.bat %eingabe%",0,0
    CSCRIPT openloop.vbs
    del /f /q openloop.vbs


    -

    Und das mit dem Wiedereinstellen oder dem Verwenden von einer bereits eingegebenen Uhrzeit ist eigentlich auch gar nicht so schwer.
    Habe das in 3 Zeilen packen können.

    Ich habe hier ein Beispiel, bei dem die einzugebene Uhrzeit in "zeit.txt" gespeichert wird.
    Zuvor wird aber versucht, aus dieser Datei zu lesen, diese dient dann jedes Mal als vorgegebene Standardzeit %eingabe%
    Wird nun hinter "Eingabe[%eingabe%]:" nichts neues eingegeben, dann bleibt der Wert der Variable, den es zuvor hatte, in dem Fall den Wert aus der zeit.txt


    Nun noch nachträglich (falls es doch eine Neueingabe gab) einfach die eingabe in die zeit.txt gespeichert.
    Aussehen tut dies so.

    set /p eingabe=zeit.txt %eingabe%

    Hoffe dies hat nun dein Problem gelöst ;)

    Kommentar von bendebass bendebassbendebass

    Schade, Gutefrage.net kann keine spitze Klammer auf anzeigen :(

    Der letzte Codeblock oben ist also schwachsinnig.

    Also dort wo das Rautezeichen # steht einfach eine offene spitze Klammer einfügen, damit die Daten aus der zeit.txt in die variable eingelesen werden:

    set /p eingabe=#zeit.txt
    set /p eingabe=Eingabe[%eingabe%]:
    echo>zeit.txt %eingabe%

    Kommentar von abbrechen abbrechenabbrechen

    Soweit nicht schlecht, die Dateien werden erstellt, doch "goto" kann syntaktisch an dieser Stelle nicht verarbeitet werden.

    Zu dem wird die Eingabe doppelt abgefragt (, was ersteinmal kein Problem ist.

    Seltsamer ist eher, dass dass {zeit.txt dem Benutzer angezeigt wird.

    Das Ganze sieht bisher wie folgt aus:

     

    start.bat

    @echo off
    cls

    echo Wann wollen sie Ihren Rechner herunterfahren lassen? (hh:mm:ss)
    set /p eingabe= {zeit.txt
    set /p eingabe= Eingabe[%eingabe%]:
    echo>zeit.txt %eingabe%

     

    schleife.bat

    @echo off
    cls

    echo>openloop.vbs WScript.CreateObject( "WScript.Shell" ).Run "schleife.bat",0,0
    start openloop.vbs
    :schleifenstart
    IF %1==%time:~0,8% goto schleifenende
    goto schleifenstart
    :schleifenende
    shutdown -f -s -t 60

    CSCRIPT openloop.vbs
    del/f /q openloop.vbs

     

    openloop.vbs

    WScript.CreateObject( "WScript.Shell" ).Run "schleife.bat",0,0

    Kommentar von bendebass bendebassbendebass

    Nee. Wieso sollte goto syntaktisch nicht verarbeitbar sein?

    Aber, da hast du jetzt ein paar Sachen durcheinander gebracht.

    mit der spitzen Klammer meine ich nicht { sondern das Pfeilartige Ding neben der Y-Taste, dann sollte {zeit.txt dem Benutzer auch nicht mehr angezeigt werden.

    Ausserdem: die Zeile

    echo>openloop.vbs WScript.CreateObject( "WScript.Shell" ).Run "schleife.bat",0,0

    kommt in die start.bat, denn diese startet doch die schleife.bat, deswegen macht sie innerhalb der schleife.bat selbst kein Sinn.

    (zudem ist hier das %eingabe% nach Run"schleife.bat" nicht drin, das ist wichtig, sonst kann die schleife.bat mit dem %1 nichts anfangen!)

    zudem hast du mit openloop.vbs und mit CSCRIPT openloop.vbs

    die schleife.bat gleich zweimal geöffnet. Das würde sich unter Umständen so oft wiederholen bis der PC abstürzt.

     

    -

    Hier nochmal die Dateien, wie sie aussehen sollten.

    start.bat

    @echo off
    cls
    echo Wann wollen sie Ihren Rechner herunterfahren lassen? (hh:mm:ss)
    set /p eingabe=#zeit.txt
    set /p eingabe=Eingabe[%eingabe%]:
    echo>zeit.txt %eingabe%
    echo>openloop.vbs WScript.CreateObject( "WScript.Shell" ).Run "schleife.bat %eingabe%",0,0
    CSCRIPT openloop.vbs
    del /f /q openloop.vbs

     

    schleife.bat

    @echo off
    cls
    :schleifenstart
    IF %1==%time:~0,8% goto schleifenende
    goto schleifenstart
    :schleifenende
    shutdown -s -t 60

    Kommentar von abbrechen abbrechenabbrechen

    Die 9. Zeile der start.bat ("schleife.bat %eingabe%",0,0) musste ich in die 8. Zeile zu .Run schreiben, da ich ansonsten folgende Fehlermeldung bekomme:

    Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch.

    C:\Users\[Benutzername]\Desktop\openloop.vbs(1, 1) Laufzeitfehler in Microsoft VBScript: Falsche anzahl an Argumenten oder ungültige Eigenschaftszuweisung: 'WScript.CreateObject(...).Run'

    Und so war es auch beim Syntaxfehler.

    So, damit wäre das Rätsel gelöst, doch eines hat nicht funktioniert und zwar wollte ich mit iexpress eine exe-Datei erstellen, die die Auslösedatei für zeit.txt automatisch startet, damit bei jedem Systemstart der Rechner entsprechend der eingestllten Uhrzeit herunterfährt.

    Doch aus irgendeinem Grund bekomme ich folgende Fehlermeldung: Unable to end update of resources

    Und die exe-Datei schafft es nicht die Datei zu dekomprimieren, sodass ich den Vorgang abbrechen musste.

    mein Versuch, eine Auslöserdatei zu erstellen endete zu dem in folgendem Versuch: shutdown -s -t zeit.txt

    Denn hätte ich einen echo Befehl benutzt, wäre es nur ausgerufen worden und eine Klammer hätte es nur in eine Datei geschrieben.

    Kommentar von bendebass bendebassbendebass

    OK.

    Also Autostart würde ich per Registrierung machen, dann benötigt man keine iexpress. Denn damit erstellt man eigentlich Installationsarchive, ist also wesentlich komplizierter als es sein müsste. Zudem hat man das Problem mit der Dekomprimierung nicht mehr.

    Ich denke wir müssen unter diesem Umstand das Projekt doch in 3 anstatt nur 2 Dateien aufteilen. Einmal die Eingabe der Uhrzeit bzw. das Einstellen des Autostarts(einstellungen.bat), einmal die schleife mit dem Shutdown-Befehl (schleife.bat) und einmal der Eintrag aus dem Autostart selbst, der die schleife mit dem vbs-skript versteckt startet (start.bat)

    So können wir die ständige Abfrage nach der Uhrzeit umgehen, aber trotzdem lässt sie sich auf Wunsch einstellen.

    Zu guter Letzt ist es etwas unschön die gespeicherte Zeit in eine Datei namens zeit.txt unterzubringen. Das würde ich ebenso in die Registry stecken. Somit muss auch kein Argument mehr übermittelt werden. Das sollte daher erstens einfacher und zweitens besser geschützt gegen ungewollte Eingriffe in die zeit.txt werden.

    Das ist jetzt allerdings ein etwas größeres Unterfangen. Vorallem das mit der Registrierung ist etwas schwerer. Ich werde mich mal daran setzen und etwas zusammen basteln.

    Kommentar von abbrechen abbrechenabbrechen

    Ok, vielen Dank. =)

    Kommentar von bendebass bendebassbendebass

    Ich hab es noch nicht vergessen. ;)

    Ich bin schon recht weit. Momentan bin ich nur leider auf ein Problem gestossen.

    Zum Systemstart soll die vbs ausgeführt werden, die unsere Batch versteckt starten soll. Jedoch benötigt Windows zur Ausführung dieser vbs den Windows Script Host. Dieser allerdings scheint erst später zu starten, sodass die vbs nicht direkt nach dem Systemstart ausgeführt werden kann. Sehr merkwürdig, leider. Ich habe diesbezüglich auch schon selber eine Frage hier auf GF gestellt.

    Momentan aber bin ich bei der Überlegung ob es denn sinnvoll wäre eine Art "Zeitzünder" einzubauen, sodass die vbs erst später gestartet wird. Doof ist dabei aber nur, dass während die Zeitschleife abläuft die Eingabeaufforderung zu sehen ist.

    Da nicht jeder PC gleich schnell ist, kann es schon nerven wenn dann also noch eine Minute lang die cmd zu sehen ist. Sollte man daher besser eine Abfrage machen, wann die Kindersicherung gestartet werden soll? Was denkst du denn dazu?

    Meine bisherige Lösuingsidee sieht so aus. Damit dass Kind also nicht einfach die Batch zumachen kann, sondern diese Bestätigen muss, sollte also erreicht werden, dass die Batch nicht zu schliessen geht. Hierfür habe ich ein Programm gefunden: http://masterbootrecord.de/docs/dontcloseme.php

    Das Kind könnte allerdings auch einfach die Batch nicht bestätigen und somit die Kindersicherung umgehen. Daher könnte man diese Abfragebatch evtl. nach 5 Minuten den PC automatisch herunterfahren lassen, es sei denn sie wird also bestätigt..

    Was hältst du von dieser Idee? Oder gibt es eventuell noch einen anderen Lösungsansatz? Sehr elegant finde ich das nämlich nicht. Zumal man trotz der DontCloseMe.exe die Batch einfach per Strg+C abbrechen könnte ;(

    Kommentar von abbrechen abbrechenabbrechen

    Was mir dazu einfällt ist der /min Befehl, der die cmd exe in der Taskleiste anzeigt, doch in Verbindung mit der dontcloseme.exe sollte sie dann nicht so einfach zu schließen sein.

    Sicher, über einen weiteren taskkill Befehl in einer seperaten cmd.exe oder den Taskmanager ist im Zeitraum der Fensterminimierung die Kindersicherung zu schließen, aber viele Möglichkeiten gibt es nicht. Evtl. den, dass man der ausgeführten Datei einen anderen Titel gibt, sodass das Kind nicht weiss, wie die Datei heißt, um dann den Befehl einzusetzen. Ich google mal, wie man eine Datei im Taskmanager verbergen kann (Prozesse-Option ausgeschlossen).

    Kommentar von bendebass bendebassbendebass

    Alles zurück.

    Meine Fragestellung bezüglich des verspäteten Windows Script Hosts hat sich geklärt.

    Leider nicht hier auf gutefrage.net, dafür aber auf Stackoverflow.com

    Das Problem ist nämlich nicht der WSH. Dieser ist nämlich kein Dienst der gestartet wird, sondern ein einfaches Programm das im Systemordner liegt und automatisch per Programmverknüpfung gestartet wird sobald eine vbs geöffnet wird.

    Das die start.vbs und die schleife.bat im selben Ordner liegen ist klar.Wenn man die start.vbs manuell startet, dann weiss sie auch automatisch wo die schleife.bat liegt. Nicht so wenn man diese von der Registrierung aus startet, dann muss man zwingend den gesamten Pfad mit angeben. Und das ist schon die Lösung des gesamten verflixten Problems gewesen ...

    Somit funktioniert mein System doch noch. Wir brauchen keinen Windowsdienst, keinen Zeitzünder und auch kein Dontcloseme.

    Hier mal eine Zusammenfassung was ich nun alles getan habe.

    Es gibt 3 Dateien.

    Eine einstellungen.bat in der man Einstellungen vornimmt. Also der Autostart, der Shutdownzeitpunkt wird hier eingestellt. Da das Programm auch diese Daten in der Registrierung speichert habe ich zur Reinigung auch eine Deinstallationsroutine eingebaut.

    Eine schleife.bat, die die momentane Uhrzeit mit der Uhrzeit, die in der Registrierung gespeichert ist abgleicht. Wenn sie gleich sind, dann wird der Shutdown Befehl gegeben.

    Die letzte Datei sskss.vbs beinhaltet einfach den Startbefehl der schleife.bat, damit diese unsichtbar ist.

    Zur Kennzeichnung habe ich das Programm nun einfach mal "Kss" genannt.Überall wo Kss steht, kommt der eigentliche Programmname hin.

    Die einzelnen Dateien mögen etwas wirr wirken, sollten jedoch recht gut funktionieren und sind sogar schon Endnutzerfähig.

    Mir fiel dabei nur leider auf, als ich es per Task Manager schliessen musste, dass die schleife.bat während der Vergleichsroutine nahezu 20% der gesamten CPU Auslastung frisst. Hier ist wiedermal der Beweis dafür, dass Batch einfach nicht geeignet ist um komplexere Programme zu schreiben. Vielleicht wäre es doch besser eine andere Programmiersprache zu nutzen. Denn immerhin ist dies so nicht mehr schlicht und effektiv, was ja deine Hauptgründe waren solche ein Kindersicherungsprogramm in Batch zu schreiben. Dennoch habe ich das Programm zuende geschrieben.

    Ich werde die Dateien hier jetzt nicht darstellen können, da es von gutefrage den Rahmen sprengen würde. Und nun muss ich dir die Dateien per Email zusenden.Und ich werde sie hier auch nicht weiter erklären obwohl ich sehr viel daran verändert habe und einige weitere Funktionen eingebaut habe.

    Du solltest dir erstmal alles genau ansehen und bei Fragen mich nochmal anfragen. Das ist wohl der einfachere Weg.

    Damit wir unsere Emailaddressen austauschen können ohne sie hier zu veröffentlichen habe ich dir eine Freundschaftsanfrage geschickt.

    PS: Sollte sich das Programm irgendwann trotz der extremen CPU-Auslastung verkaufen, werde ich doch auch mein Anteil bekommen, oder ;)

Diese Frage

Verwandte Fragen

Noch nicht den richtigen Rat gefunden?

Einfach und schnell viele hilfreiche Ratschläge von Deutschlands aktivster Ratgeber-Community erhalten!

Einfach und schnell einen Tipp erstellen und Ihren guten Rat mit anderen teilen!

Einfach und schnell ein Video hochladen und anschaulichen Rat an alle geben!

Die unter gutefrage.net angebotenen Dienste und Ratgeber Inhalte werden nicht geprüft. Die Richtigkeit der Inhalte wird nicht gewährleistet. Rechtliche Hinweise finden Sie hier.