kriegstreiber
Goto Top

Batch FOR Schleife - Operationen aus CALL Befehl werden nicht ausgeführt

Hallo liebe Community ich habe ein Problem und komme nicht auf die Lösung. Also was habe ich vor, ich werkel an einem Skript, das mir *.mkv Dateien scannt und Anhand der Scanergebnisse am Ende umbenennt. Das soll sowohl mit Einzelfiles, als auch mit mehreren Files im Verzeichnis gehen. Nun ist es so, dass das Script mit Einzelfiles 100%ig funktioniert, mit Ordnerstrukturen die Variablen aus der Funktion CHECK aber nicht übernimmt. Auszüge aus dem Script:

rem --- Hardcoded settings. Cannot be changed ---
set "INPUTFILE=%~dpnx1"  
set "INPUTFILEPATH=%~dp1"  
set "INPUTFILENAME=%~n1"  
set "INPUTFILEEXT=%~x1"  
set "DIRFOUND=FALSE"  
set "FAKEP5ALLOWED=FALSE"  
set "FAKEP5=NO"  
set "TMP_FOLDER=SAME AS SOURCE"  
set "TARGET_FOLDER=SAME AS SOURCE"  
set "MKVTOOLNIX_FOLDER=INCLUDED"  
set "HDR_Info=No HDR Infos found"  
set "RESOLUTION=N/A"  
set "HDR=N/A"  
set "CODEC_NAME=N/A"  
set "FRAMERATE=N/A"  
set "FRAMES=N/A"  
set "DIR=FALSE"  
set /a ERRORCOUNT=0

rem Erkennen ob Verzeichnis oder Einzeldatei
dir /b/ad "%~1" >nul 2>nul && set DIRFOUND=TRUE  
if "!DIRFOUND!"=="TRUE" goto :MPREPARE  

rem Vorbereitungen fuer Massenumbenennung, setze Counter.
:MPREPARE
set "SOURCE_FOLDER=%~1"  
set /A SOURCEFILES=0 & set "SOURCEFILESC=0F"  
set /A FERRORCOUNT=0 & set "FERRORCOUNTC=0A"  
set /A DONECOUNT=0 & set "DONECOUNTC=08"  
set /A PFILECOUNT=0 & set "PFILECOUNTC=08"  
for /F %%i in ('dir "!SOURCE_FOLDER!\*.mkv" /B /A-d') do set /A SOURCEFILES=!SOURCEFILES!+1>nul  
goto :START

rem Start ist uninteressant, da kann ich nur noch ein paar Sachen einstellen, wie Reihenfolge der Variablen für die umbenennung und co. Wenn da alles ausgewählt ist und DIRFOUND=TRUE geht es zur Funktion MBEGIN.

rem Beginne Stapelverarbeitung für Verzeichnis.
:MBEGIN
if not exist "!TMP_FOLDER!" MD "!TMP_FOLDER!">nul  
if not exist "!TARGET_FOLDER!" MD "!TARGET_FOLDER!">nul  
for /F %%A in ('dir "!SOURCE_FOLDER!\*.mkv" /B /A-d') do (  
	set /A PFILECOUNT=!PFILECOUNT!+1
	set "INPUTFILE=%%A"  
	set "INPUTFILENAME=%%~nA"  
	set "INPUTFILEEXT=%%~xA"  
	call :CHECK
	echo.
	echo Filename   = [!INPUTFILENAME!]
	echo Video Info = [Resolution = !RESOLUTION!] [Codec = !CODEC_NAME!] [Frames = !FRAMES!] [FPS = !FRAMERATE!]
	echo HDR Info   = [!HDR_Info!]	
	pause
)

So ab hier ist jetzt das Problem, das bei "!RESOLUTION!" "!CODEC_NAME!" "!FRAMES!" "!FRAMERATE!" "!HDR_Info!" überall "N/A" angezeigt wird (also die Grundvariable die ich am Anfang festsetze. Die Variablen für die Datei (also die !INPUTFILE" Dinger) werden komischerweise übernommen. Alle Ergebnisse aus CHECK werden nicht übernommen. In CHECK sind auch Operationen drin die in einer FOR Schleife hängen, ich kopiere die Funktion CHECK am Ende auch nochmal rein. Die Funktion CHECK funktioniert soweit mit Einzeldateien tadellos, nur aus meiner Massenverarbeitung heraus irgendwie nicht. Woran könnte das liegen?

EDIT:
z.B dieser Befehl in CHECK:
"!MEDIAINFOpath!" --output=Video;%%HDR_Format_String%% "!INFOSTREAM!">"!TMP_FOLDER!\Info.txt"  
Erzeugt eine leere Info.txt. Bei einer Einzeldatei steht etwas drin. Auch wenn ich den Befehl mit echo wiedergebe ist die Variable !INFOSTREAM! korrekt gesetzt.

:CHECK
if not exist "!TMP_FOLDER!" MD "!TMP_FOLDER!">nul  
echo.
%CYAN%
echo Analysing File. Please wait...
echo.
set "INPUTSTREAM=!INPUTFILE!"  
set "INFOSTREAM=!INPUTFILE!"  
FOR /F "delims=" %%A in ('""!MEDIAINFOpath!" --output=General;%%VideoCount%% "!INFOSTREAM!""') do set "VIDEO_COUNT=%%A"  

::SET HDR FORMAT
"!MEDIAINFOpath!" --output=Video;%%HDR_Format_String%% "!INFOSTREAM!">"!TMP_FOLDER!\Info.txt"  
FOR /F "delims=" %%A IN ('findstr /C:"Dolby Vision" "!TMP_FOLDER!\Info.txt"') DO set "DVinput=YES"  
FOR /F "delims=" %%A IN ('findstr /C:"HDR10" "!TMP_FOLDER!\Info.txt"') DO set "HDRFormat=HDR10"  
FOR /F "delims=" %%A IN ('findstr /C:"HDR10+" "!TMP_FOLDER!\Info.txt"') DO set "HDRFormat=HDR10+"  
FOR /F "delims=" %%A IN ('findstr /C:"dvhe.05" "!TMP_FOLDER!\Info.txt"') DO set "HDRFormat=IPT-PQ-C2"  
FOR /F "delims=" %%A IN ('findstr /C:"HLG" "!TMP_FOLDER!\Info.txt"') DO set "HDRFormat=HLG"  

::SET DV FORMAT
"!MEDIAINFOpath!" --output=Video;%%HDR_Format_Profile%% "!INFOSTREAM!">"!TMP_FOLDER!\Info.txt"  
FOR /F "delims=" %%A IN ('findstr /C:".08" "!TMP_FOLDER!\Info.txt"') DO set "DVinput=YES" & set "DVprofile=8"  
FOR /F "delims=" %%A IN ('findstr /C:".07" "!TMP_FOLDER!\Info.txt"') DO set "DVinput=YES" & set "DVprofile=7"  
FOR /F "delims=" %%A IN ('findstr /C:".06" "!TMP_FOLDER!\Info.txt"') DO set "DVinput=YES" & set "DVprofile=6"  
FOR /F "delims=" %%A IN ('findstr /C:".05" "!TMP_FOLDER!\Info.txt"') DO set "DVinput=YES" & set "DVprofile=5"  
FOR /F "delims=" %%A IN ('findstr /C:".04" "!TMP_FOLDER!\Info.txt"') DO set "DVinput=YES" & set "DVprofile=4"  
FOR /F "delims=" %%A IN ('findstr /C:".03" "!TMP_FOLDER!\Info.txt"') DO set "DVinput=YES" & set "DVprofile=3"  

::DUAL LAYER OPERATION
if "!VIDEO_COUNT!"=="2" (  
	set "LAYERTYPE= DL"  
	set "DT=-map 0:1"  
	"!FFMPEGpath!" -loglevel panic -i "!INFOSTREAM!" -map 0:0 -c:v copy -to 1 "!TMP_FOLDER!\BL.mkv">nul 2>&1  
)
if "!DVinput!"=="YES" "!FFMPEGpath!" -loglevel panic -i "!INFOSTREAM!" !DT! -c:v copy -to 1 -bsf:v hevc_mp4toannexb -f hevc - | "!DO_VI_TOOLpath!" extract-rpu -o "!TMP_FOLDER!\RPU.bin" - >nul 2>&1  
if exist "!TMP_FOLDER!\BL.mkv" set "INFOSTREAM=!TMP_FOLDER!\BL.mkv"  

::BEGIN MEDIAINFO
FOR /F "delims=" %%A in ('""!MEDIAINFOpath!" --output=Video;%%Width%%x%%Height%% "!INFOSTREAM!""') do set "RESOLUTION=%%A"  
FOR /F "delims=" %%A in ('""!MEDIAINFOpath!" --output=Video;%%Format%%^-%%BitDepth%%Bit^-%%ColorSpace%%^-%%ChromaSubsampling%% "!INFOSTREAM!""') do set "CODEC_NAME=%%A"  
FOR /F "tokens=1,2 delims= " %%A in ('""!MEDIAINFOpath!" --output=Video;%%FrameRate_String%% "!INPUTSTREAM!""') do (  
	set "FRAMERATE=%%A"  
	set "FRAMERATE_ORIG=%%A"  
)
FOR /F "delims=" %%A in ('""!MEDIAINFOpath!" --output=Video;%%FrameCount%% "!INPUTSTREAM!""') do set "FRAMES=%%A"  
if "!VIDEO_COUNT!"=="2" set "FRAMES=N/A DL"  
if "!HDRFormat!"=="HDR10" (  
	set "HDR=TRUE"  
	%GREEN%
	echo HDR10 found.
)
if "!HDRFormat!"=="HLG" (  
	set "HDR=TRUE"  
	%GREEN%
	echo HLG found.
)
if "!HDRFormat!"=="HDR10+" (  
	set "HDR=TRUE"  
	set "HDR10P=TRUE"  
	%GREEN%
	echo HDR10+ Metadata found.
)
if "!DVprofile!"=="8" (  
	set "HDR=TRUE"  
	set "DV=TRUE"  
	set "DV_Profile=8"  
	%GREEN%
	echo Dolby Vision Profile 8 found.
)
if "!DVprofile!"=="7" (  
	set "HDR=TRUE"  
	set "DV=TRUE"  
	set "DV_Profile=7"  
	if "!RESOLUTION!"=="1920x1080" set "ELFILE=TRUE"  
	if exist "!TMP_FOLDER!\RPU.bin" (  
		FOR /F "usebackq" %%A IN ('!TMP_FOLDER!\RPU.bin') DO set "RPUSIZE=%%~zA">nul 2>&1  
		if "!RPUSIZE!" NEQ "0" (  
			"!DO_VI_TOOLpath!" info -s "!TMP_FOLDER!\RPU.bin">"!TMP_FOLDER!\RPUINFO.txt"  
			if exist "!TMP_FOLDER!\RPUINFO.txt" (  
				FOR /F "delims=" %%A IN ('findstr /C:"Profile:" "!TMP_FOLDER!\RPUINFO.txt"') DO set "subprofile=%%A"  
				if defined subprofile (
					for /F "tokens=3 delims=:/ " %%A in ("!subprofile!") do set "subprofile= %%A"  
				) else (
					set "subprofile="  
				)
			)
		)
	)
	%GREEN%
	if "!ELFILE!"=="FALSE" (  
		echo Dolby Vision Profile 7!subprofile!!LAYERTYPE! found.
	) else (
		echo Dolby Vision Profile 7!subprofile!!LAYERTYPE! EL Layer found.
	)
	set "DV_Profile=7!subprofile!!LAYERTYPE!"  
)
if "!DVprofile!"=="5" (  
	set "HDR=FALSE"  
	set "DV=TRUE"  
	set "DV_Profile=5"  
	%GREEN%
	echo Dolby Vision Profile 5 found.
)
if "!DVprofile!"=="4" (  
	set "HDR=TRUE"  
	set "DV=TRUE"  
	set "DV_Profile=4"  
	%GREEN%
	echo Dolby Vision Profile 4 found.
)
%GREEN%
if exist "!TMP_FOLDER!\Info.mkv" del "!TMP_FOLDER!\Info.mkv">nul  
if exist "!TMP_FOLDER!\BL.mkv" del "!TMP_FOLDER!\BL.mkv">nul  
if exist "!TMP_FOLDER!\RPU.bin" del "!TMP_FOLDER!\RPU.bin">nul  
if "!HDR!"=="TRUE" set "HDR_Info=!HDRFormat!"  
if "!HDR10P!"=="TRUE" set "HDR_Info=HDR10, !HDRFormat!"  
if "!DV!"=="TRUE" set "HDR_Info=Dolby Vision Profile !DV_Profile!"  
if "!HDR!!DV!"=="TRUETRUE" set "HDR_Info=!HDRFormat!, Dolby Vision Profile !DV_Profile!"  
if "!HDR10P!!DV!"=="TRUETRUE" set "HDR_Info=HDR10, !HDRFormat!, Dolby Vision Profile !DV_Profile!"  
echo.
echo Analysing complete.
if "!DIRFOUND!"=="TRUE" goto :eof  
if exist "!TMP_FOLDER!" RD /S /Q "!TMP_FOLDER!">nul  
TIMEOUT 3 /NOBREAK>nul
goto :START

Content-ID: 670655

Url: https://administrator.de/forum/batch-for-schleife-operationen-aus-call-befehl-werden-nicht-ausgefuehrt-670655.html

Ausgedruckt am: 12.01.2025 um 14:01 Uhr

Kriegstreiber
Lösung Kriegstreiber 12.01.2025 aktualisiert um 14:46:35 Uhr
Goto Top
So ich habe die Lösung gefunden, ich bin auch echt ein Depp ey. Der Fehler lag bereits in der Funktion :MBEGIN und ich habe nicht richtig geguckt :/ Das war die Ursache:

for /F %%A in ('dir "!SOURCE_FOLDER!\*.mkv" /B /A-d') do  

Natürlich wird bei dem Befehl der letzte Ordner "verschluckt". Ersetzt durch:

for %%A in ("!SOURCE_FOLDER!\*.mkv") do  

und schon geht auch alles. Achja, so als kleiner Tip was Verzeichnisvariablen angeht, wenn man z.B. Dateien hinzufügt.
Da ich viele Scripte erstelle wo ich Dateien/Verzeichnis mit set /p und Drag and Drop benutze, bzw. Scripte erstelle die mit Verzeichnissen/Dateien gestartet werden können (also z.B. MeinTool.cmd "C:\Meine Dateien\MeineDatei.txt") und man jetzt diesen Input als Variable anlegen will, kann man z.B set "MEIN_INPUT_FILE=%~1" nehmen. Das hat aber zur Folge, dass die Variable %MEIN_INPUT_FILE% in unserem Beispiel nun "C:\Meine Dateien\MeineDatei.txt" wäre. Bedeutet also dass die "" schon mit gesetzt sind. Da ich mir angewöhnt habe bei Verzeichnissen in den Scripts diese auch immer in "" zu setzen (sonst steigt Batch halt bei Leerzeichen und dergleichen aus) kam es oft zu dem Problem, das ich die Variable "%MEIN_INPUT_FILE%" gesetzt habe und nun das ganze oft nicht funktioniert, weil jetzt quasi ""C:\Meine Dateien\MeineDatei.txt"" verarbeitet wird. Um das zu verhindern habe ich mir angewöhnt, immer [%~dpnx1] (set "MEIN_INPUT_FILE=%~dpnx1") statt [%~1] (set "MEIN_INPUT_FILE=%~1") zu verwenden, weil hier die Variable keine "" hat und man wie gewohnt "%MEIN_INPUT_FILE%" nutzen kann. Vielleicht hilft es ja dem ein oder anderen.

Gruss an euch alle und schönen Sonntag gewünscht.
DivideByZero
DivideByZero 12.01.2025 um 14:55:17 Uhr
Goto Top
Moin,

danke, dass Du auch gleich die Lösung dargestellt hast. Aber der Code und Deine Überlegungen zeigen, warum es schwierig ist, Batch"code" zu debuggen und zu verstehen. Das, was Du machst, ist ideal für eine Programmiersprache oder die Powershell geeignet. Besser zu lesender und zu verstehender, kürzerer und weniger komplexer Code.

Gruß

DivideByZero
Kriegstreiber
Kriegstreiber 12.01.2025 um 15:57:27 Uhr
Goto Top
Leider kann ich nichts anderes als Batch, bin auch zu alt mich jetzt noch mit Powershell und Co. zu beschäftigen. Obwohl ich Batch jetzt nicht als Programmiersprache sehe, ist ja im Grunde nur eine Aneinanderreihung von CMD Befehlen. Komme noch aus der DOS Ära und da kann man ja dann zwangsweise Batch. Ich hatte mich mal an Free Pascal und der Lazarus IDE probiert, weil ich gerne viele meiner komplexeren Scripte in einer schönen GUI hätte, Häkchen setzen statt choice Befehle, aber bin auch daran kläglich gescheitert. Egal was probiere und übe ich "denke" immer in Batch und komm davon nicht los.