PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Skript funktioniert nach Mitternacht nicht mehr?


Geldmann3
2022-04-24, 00:57:35
Habe gestern mithilfe von nircmd (https://www.nirsoft.net/utils/nircmd.html) und Image Magick (https://imagemagick.org/index.php) ein Skript geschrieben, welches alle 5 Minuten einen Screenshot anfertigt und diesen resized und in einen Ordner in meinem Google Drive schiebt.

Das Skript lief für 40 Minuten ohne Probleme, dann war 0 Uhr und ab genau 0 Uhr funktionierte es nicht mehr??

:loop
nircmd.exe savescreenshot screenhot.png
echo "Current time: "%time%
md %date:~6,4%\%date:~3,2%\%date:~0,2%\Computerbildschirm
timeout /T 1
magick convert screenhot.png -resize 640x360 %date:~6,4%/%date:~3,2%/%date:~0,2%/Computerbildschirm/%time:~-11,2%Uhr-%time:~-8,2%Minuten-%time:~-5,2%Sekunden.png
timeout 299
goto loop
test.txt wird noch angelegt, folglich wurde der Ordner erfolgreich erstellt.

Doch convert gibt zurück:
C:\AutoImage>magick convert screenhot.png -resize 640x360 2022/04/24/Computerbildschirm/ 1Uhr-03Minuten-15Sekunden.png
convert: unable to open image '2022/04/24/Computerbildschirm/': Permission denied @ error/blob.c/OpenBlob/3529.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/737.

Das fertige Bild landet darauf nicht mehr im zusammengebauten Pfad, sondern im selben Pfad der nircmd exe, aus dem ich das Skript ausführe.
Was ist hier um 0 Uhr passiert?

Zuerst dachte ich, es wäre eine Rechte Sache, dass das Google Drive hier vielleicht hineinfunkt, doch es funktioniert auch nicht, wenn ich als Zielordner einfach ,,%date:~6,4%/%date:~3,2%/%date:~0,2%/Computerbildschirm/" nehme.

Monger
2022-04-24, 01:11:00
Keine Ahnung warum das Skript irgendwann stoppt, aber so extrem langlebige Prozesse haben so ihre Tücken. Empfehle dir eher nen Scheduled Task zu machen der dein Skript aufruft, dann kannst du dir die Schleife sparen, und kriegst die Fehlerbehandlung geschenkt.

myMind
2022-04-24, 01:11:23
Besser das Datum am Anfang des Loops einmal in einer Variablen speichern und dann mit dem Festen Wert arbeiten.

%date% ist eine Funktion. Der Wert kann sich von einer Zeile auf die andere Ändern. Z.B. zwischen md und echo test >... und dann legst Du ggf. 2022/04/23 an und willst nach 2022/04/24 schreiben.

Geldmann3
2022-04-24, 01:17:16
Keine Ahnung warum das Skript irgendwann stoppt, aber so extrem langlebige Prozesse haben so ihre Tücken. Empfehle dir eher nen Scheduled Task zu machen der dein Skript aufruft, dann kannst du dir die Schleife sparen, und kriegst die Fehlerbehandlung geschenkt.

Oh, das ist eine gute Idee, würde ich angehen, wenn ich es als Batch laufen habe.

Besser das Datum am Anfang des Loops einmal in einer Variablen speichern und dann mit dem Festen Wert arbeiten.

%date% ist eine Funktion. Der Wert kann sich von einer Zeile auf die andere Ändern. Z.B. zwischen md und echo test >... und dann legst Du ggf. 2022/04/23 an und willst nach 2022/04/24 schreiben.

Stimme zu, ist dann auch besser lesbar.

registrierter Gast
2022-04-24, 01:32:44
Kommt dein Skript nicht mit einstelligen Stunden zurecht? Es schneidet die Stunde trotzdem zweistellig aus, weswegen da ein Leerzeichen in den Pfad kommt, welches nicht da sein sollte. Als Folge davon kann das Skript nicht auf die Datei zugreifen.

Probiere es ab 10 Uhr nochmal. :D

Geldmann3
2022-04-24, 01:34:44
Kommt dein Skript nicht mit einstelligen Stunden zurecht? Es schneidet die Stunde trotzdem zweistellig aus, weswegen da ein Leerzeichen in den Pfad kommt, der nicht da sein sollte. Als Folge davon, kann das Skript nicht auf die Datei zugreifen.

Probiere es ab 10 Uhr nochmal. :D

Jaaa! Wenn ich echo %time% ausgebe, bekomme ich eine Zeile, mit einem Leerzeichen am Anfang. :eek: Wer macht denn sowas.;D
Probleme wird es übrigens auch bei unterschiedlichen Spracheinstellungen machen.
Doch mir fällt in CMD keine einfache Lösung dafür ein.

Gibt es nicht irgendwie eine cleane Methode sich die Zeit zu holen, ohne am String herumzudoktoren?

So geht es:
:loop
set stunde=%time:~-11,2%
set stunde=%stunde: =%
echo %stunde%
nircmd.exe savescreenshot screenhot.png
md %date:~6,4%\%date:~3,2%\%date:~0,2%\Computerbildschirm
timeout /T 1
magick convert screenhot.png -resize 640x360 %date:~6,4%/%date:~3,2%/%date:~0,2%/Computerbildschirm/%stunde%Uhr-%time:~-8,2%Minuten-%time:~-5,2%Sekunden.png
timeout 299
goto loop

Darkman.X
2022-04-24, 05:53:30
Das ist doch schon clean. Batch ist halt keine Programmiersprache, aber selbst wenn, dann muss man halt Strings so umbauen wie sie benötigt.

Außerdem von "clean" bei deiner Batch zu reden ist schon leicht ironisch. Alle 5min wird dein "md"-Befehl auf Fehler laufen, weil das Verzeichnis außer beim 1. Durchgang schon existiert. Ist nicht schlimm, aber das ist (für mich) dann nicht mehr "clean" oder "schön", sondern eher zweckmäßig ;)

Und den Hinweis von "myMind" hast du leider auch nicht umgesetzt. Zugegeben, zu dem erwähnten Fehler wird es eher selten kommen, aber es kann dazu kommen.

Monger
2022-04-24, 08:22:21
Auch wenn ich damit leicht ins offtopic rutsche: wer unter Windows Batch Skripte schreibt, sollte mMn sich unbedingt mal Powershell anschauen. Ist ja im Grunde der Nachfolger, nur halt 20 Jahre weiter. Dank Debugger und gescheiter Typisierung passiert sowas dort dann nicht bzw. ist in nullkomma nix gelöst.

Geldmann3
2022-04-24, 10:36:39
Wollte den Vorschlag von myMind heute Nacht ja umsetzen, doch es war schon spät.

Hier nochmal mit fixem Datum.

@echo off
:loop
echo Entferne Leerzeichen aus Stunde
set stunde=%time:~-11,2%
set stunde=%stunde: =%

echo Speichere Timestamp fuer Ordnernamen
set timestamp=%date%

echo Generiere Pfad fuer Zielordner
set targetFolder=H:\Drive\Screenshots\%timestamp:~6,4%\%timestamp:~3,2%\%timestamp:~ 0,2%\Computerbildschirm

echo Generiere Namen fuer Zieldatei
set targetFileName=%stunde%Uhr-%time:~-8,2%Minuten-%time:~-5,2%Sekunden.png

echo Erstelle screenshot
nircmd.exe savescreenshot screenhot.png

echo Erstelle Zielordner
md %targetFolder%

echo Rechne Bild herunter und speichere es im Zielornder
magick convert screenhot.png -resize 640x360 %targetFolder%/%targetFileName%

echo Warte 300 Sekunden bis zum nächsten Screenshot
timeout 300
goto loop

Sweepi
2022-04-25, 11:57:51
Ich würde empfehlen, so etwas in Python zu schreiben, das lässt sich im Notfall auch debuggen/steppen (z.B. in Visual Studio Code), und wenn du Batch schreiben kannst, kannst du auch Python, nur machen for-loops und Subfunktionen auf einmal Spass.

Edit: Laut Monger scheint Powershell ja auch brauchbar zu sein.

Geldmann3
2022-04-25, 15:51:17
Ja, hatte auch direkt über Python nachgedacht, doch das muss man ja auch erstmal auf dem Rechner installiert haben. Kann ich nicht einfach überall mal schnell draufwerfen.

Wobei, scheint auch Kinderleicht zu sein es self-contained zu machen.
Doch das wäre ja langweilig. :D

Python gefällt mir auch viel besser!

Sweepi
2022-04-25, 16:44:54
Du kannst mit (z.B.) pyinstaller aus einem Python Script eine .exe machen, die dann wiederum auf jeden Rechner ohne Python läuft. (meintest du das mit self-contained?)

myMind
2022-04-25, 18:54:51
Ja, hatte auch direkt über Python nachgedacht, doch das muss man ja auch erstmal auf dem Rechner installiert haben. Kann ich nicht einfach überall mal schnell draufwerfen.
Für Skripting kann man sagen:

Wenn du unter Linux unterwegs bist oder dein Skript auf mehreren Plattformen laufen soll, dann ist Python das Mittel der Wahl. Unter Linux ist das ein Nobrainer, weil Omnipräsent. Unter Windows benötigt man leichte Klimmzüge. Nicht schlimm, aber man muss halt was tun.

Wenn ausschließlich Windows notwendig ist, dann eher Powershell. Das ist eben unter Windows Omnipräsent. Es ist einfach da. Microsoft stellt alle Windows-APIs seit Jahren zuerst als Powershell-API bereit. Und wenn man will, kommt man auch auf tieferliegende APIs (.NET) oder alte APIs (Win32) herunter. Mit Python läuft man da eher in Limitierungen, was Systemprogrammierung angeht.

Die Lernkurve ist bei Powershell etwas steiler. Python ist sehr zugänglich.

Morgenlicht
2022-05-21, 00:47:18
Ich hatte vor einem Jahr bei mir ebenso das Problem in der Batch, daß in der Zeit von 00:00 - 09:59 Uhr die vorangestellte Null nicht mittels %time% ausgegeben wird. Zwar ist die Ausgabe dort 2-stellig, nur mit einem vorangestellten Leerzeichen, statt der erwarteten Null :)

Sofern die Null nicht unbedingt nötig ist, wäre die erste Hilfe beim Auftreten des Fehlers anzusetzen. Fehlerquelle sind die fehlenden doppelten-Hochkomma für die Umschließung der Pfadangabe. Aus diesem Grunde hat magick.exe eine Fehler geworfen, weil der Save-Pfad durch das Leerzeichen unterbrochen wurde.


magick.exe convert screenhot.png -resize 640x360 %date:~6,4%/%date:~3,2%/%date:~0,2%/Computerbildschirm/%time:~-11,2%Uhr-%time:~-8,2%Minuten-%time:~-5,2%Sekunden.png

:: jetzt nach Mitternacht, würde die Commandozeile wie folgt arbeiten:
:: magick.exe convert screenhot.png -resize 640x360 2022/05/21/Computerbildschirm/ 0Uhr-50Minuten-20Sekunden.png
:: ^
:: ∟ an der Stelle bricht die Verarbeitung ab
:: erste Hilfe, setzen der doppelten-Hochkommas:
magick.exe convert screenhot.png -resize 640x360 "2022/05/21/Computerbildschirm/ 0Uhr-50Minuten-20Sekunden.png"
:: bzw.
magick.exe convert screenhot.png -resize 640x360 "%date:~6,4%/%date:~3,2%/%date:~0,2%/Computerbildschirm/%time:~-11,2%Uhr-%time:~-8,2%Minuten-%time:~-5,2%Sekunden.png"



Für mich selbst hatte ich entsprechend Anpassungen vorgenommen, um nach der fehlenden Null zu suchen und zu ersetzen. Also wird der Frage nachgegangen, ob denn weniger als 9, wenn ja, dann %std% neu zusammensetzen
SET "std=%time:~0,2%"
IF %std% LEQ 9 (SET "std=0%std:~1,1%")



Edit, Samstag, 21. Mai 2022, 01:08 Uhr
Es ist auch machbar eine Kombination aus Batch und Powershell.
FOR /F "tokens=*" %%a IN (' powershell -Executionpolicy Bypass -Command "Get-Date -Format 'yyyy.MM.dd HH:mm:ss.ffff' " ') DO @(ECHO %%a)
:: 2022.05.21 01:08:01.3728