viper-berlin
Goto Top

Errorlevel Syntax? Robocopy Fehlerauswertung geht nicht

Servus Leute,

wer kann Helfen???

System W2K3 und Win7

1. wie ist die richtige Syntax von ERRORLEVEL ?

z.B.
IF ERRORLEVEL 2 ECHO ##Fehler größer 2## ?

mit Robocopy hab ich Probleme die Fehlerauswertung geht nicht

hier der Soucecode.. die PROCEDURE DIE NICHT geht !!! ich bekomme immer als Ergebnis:NOERR 00 NO CHANGE
und ERRORLEVEL 0 was ist Falsch ???
REM  *** ROBOCOPY FÜR ALLES +FEHLERAUSWERTUNG INS LOG **************************************************************************************
REM  ### Var: %P_Robo_Path_Von%  # VON WO KOPIERT WERDEN SOLL NUR PATH C:\TEST\         ###
REM  ### Var: %P_Robo_Path_Nach% # WOHIN WIRD KOPIERT WERDEN SOLL NUR PATH C:\TEST\     ###
REM  ### Var: %P_Robo_FileS%     # ZU KOPIERENDE FILES *.* für alle  z.B datei.txt      ###
REM  ### Var: %P_Robo_Para%      # PARAMETERÜBERGABE AN ROBOCOPY Z.B /E / PURGE /MIR    ###
REM  ### Var: %P_Robo_MSG_OK%    # FEHLERMELDUNG  OK-TEXT DER BEI FEHLER VERWENDET WIRD ###
REM  ### Var: %P_Robo_MSG_ERR%   # FEHLERMELDUNG ERR-TEXT DER BEI FEHLER VERWENDET WIRD ###
:ProRobocopy4Var
     REM  --- WRITE LOGFILE IST VORHANDEN ALSO INS LOGFILE SCHREIBEN ---
     ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE  
     IF  ERRORLEVEL 17 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 17 ***ERROR ?? ***"  
     IF  ERRORLEVEL 16 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 16 ***FATAL ERROR***"  
     IF  ERRORLEVEL 15 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 15 FAIL MISM XTRA COPY"  
     IF  ERRORLEVEL 14 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 14 FAIL MISM XTRA"  
     IF  ERRORLEVEL 13 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 13 FAIL MISM COPY"  
     IF  ERRORLEVEL 12 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 12 FAIL MISM"  
     IF  ERRORLEVEL 11 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 11 FAIL XTRA COPY"  
     IF  ERRORLEVEL 10 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 10 FAIL XTRA"  
     IF  ERRORLEVEL  9 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 09 FAIL COPY"  
     IF  ERRORLEVEL  8 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 08 FAIL"  
     IF  ERRORLEVEL  7 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 07 MISM XTRA COPY"  
     IF  ERRORLEVEL  6 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 06 MISM XTRA"  
     IF  ERRORLEVEL  5 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 05 MISM COPY"  
     IF  ERRORLEVEL  4 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 04 MISM"  
     IF  ERRORLEVEL  3 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 03 XTRA COPY"  
     IF  ERRORLEVEL  2 SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS: ERR 02 XTRA"  
     REM ### SONDERFäLLE 0 u 1 SIND KEINE FEHLER ###
     IF  ERRORLEVEL  1 SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS: NOERR 01 COPY"  
     IF  ERRORLEVEL  0 SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS: NOERR 00 NO CHANGE"  
     
    ECHO ### %ERRORLEVEL%   der ist immer 0 ?????####
    
    REM --- ROBOCOPY STATUS auf Bildschirm ---
    
    IF  ERRORLEVEL 2 (               
          ECHO ROCOPY: Fehler STATUS: %MsgInfoSwap% beim kopieren %P_Robo_FileS% ERR:%ERRORLEVEL%  !."  
          ) ELSE (
                 echo ROCOPY: STATUS: %MsgInfoSwap% FILES: %P_Robo_FileS% wurden kopiert!."  
     )
GOTO :EOF

Content-Key: 223631

Url: https://administrator.de/contentid/223631

Printed on: April 18, 2024 at 15:04 o'clock

Member: colinardo
colinardo Dec 04, 2013 updated at 10:36:05 (UTC)
Goto Top
Hallo Viper-Berlin,
du solltest dir das hier mal durchlesen: http://hannes-schurig.de/26/08/2010/batch-if-errorlevel/
Der Vergleich ohne operator wie du ihn machst könnte man quasi so lesen:
WENN ERRORLEVEL >= 0
Geprüft wird also nicht if errorlevel = X sondern if errorlevel >= X!
da bei dir der letzte Vergleich, der mit dem ERRORLEVEL 0 ist, wird die Variable immer mit "NOERR 00 NO CHANGE" versehen.

mach den Vergleich mit ERRORLEVEL also besser so:
IF "%ERRORLEVEL%" == "17" SET ....
usw.

Grüße Uwe
Member: Viper-Berlin
Viper-Berlin Dec 04, 2013, updated at Dec 06, 2013 at 00:28:58 (UTC)
Goto Top
Hallo Uwe,
ja danke für die schnelle Antwort face-wink
hast recht die Letzte Zeile war natürlich quatsch
aber es geht immer noch nicht ich bekomme auch mit einem direkten ECHO %ERRORLEVEL% immer 0 angezeigt
hier noch mal der Code was ist da blos falsch ????.....
:ProRobocopy4Var
      ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE 
     SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:KEIN FEHLER ERKANNT"      & REM STATUSMELDUNG ÜBERSCHREIBEN  
     IF  "%ERRORLEVEL%"=="17" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 17 ***ERROR ?? ***"  
     IF  "%ERRORLEVEL%"=="16" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 16 ***FATAL ERROR***"  
     IF  "%ERRORLEVEL%"=="15" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 15 FAIL MISM XTRA COPY"  
     IF  "%ERRORLEVEL%"=="14" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 14 FAIL MISM XTRA"  
     IF  "%ERRORLEVEL%"=="13" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 13 FAIL MISM COPY"  
     IF  "%ERRORLEVEL%"=="12" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 12 FAIL MISM"  
     IF  "%ERRORLEVEL%"=="11" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 11 FAIL XTRA COPY"  
     IF  "%ERRORLEVEL%"=="10" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 10 FAIL XTRA"  
     IF  "%ERRORLEVEL%"=="9"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 09 FAIL COPY"  
     IF  "%ERRORLEVEL%"=="8"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 08 FAIL"  
     IF  "%ERRORLEVEL%"=="7"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 07 MISM XTRA COPY"  
     IF  "%ERRORLEVEL%"=="6"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 06 MISM XTRA"  
     IF  "%ERRORLEVEL%"=="5"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 05 MISM COPY"  
     IF  "%ERRORLEVEL%"=="4"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 04 MISM"  
     IF  "%ERRORLEVEL%"=="3"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 03 XTRA COPY"  
     IF  "%ERRORLEVEL%"=="2"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 02 XTRA"  
     REM  --- SIND KEIN FEHLER 0 DATEIEN SIND SCHON VORHANDEN 1 KOPIERT ---
     IF  "%ERRORLEVEL%"=="1"  SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:NOERR 01 COPY"  
     IF  "%ERRORLEVEL%"=="0"  SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:NOERR 00 NO CHANGE"  
     ECHO ################ERRORLEVEL=%ERRORLEVEL%#########################
     ECHO ################MsgInfoSwap=%MsgInfoSwap%#######################

rem  hier kommt immer errorlevel =0 raus ??????

     REM --- ROBOCOPY STATUS IN MSG SCHREIBEN WENN ERRORLEVEL >=2 DANN FEHLERMELDUNG ANSONSTEN CHECKEN OB KOPIERT WURDE O    ÜBERSPRUNGEN---
     IF  ERRORLEVEL 2 (
          SET  "MsgInfoSwap=%Msg_ERR%ROCOPY: Fehler beim kopieren %P_Robo_FileS% ERR:%ERRORLEVEL%  !."  
          ) ELSE (
                 IF  "%ERRORLEVEL%" == "1" (  
                      SET  "MsgInfoSwap=%Msg_OK%ROCOPY: FILES: %P_Robo_FileS% wurden kopiert!."  
                 )
                 IF  "%ERRORLEVEL%" == "0" (  
                     SET  "MsgInfoSwap=%Msg_WAR%ROCOPY: FILES: %P_Robo_FileS% wurden übersprungen!."  
                 )
           )
     )
Member: Viper-Berlin
Viper-Berlin Dec 04, 2013 at 11:32:35 (UTC)
Goto Top
kann das sein das der SET Befehl den ERRORLEVEL STATUS überschreibt also 0 für OK ???
Member: colinardo
colinardo Dec 04, 2013 updated at 11:38:12 (UTC)
Goto Top
mach es so:
Du speicherst nach dem Robocopy-Befehl den ERRORLEVEL-Wert in einer eigenen VARIABLEN und überprüfst dann nur noch diese nacheinander:
ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE 
set FEHLERCODE=%ERRORLEVEL%
IF "%FEHLERCODE%"=="17" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 17 *ERROR ?? *"  
usw.
....
...
Member: Viper-Berlin
Viper-Berlin Dec 04, 2013 updated at 12:35:28 (UTC)
Goto Top
So Versuch mach Kluch !!!
hat leider nicht geklappt alles 0 ERRORLEVEL und 0 FEHLERCODE auch bei Dateien die kopiert werden die gar nät da sind
ich weiss das es eine Version von ROBOCOPY gibt die kein ERRORLEVEL zurückgibt die hab ich aber nicht ! ich hab hier die XP10

hier noch mal das ganze geraffel vielleicht findest du den BUG face-wink


 
REM  *** ROBOCOPY FÜR ALLES +FEHLERAUSWERTUNG INS LOG **************************************************************************************
REM  ### Var: %P_Robo_Path_Von%      # VON WO KOPIERT WERDEN SOLL NUR PATH C:\TEST\         ###
REM  ### Var: %P_Robo_Path_Nach%   # WOHIN WIRD KOPIERT WERDEN SOLL NUR PATH C:\TEST\     ###
REM  ### Var: %P_Robo_FileS%            # ZU KOPIERENDE FILES *.* FÜR ALLE  Z.B DATEI.TXT      ###
REM  ### Var: %P_Robo_Para%             # PARAMETERÜBERGABE AN ROBOCOPY Z.B /E / PURGE /MIR    ###
:ProRobocopy4Var
     SET /A  "Err_Robo=0"                                   & REM *** ERRORVARIABLE VON ROBOCOPY AUF 0 SETZEN          ***  
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:   WAS:%P_Robo_FileS%"  
     CALL :ProMsgWriteToScrAndLog
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:   VON:%P_Robo_Path_Von%"  
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                 ***
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:  NACH:%P_Robo_Path_Nach%"  
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                 ***
     IF  /I  "%LogF_Full_Main_Swap%"=="NUL" (  
         REM  --- NOT WRITE LOGFILE IST NICHT VORHANDEN ALSO NICHT REIN SCHREIBEN AUSGABE IN NULL UMLEITEN ---
         ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE >NUL
         SET /A "FEHLERCODE=%ERRORLEVEL%"                      & REM *** FEHLER in VARIABLE SPEICHERN ***  
         ) ELSE (
             REM  --- WRITE LOGFILE IST VORHANDEN ALSO INS LOGFILE SCHREIBEN ---
             ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE /LOG+:"%LogF_Full_Main%" >NUL  
             SET /A "FEHLERCODE=%ERRORLEVEL%"                      & REM *** FEHLER in VARIABLE SPEICHERN ***  
     )
     ECHO  ##### vorher FEHLERCODE=%FEHLERCODE% ERRORLEVEL=%ERRORLEVEL% ######
     IF  "%FEHLERCODE%" == "17" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 17 ***ERROR ?? ***"  
     IF  "%FEHLERCODE%" == "16" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 16 ***FATAL ERROR***"  
     IF  "%FEHLERCODE%" == "15" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 15 FAIL MISM XTRA COPY"  
     IF  "%FEHLERCODE%" == "14" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 14 FAIL MISM XTRA"  
     IF  "%FEHLERCODE%" == "13" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 13 FAIL MISM COPY"  
     IF  "%FEHLERCODE%" == "12" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 12 FAIL MISM"  
     IF  "%FEHLERCODE%" == "11" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 11 FAIL XTRA COPY"  
     IF  "%FEHLERCODE%" == "10" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 10 FAIL XTRA"  
     IF  "%FEHLERCODE%" == "9"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 09 FAIL COPY"  
     IF  "%FEHLERCODE%" == "8"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 08 FAIL"  
     IF  "%FEHLERCODE%" == "7"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 07 MISM XTRA COPY"  
     IF  "%FEHLERCODE%" == "6"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 06 MISM XTRA"  
     IF  "%FEHLERCODE%" == "5"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 05 MISM COPY"  
     IF  "%FEHLERCODE%" == "4"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 04 MISM"  
     IF  "%FEHLERCODE%" == "3"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 03 XTRA COPY"  
     IF  "%FEHLERCODE%" == "2"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 02 XTRA"  
     REM  --- SIND KEIN FEHLER 0 DATEIEN SIND SCHON VORHANDEN 1 KOPIERT ---
     IF  "%FEHLERCODE%" == "1"  SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:NOERR 01 COPY"  
     IF  "%FEHLERCODE%" == "0"  SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:NOERR 00 NO CHANGE"  
     ECHO  ##### nachher FEHLERCODE=%FEHLERCODE% ERRORLEVEL=%ERRORLEVEL% ######
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                     ***
     REM --- ROBOCOPY STATUS IN MSG SCHREIBEN WENN ERRORLEVEL >=2 DANN FEHLERMELDUNG ANSONSTEN CHECKEN OB KOPIERT WURDE O ÜBERSPRUNGEN---
     IF  "%FEHLERCODE%" GEQ "2" (  
         SET  /A "Err_Robo=1"                               & REM *** Err_Robo FÜR DIE AUSWERTUNG VON FEHLERN BEI ROBOCOPY ***  
         SET  "MsgInfoSwap=%Msg_ERR%ROCOPY: Fehler beim kopieren %P_Robo_FileS% ERR:%FEHLERCODE%  !."  
         CALL :ProEventLogCreateERR                         & REM *** CREATE EVENT ERROR                                   ***
         ) ELSE (
             IF  "%FEHLERCODE%" == "1" (  
                   SET  "MsgInfoSwap=%Msg_OK%ROCOPY: FILES: %P_Robo_FileS% wurden kopiert!."  
             )
             IF  "%FEHLERCODE%" == "0" (  
                  SET  "MsgInfoSwap=%Msg_WAR%ROCOPY: FILES: %P_Robo_FileS% wurden übersprungen!."  
             )
             CALL :ProMsgWriteToScrAndLog                   & REM *** CREATE INFO -MSG TO SCR UND LOG-                    ***
         )
     )
Member: colinardo
colinardo Dec 04, 2013 updated at 12:31:50 (UTC)
Goto Top
bitte benutze Tags um deinen Code zu posten, sonst gehen hier vielleicht wichtige Sonderzeichen unter !!
mach mal bitte die Umleitung der Ausgaben von Robocopy weg : >NUL
Member: Viper-Berlin
Viper-Berlin Dec 04, 2013 at 12:35:58 (UTC)
Goto Top
OK gemacht face-wink
Member: Viper-Berlin
Viper-Berlin Dec 04, 2013 at 12:49:07 (UTC)
Goto Top
So jetzt richtig formatiert.....
hat leider nicht geklappt alles 0 ERRORLEVEL und 0 FEHLERCODE auch bei Dateien die kopiert werden die gar nät da sind
ich weiss das es eine Version von ROBOCOPY gibt die kein ERRORLEVEL zurückgibt die hab ich aber nicht ! ich hab hier die XP10

hier noch mal das ganze geraffel vielleicht findest du den BUG face-wink


 
REM  *** ROBOCOPY FÜR ALLES +FEHLERAUSWERTUNG INS LOG **************************************************************************************
REM  ### Var: %P_Robo_Path_Von%      # VON WO KOPIERT WERDEN SOLL NUR PATH C:\TEST\         ###
REM  ### Var: %P_Robo_Path_Nach%   # WOHIN WIRD KOPIERT WERDEN SOLL NUR PATH C:\TEST\     ###
REM  ### Var: %P_Robo_FileS%            # ZU KOPIERENDE FILES *.* FÜR ALLE  Z.B DATEI.TXT      ###
REM  ### Var: %P_Robo_Para%             # PARAMETERÜBERGABE AN ROBOCOPY Z.B /E / PURGE /MIR    ###
:ProRobocopy4Var
     SET /A  "Err_Robo=0"                                   & REM *** ERRORVARIABLE VON ROBOCOPY AUF 0 SETZEN          ***  
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:   WAS:%P_Robo_FileS%"  
     CALL :ProMsgWriteToScrAndLog
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:   VON:%P_Robo_Path_Von%"  
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                 ***
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:  NACH:%P_Robo_Path_Nach%"  
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                 ***
     IF  /I  "%LogF_Full_Main_Swap%"=="NUL" (  
         REM  --- NOT WRITE LOGFILE IST NICHT VORHANDEN ALSO NICHT REIN SCHREIBEN AUSGABE IN NULL UMLEITEN ---
         ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE >NUL
         SET /A "FEHLERCODE=%ERRORLEVEL%"                      & REM *** FEHLER in VARIABLE SPEICHERN ***  
         ) ELSE (
             REM  --- WRITE LOGFILE IST VORHANDEN ALSO INS LOGFILE SCHREIBEN ---
             ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE /LOG+:"%LogF_Full_Main%" >NUL  
             SET /A "FEHLERCODE=%ERRORLEVEL%"                      & REM *** FEHLER in VARIABLE SPEICHERN ***  
     )
     ECHO  ##### vorher FEHLERCODE=%FEHLERCODE% ERRORLEVEL=%ERRORLEVEL% ######
     IF  "%FEHLERCODE%" == "17" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 17 ***ERROR ?? ***"  
     IF  "%FEHLERCODE%" == "16" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 16 ***FATAL ERROR***"  
     IF  "%FEHLERCODE%" == "15" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 15 FAIL MISM XTRA COPY"  
     IF  "%FEHLERCODE%" == "14" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 14 FAIL MISM XTRA"  
     IF  "%FEHLERCODE%" == "13" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 13 FAIL MISM COPY"  
     IF  "%FEHLERCODE%" == "12" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 12 FAIL MISM"  
     IF  "%FEHLERCODE%" == "11" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 11 FAIL XTRA COPY"  
     IF  "%FEHLERCODE%" == "10" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 10 FAIL XTRA"  
     IF  "%FEHLERCODE%" == "9"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 09 FAIL COPY"  
     IF  "%FEHLERCODE%" == "8"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 08 FAIL"  
     IF  "%FEHLERCODE%" == "7"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 07 MISM XTRA COPY"  
     IF  "%FEHLERCODE%" == "6"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 06 MISM XTRA"  
     IF  "%FEHLERCODE%" == "5"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 05 MISM COPY"  
     IF  "%FEHLERCODE%" == "4"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 04 MISM"  
     IF  "%FEHLERCODE%" == "3"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 03 XTRA COPY"  
     IF  "%FEHLERCODE%" == "2"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 02 XTRA"  
     REM  --- SIND KEIN FEHLER 0 DATEIEN SIND SCHON VORHANDEN 1 KOPIERT ---
     IF  "%FEHLERCODE%" == "1"  SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:NOERR 01 COPY"  
     IF  "%FEHLERCODE%" == "0"  SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:NOERR 00 NO CHANGE"  
     ECHO  ##### nachher FEHLERCODE=%FEHLERCODE% ERRORLEVEL=%ERRORLEVEL% ######
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                     ***
     REM --- ROBOCOPY STATUS IN MSG SCHREIBEN WENN ERRORLEVEL >=2 DANN FEHLERMELDUNG ANSONSTEN CHECKEN OB KOPIERT WURDE O ÜBERSPRUNGEN---
     IF  "%FEHLERCODE%" GEQ "2" (  
         SET  /A "Err_Robo=1"                               & REM *** Err_Robo FÜR DIE AUSWERTUNG VON FEHLERN BEI ROBOCOPY ***  
         SET  "MsgInfoSwap=%Msg_ERR%ROCOPY: Fehler beim kopieren %P_Robo_FileS% ERR:%FEHLERCODE%  !."  
         CALL :ProEventLogCreateERR                         & REM *** CREATE EVENT ERROR                                   ***
         ) ELSE (
             IF  "%FEHLERCODE%" == "1" (  
                   SET  "MsgInfoSwap=%Msg_OK%ROCOPY: FILES: %P_Robo_FileS% wurden kopiert!."  
             )
             IF  "%FEHLERCODE%" == "0" (  
                  SET  "MsgInfoSwap=%Msg_WAR%ROCOPY: FILES: %P_Robo_FileS% wurden übersprungen!."  
             )
             CALL :ProMsgWriteToScrAndLog                   & REM *** CREATE INFO -MSG TO SCR UND LOG-                    ***
         )
     )
Member: Penny.Cilin
Penny.Cilin Dec 04, 2013 updated at 12:51:37 (UTC)
Goto Top
Hallo,

zunächst war Dein erster Ansatz bzgl. der Auswertung schon korrekt. Allerdings sollte der Setbefehl meines Wissens nach so lauten?
IF ERRORLEVEL 17 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 17 *ERROR ?? *"
IF ERRORLEVEL 16 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 16 *FATAL ERROR*"
IF ERRORLEVEL 15 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 15 FAIL MISM XTRA COPY"
IF ERRORLEVEL 14 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 14 FAIL MISM XTRA"
IF ERRORLEVEL 13 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 13 FAIL MISM COPY"
IF ERRORLEVEL 12 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 12 FAIL MISM"
IF ERRORLEVEL 11 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 11 FAIL XTRA COPY"
IF ERRORLEVEL 10 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 10 FAIL XTRA"
IF ERRORLEVEL 9 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 09 FAIL COPY"
IF ERRORLEVEL 8 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 08 FAIL"
IF ERRORLEVEL 7 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 07 MISM XTRA COPY"
IF ERRORLEVEL 6 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 06 MISM XTRA"
IF ERRORLEVEL 5 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 05 MISM COPY"
IF ERRORLEVEL 4 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 04 MISM"
IF ERRORLEVEL 3 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 03 XTRA COPY"
IF ERRORLEVEL 2 SET MsgInfoSwap="%Msg_ERR%ROCOPY:STATUS: ERR 02 XTRA"

Und schau Dir mal folgende Seite an ROBOCOPY Exit Codes

Gruss Penny.
Member: Jochem
Solution Jochem Dec 04, 2013, updated at Dec 05, 2013 at 11:49:01 (UTC)
Goto Top
Moin,

Helpfile zu "IF" bezüglich Errorlevel:

ERRORLEVEL Nummer --> Bedingung ist erfüllt, wenn das zuletzt ausgeführte Programm einen Code größer oder gleich der Nummer zurückgibt.

Laut Deinem Script wird in Zeile 17 bzw. 21 der ROBOCOPY-Befehl ausgeführt.
In Zeile 22 folgt ein SET-Befehl.

Die Rückgabewert welchen Befehls wird nun in ERRORLEVEL enthalten sein?

Außerdem willst Du doch mit SET eine Variable füllen, aber welche geht aus Deinem Script nicht hervor (siehe Post von P.C).

Gruß J face-smile chem
Member: Viper-Berlin
Viper-Berlin Dec 04, 2013 at 13:14:51 (UTC)
Goto Top
ja danke !!

also
SET A="test"
bring bei ECHO %A%

Ergebniss "test" also Falsch! mit ""

SET "A=test" ist deshalb gut weil dann der übliche Fehler, es ist noch ein Blank hinten dran
z.B so set A=test . und grade bei Numerischen Variablen gibts da ein Abschuss

SET /A A=11 blanks

gut ist es auch bei dieser Schreibweise

SET "A=test" hier kann man noch ein Befehl hinter schreiben & REM * ALLES OK GUT FÜR ZEILENDOKU *

Gruß jens
Member: colinardo
Solution colinardo Dec 04, 2013, updated at Dec 05, 2013 at 11:48:42 (UTC)
Goto Top
so müsste es laufen:
setlocal ENABLEDELAYEDEXPANSION
REM  *** ROBOCOPY FÜR ALLES +FEHLERAUSWERTUNG INS LOG **************************************************************************************
REM  ### Var: %P_Robo_Path_Von%      # VON WO KOPIERT WERDEN SOLL NUR PATH C:\TEST\         ###
REM  ### Var: %P_Robo_Path_Nach%   # WOHIN WIRD KOPIERT WERDEN SOLL NUR PATH C:\TEST\     ###
REM  ### Var: %P_Robo_FileS%            # ZU KOPIERENDE FILES *.* FÜR ALLE  Z.B DATEI.TXT      ###
REM  ### Var: %P_Robo_Para%             # PARAMETERÜBERGABE AN ROBOCOPY Z.B /E / PURGE /MIR    ###

:ProRobocopy4Var
     SET /A  "Err_Robo=0"                                   & REM *** ERRORVARIABLE VON ROBOCOPY AUF 0 SETZEN          ***  
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:   WAS:%P_Robo_FileS%"  
     CALL :ProMsgWriteToScrAndLog
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:   VON:%P_Robo_Path_Von%"  
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                 ***
     SET  "MsgInfoSwap=%Msg_OK%ROCOPY:  NACH:%P_Robo_Path_Nach%"  
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                 ***
     IF  /I  "%LogF_Full_Main_Swap%"=="NUL" (  
         REM  --- NOT WRITE LOGFILE IST NICHT VORHANDEN ALSO NICHT REIN SCHREIBEN AUSGABE IN NULL UMLEITEN ---
         ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE >NUL
         SET /A "FEHLERCODE=!ERRORLEVEL!"                      & REM *** FEHLER in VARIABLE SPEICHERN ***  
         ) ELSE (
             REM  --- WRITE LOGFILE IST VORHANDEN ALSO INS LOGFILE SCHREIBEN ---
             ROBOCOPY %P_Robo_Path_Von% %P_Robo_Path_Nach% %P_Robo_FileS% %P_Robo_Para% /IS /W:2 /R:10 /COPY:DAT /V /TEE /LOG+:"%LogF_Full_Main%" >NUL  
             SET /A "FEHLERCODE=!ERRORLEVEL!"                      & REM *** FEHLER in VARIABLE SPEICHERN ***  
     )
     ECHO  ##### vorher FEHLERCODE=!FEHLERCODE!######
     IF  "!FEHLERCODE!" == "17" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 17 ***ERROR ?? ***"  
     IF  "!FEHLERCODE!" == "16" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 16 ***FATAL ERROR***"  
     IF  "!FEHLERCODE!" == "15" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 15 FAIL MISM XTRA COPY"  
     IF  "!FEHLERCODE!" == "14" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 14 FAIL MISM XTRA"  
     IF  "!FEHLERCODE!" == "13" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 13 FAIL MISM COPY"  
     IF  "!FEHLERCODE!" == "12" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 12 FAIL MISM"  
     IF  "!FEHLERCODE!" == "11" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 11 FAIL XTRA COPY"  
     IF  "!FEHLERCODE!" == "10" SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 10 FAIL XTRA"  
     IF  "!FEHLERCODE!" == "9"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 09 FAIL COPY"  
     IF  "!FEHLERCODE!" == "8"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 08 FAIL"  
     IF  "!FEHLERCODE!" == "7"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 07 MISM XTRA COPY"  
     IF  "!FEHLERCODE!" == "6"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 06 MISM XTRA"  
     IF  "!FEHLERCODE!" == "5"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 05 MISM COPY"  
     IF  "!FEHLERCODE!" == "4"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 04 MISM"  
     IF  "!FEHLERCODE!" == "3"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 03 XTRA COPY"  
     IF  "!FEHLERCODE!" == "2"  SET "MsgInfoSwap=%Msg_ERR%ROCOPY:STATUS:ERR 02 XTRA"  
     REM  --- SIND KEIN FEHLER 0 DATEIEN SIND SCHON VORHANDEN 1 KOPIERT ---
     IF  "!FEHLERCODE!" == "1"  SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:NOERR 01 COPY"  
     IF  "!FEHLERCODE!" == "0"  SET "MsgInfoSwap=%Msg_OK%ROCOPY:STATUS:NOERR 00 NO CHANGE"  
     ECHO  ##### nachher FEHLERCODE=!FEHLERCODE! ######
     CALL :ProMsgWriteToScrAndLog                           & REM *** CREATE INFO -MSG TO SCR UND LOG-                     ***
     REM --- ROBOCOPY STATUS IN MSG SCHREIBEN WENN ERRORLEVEL >=2 DANN FEHLERMELDUNG ANSONSTEN CHECKEN OB KOPIERT WURDE O ÜBERSPRUNGEN---
     IF  "!FEHLERCODE!" GEQ "2" (  
         SET  /A "Err_Robo=1"                               & REM *** Err_Robo FÜR DIE AUSWERTUNG VON FEHLERN BEI ROBOCOPY ***  
         SET  "MsgInfoSwap=%Msg_ERR%ROCOPY: Fehler beim kopieren %P_Robo_FileS% ERR:!FEHLERCODE! ."  
         CALL :ProEventLogCreateERR                         & REM *** CREATE EVENT ERROR                                   ***
         ) ELSE (
             IF  "!FEHLERCODE!" == "1" (  
                   SET  "MsgInfoSwap=%Msg_OK%ROCOPY: FILES: %P_Robo_FileS% wurden kopiert."  
             )
             IF  "!FEHLERCODE!" == "0" (  
                  SET  "MsgInfoSwap=%Msg_WAR%ROCOPY: FILES: %P_Robo_FileS% wurden übersprungen."  
             )
             CALL :ProMsgWriteToScrAndLog                   & REM *** CREATE INFO -MSG TO SCR UND LOG-                    ***
         )
     )
Stichwort: delayed expansion
Member: Viper-Berlin
Viper-Berlin Dec 04, 2013 at 13:53:23 (UTC)
Goto Top
Ja danke,
ich versuchs mal.....

ich hätte noch ein paar Fragen dazu hat diese
also was lokale u globale Variablen sind ist klar aber wozu braucht man diesen Befehl
setlocal ENABLEDELAYEDEXPANSION
Hat der auswirkungen auf meine anderen globalen Variablen ???
wie kann man es beenden ?
endlocal ??? in der Procedure ?
Diese Problematik hab ich noch nie begriffen ??
wie kann ich das Script so schreiben das es funktioniert wie in jeder anderen Programmiersprache ?
und ich nicht ständig auf solche Probleme stoße.

Danke Vipy
Member: colinardo
Solution colinardo Dec 04, 2013, updated at Dec 05, 2013 at 11:48:39 (UTC)
Goto Top
Zitat von @Viper-Berlin:
ich hätte noch ein paar Fragen dazu hat diese
also was lokale u globale Variablen sind ist klar aber wozu braucht man diesen Befehl
setlocal ENABLEDELAYEDEXPANSION
Tutorial zur FOR-Schleife
Hat der auswirkungen auf meine anderen globalen Variablen ???
nur wenn etwas mit zwei Ausrufezeichen umschlossen ist
wie kann man es beenden ?
setlocal DISABLEDELAYEDEXPANSION
wie kann ich das Script so schreiben das es funktioniert wie in jeder anderen Programmiersprache ?
eine andere Programmiersprache bzw. Scriptsprache benutzen anstatt noch immer auf Batch zu setzen....
Member: rubberman
Solution rubberman Dec 04, 2013, updated at Dec 05, 2013 at 11:48:36 (UTC)
Goto Top
Hallo Zusammen.

Der Errorlevelwert von ROBOCOPY ist genau genommen eine Bitmaske, in der einzelne Fehlerflags gesetzt sind. Genau so kann man also auch die einzelnen Flags checken, nämlich mittels bitweisen Operationen. Eine kleine Subroutine genügt, um nicht jeden einzelnen Errorlevelwert gesondert behandeln zu müssen.
@echo off &setlocal

REM Deine ROBOCOPY-Zeile hierher!
call :robocopycheck %errorlevel% descr

echo Is Error [0/1]: %errorlevel%
echo Description   : %descr%

pause
goto :eof

:robocopycheck robocopy_errorlevel [description_variable_name]
setlocal EnableDelayedExpansion &set /a "return = %~1, err = 0" &set "txt="  
if !return!==0 (set "txt=NO CHANGE   ") else (  
  for %%i in ("COPY" "EXTRA" "MISMATCHES" "FAILS" "FATAL ERROR") do (set "bit!err!=%%~i" & set /a "err += 1")  
  if !return! gtr 1 (set "err=1") else set "err=0"  
  for /l %%i in (0 1 4) do (set /a "bit=return & 1, return >>= 1" &if !bit!==1 set "txt=!bit%%i! + !txt!")  
)
endlocal &if "%~2" neq "" set "%~2=%txt:~0,-3%" &exit /b %err%  

Grüße
rubberman
Member: Viper-Berlin
Viper-Berlin Dec 05, 2013 at 08:59:43 (UTC)
Goto Top
Ja schönen Dank für den Vorschlag Rubberman,

also ich bin leider nicht so fit in CMD ich flück das man auseinander
so das ich es halbwegs verstehe...
vielleicht könntest du die einzelnen Schritte erklären face-wink

@echo off 
REM ### WARUM LOCALE VARIABLEN ?? ###
setlocal 

REM Deine ROBOCOPY-Zeile hierher! 

REM ### wozu steht noch %errorlevel% descr  hinter den Procedure Auruf ? ###
call :robocopycheck %errorlevel% descr 
echo Is Error [0/1]: %errorlevel% 
echo Description   : %descr% 
pause 
goto :eof 
 REM ### wozu brauch ich das robocopy_errorlevel [description_variable_name] hinter dem Procedureaufruf ?? ###
:robocopycheck robocopy_errorlevel [description_variable_name] 
rem wozu brauch ich ein Setlocal ???

REM ### was macht dieses EnableDelayedExpansio genau ? ###
setlocal EnableDelayedExpansion 
REM ### was passiert hier woher bekommt er den Returnwert ? ###
set /a "return = %~1"  
SET  "err = 0"  
set   "txt="   


if !return!==0 (
    set "txt=NO CHANGE   "  
    ) else ( 
         for %%i in ("COPY" "EXTRA" "MISMATCHES" "FAILS" "FATAL ERROR") do (  
               set  "bit!err!=%%~i"   
               REM OK ADDIERE NUMERISCHEN ERRORCOUNTER
               set  /a "err += 1"  
    ) 
   REM --- OK Fehlerauswertung ---
    if  !return! gtr 1 (
        set "err=1"   
        ) else ( 
              set "err=0"   
     )
    REM ### was passiert hier ? ###
     for /l %%i in (0 1 4) do (
          set /a "bit=return & 1, return >>= 1"   
          if !bit!==1 (
              set "txt=!bit%%i! + !txt!"  
          )
      ) 
) 
endlocal 
REM ### was passiert hier ? ###
if "%~2" neq "" (  
    set "%~2=%txt:~0,-3%"  
    exit /b %err%
)
goto :eof 


Danke face-wink
Vipy
Member: rubberman
Solution rubberman Dec 05, 2013, updated at Dec 06, 2013 at 14:00:01 (UTC)
Goto Top
Hallo Viper-Berlin.

Ich weiß nicht, ob ich deine Fragen so umfangreich beantworten kann, dass es hier nicht den Rahmen sprengt, du es aber wenigstens verstehst. Ich versuch's trotzdem und beziehe mich mit der Zeilennummerierung auf deinen aufgedröselten Code.

Zeile 4
Das setlocal ist nicht unbedingt notwendig, hat sich aber eingebürgert und bewährt. Viele Scripter rufen ihre Batchdateien aus der Kommandozeile auf um sie zu debuggen. Vorteil ist, dass sich auch bei einem Syntaxfehler das Fenster nicht sofort schließt und man so erkennt, wo der Hase im Pfeffer liegt. Wenn ein Script mehrere Male aus dem gleichen CMD Fenster aufgerufen wird, so bleibt der Wert von Variablen aus dem vorangegangenen Aufruf erhalten. Das führt ggf. zu Nebenwirkungen beim erneuten Aufruf. Das setlocal am Anfang des Codes schafft da Abhilfe. Ein endlocal muss am Ende nicht im Code stehen, da dieses implizit bei Beendigung des Batchcodes für jedes setlocal ausgeführt wird.

Zeile 9
%errorlevel% und descr werden der Prozedur auf diese Weise als Argumente übergeben. Dabei enthält %errorlevel% den Rückgabewert deines ROBOCOPY Aufrufs und descr ist der Variablenname, dem letztlich in der Prozedur die Beschreibung, die sich aus dem Errorlevelwert ergibt, zugewiesen werden soll.

Zeile 15
:robocopycheck ist der Name der Prozedur, also das Einsprunglabel. Labelnamen werden nur bis zum ersten Leerzeichen bewertet (es gibt noch ein paar weitere Abbruchzeichen). Alles was danach kommt ist wie ein Kommentar anzusehen. Ich habe hier robocopy_errorlevel und [description_variable_name] hinter das Label geschrieben, um dir eine Hilfestellung zu geben, welche Argumente an die Prozedur übergeben werden müssen (ohne eckige Klammern) oder dürfen (mit eckigen Klammern).

Zeile 19
Das setlocal EnableDelayedExpansion schaltet die verzögerte Variablenerweiterung ein.
In einer Kommandozeile oder einem in Klammern eingefassten Block von Kommandozeilen (zB. in einer FOR Schleife) werden normale Umgebungsvariablen nur einmal zum Wert aufgelöst, und zwar noch bevor die Zeile/der Block ausgeführt wird. Das EnableDelayedExpansion verzögert diese Auflösung, sodass die Werte zur Laufzeit der Zeile/des Blocks abgreifbar sind. Die umschließenden Prozentzeichen für die Variable sind dabei durch Ausrufezeichen zu ersetzen.
Beispiel zur Verdeutlichung:
@echo off

setlocal
set "n=vorher"  
for /l %%i in (0 1 4) do (
  set "n=%%i"  
  echo %n%
)
endlocal

echo ~~~~~~~~~

setlocal EnableDelayedExpansion
set "n=vorher"  
for /l %%i in (0 1 4) do (
  set "n=%%i"  
  echo !n!
)
endlocal

pause

Zeile 21
Da der Prozedur Argumente übergeben wurden, lassen sich diese auch abrufen. Das erste Argument wird durch %1 repräsentiert, das zweite durch %2 usw. Die Tilde (~) entfernt eventuell vorhandene umschließende Anführungszeichen. Letztlich erhält die Variable return also den vorher übergebenen Rückgabewert (Errorlevel) deines ROBOCOPY Aufrufes zugewiesen.

Zeile 41 ff
Hier wird's interessant und ich muss etwas weiter ausholen. Wenn ich oben von Bitmaske und bitweisen Operationen gesprochen habe, bedeutet das, dass hier der ROBOCOPY Rückgabewert (repräsentiert durch Variable return) als binäre Zahl betrachtet werden muss. Dieser Rückgabewert ist nämlich aus Zweierpotenzen zusammengesetzt, wobei jede dieser Zweierpotenzen einen booleschen Wert (0 für FALSCH bzw. 1 für WAHR) repräsentiert. Errorlevelwerte können eine Breite von 32 Bit haben, im Fall von ROBOCOPY reicht es aber die 5 niedrigsten Bits zu betrachten. Warum, ergibt sich aus der Tatsache, dass der schwerwiegendste Fehler den Wert 2^4 (16) hat.
Nehmen wir an dass ROBOCOPY den Wert 5 als Errorlevel zurück gegeben hat, dann ergibt sich in binärer Schreibweise der Wert 00101.
Dröseln wir das mal in einer Tabelle auf:
Bit 0 0 1 0 1
Wert 2^4 (16) 2^3 (8) 2^2 (4) 2^1 (2) 2^0 (1)
Bedeutung FATAL
ERROR
FAILS MISMATCHES EXTRA COPY
Ich nehme an, jetzt wird das Prinzip schon mal deutlich. Wie du siehst, sind im Fall von Errorlevel 5 die Flags für MISMATCHES und COPY gesetz.
Stellt sich nur noch die Frage, wie man diese Flags in einem Batchcode vernünftig auswerten kann face-wink
Dabei helfen zwei bitweise Operationen:

1. Shift-Right (>>)
Dabei werden die einzelnen Bits eines binären Ausdrucks um die angegebene Anzahl Stellen nach rechts verschoben. Die entsprechenden niedrigsten, rechten Bits werden eliminiert, während links mit Nullen aufgefüllt wird. Bleiben wir beim Beispiel 00101 dann ergäbe >>1 die Zahl 00010, ein >>2 ergäbe 00001 usw.

2. Bitweises UND (&)
Die Regel dabei ist:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
Diese Regel wird für jedes Bit einer binären Zahl ausgeführt. Im Code verwende ich immer das & 1 mit dem immer nur das niedrigste Bit mit 1 verglichen wird.

Die FOR /L Schleife sorgt dafür, dass diese Operationen 5 mal in Folge ausgeführt werden.
Für das Beispiel 00101 sieht das so aus:
     00101
&    00001
----------
     00001 -> Bit ist gesetzt

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     00101 >>1
----------
     00010
&    00001
----------
     00000 -> Bit ist nicht gesetzt

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     00010 >>1
----------
     00001
&    00001
----------
     00001 -> Bit ist gesetzt

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     00001 >>1
----------
     00000
&    00001
----------
     00000 -> Bit ist nicht gesetzt

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     00000 >>1
----------
     00000
&    00001
----------
     00000 -> Bit ist nicht gesetzt
Also wird jedes Bit von rechts nach links einzeln betrachtet.
Im Code oben wird einfach je nachdem, ob ein Bit gesetzt ist oder nicht, der entsprechende Text hizugefügt.

Zeile 50 ff
Falls ein zweiter Parameter übergeben wurde, so wird diesem der entsprechende Text zugewiesen (also die Beschreibung für den ROBOCOPY Errorlevelwert).
Das exit /b beendet die Prozedur, wobei ein Wert übergeben werden kann, der im Hauptcode als Errorlevel abrufbar ist.

So, das war viel Text und viel Information. Ich hoffe es trägt auch zum Verständnis bei face-smile

Grüße
rubberman
Member: Viper-Berlin
Viper-Berlin Dec 11, 2013 updated at 10:59:04 (UTC)
Goto Top
Sorry Rubberman,
das ich erst jetzt Antworten kann....
Danke für die super Erklärung

ich hätte noch ein Farge zur Setlocal

1. also Setlocal macht alle Variablen in Script local was zu folge hat wenn ich einen Aufruf start irgendwas oder c:\anderescmdscript.cmd
mach das keine Variablen übergeben werden, ich kann somit die gleiche Variable mehrfach benutzen richtig.
2. normalerweise atbeitet man mit lokalen Variablen in Proceduren und übergibt diese dann an global Variablen ? wie funst das in CMD
da kommt wieder nur Mist raus ????
3. Also ich würde gerne Proceduren schreiben die was machen mit localen Variable und dann als RETURNWERT übergeben und in ein globale Variable
den oder die Rückgabewerte schreiben geht das ?
4. hat setlocal einfluss auf SETX ????

echo off
cls
set /A  "glo_a=1" & REM glogale Variable  
set /A  "loc_a=8" & REM globale  Variable die auch unten ein zweites mal benutzt wird  

echo #GLOBAL# global:%glo_a%  

setlocal
     REM local Variable eine andere wie oben da local gleicher name anderer Wert nur in setlocal endlocal gültig
     set /A  "loc_a=2"                                                                                   
     REM **** HIER FEHLER !!! wie bekomme ich Werte in die wirkliche globale Variable glo_a 
     set /A  "glo_a=loc_a + loc_a"  
     echo #SETLOCAL# global:%glo_a% local: %loc_a%
     REM *** PROCEDUREAUFRUF  ist der letzt ein Teil von SETLOCAL ENDLOCAL oder ist die Procedure wieder GLOBAL
     call :test 01
endlocal

REM HIER WIEDER GLOBAL 
echo #GLOBAL RAUS AUS SETLOCAL# global:%glo_a% local: %loc_a% pause
exit

REM  GLOBALE VARIABLE INPROCEDURE ÄNDERN
:test 01
        set /A  "glo_a=loc_a + loc_a + loc_a"  
        echo #PROC# global:%glo_a% local: %loc_a% 
GOTO :EOF

ERGEBNIS: FALCH glo_a hat falschen Wert

#GLOBAL# global:1                                                            OK
#SETLOCAL# global:4 local: 2                                            OK
#PROC# global:6 local: 2                                                    OK
#GLOBAL RAUS AUS SETLOCAL# global:1 local: 8      NOK

REM  hier muss  global 6 stehen und nicht 1


Danke für die Hilfe
Member: rubberman
rubberman Dec 11, 2013, updated at Dec 12, 2013 at 17:48:05 (UTC)
Goto Top
Hallo Viper-Berlin.

Zunächst zu deinem Code.
Ändere Zeile 16 entweder zu
endlocal &set "glo_a=%glo_a%"
oder zu
(
  endlocal
  set "glo_a=%glo_a%"
)
Auch Änderungen von globalen Variablen überleben das endlocal sonst nicht.
Hintergrund ist, dass die CMD mit setlocal ein eigenes Subenvironment schafft, in das vorher gesetzte Variablen zwar vererbt werden, alle in diesem Subenvironment gesetzten oder veränderten Variablenwerte aber nur dort gültig sind.


1. also Setlocal macht alle Variablen in Script local was zu folge hat wenn ich einen Aufruf start irgendwas oder c:\anderescmdscript.cmd
mach das keine Variablen übergeben werden, ich kann somit die gleiche Variable mehrfach benutzen richtig.
So wie ich dich gerade verstehe, stimmt das nicht. Ein Prozess vererbt sein Environment immer an den aufgerufenen Prozess weiter.

Im Fall von START wird ein neuer Prozess erzeugt. Dem wird das beim Aufruf des Befehls gültige Environment vererbt. Wenn das aus einem mit setlocal erzeugten Subenvironment erfolgt, werden also die dort gültigen Variablen vererbt. Der Kindprozess ändert aber nie das Environment des aufrufenden Elternprozesses.

Wenn ein Batch durch seinen Namen aus der Kommandozeile bzw. per CALL aufgerufen wird, verhält sich das etwas anders. Auch hier gilt das derzeit gültige Environment wieder genauso für den aufgerufenen Batch. Hauptunterschied ist aber, dass kein neuer Pozess erzeugt wird, sondern alles in der gleichen Instanz von cmd.exe läuft. So kommt es, dass nach Beendigung der aufgerufenen Batchdatei, Variablen auch weiterhin in der ursprünglichen Batchdatei gültig sind. Verhindern lässt sich das nur durch das setlocal am Anfang der aufgerufenen Batchdatei.

2. normalerweise atbeitet man mit lokalen Variablen in Proceduren und übergibt diese dann an global Variablen ? wie funst das in CMD
da kommt wieder nur Mist raus ????
Eine Möglichkeit habe ich oben schon gezeigt. Es gibt noch weitere. 2 Beispiele.
@echo off &setlocal
set "glob=irgendwas"  
set /a "x=1, y=2"  
call :proc
set /a "glob=%errorlevel%"  
echo %glob%
pause
goto :eof

:proc
setlocal
set /a "loc = x + y"  
(
  endlocal
  exit /b %loc%
)
... was natürlich nur dann funktioniert, wenn der Rückgabewert numerisch und ganzzahlig ist.

Wenn man mal aus einem Block heraus die Subroutine beenden will, wäre auch so etwas mal von Interesse:
@echo off &setlocal
set "glob=irgendwas"  
set /a "x=1, y=2"  
call :proc addiere
echo %glob%
pause
goto :eof

:proc
if "%~1"=="addiere" ( REM ziemlich sinnloses IF Statement, nur zur Verdeutlichung ...  
  setlocal EnableDelayedExpansion
  set /a "loc = x + y"  
  for /f "delims=" %%i in ("!loc!") do (  
    endlocal
    set "glob=%%i"  
  )
)
goto :eof

Dein Punkt 3 sollte damit auch bereits beantwortet sein.

4. hat setlocal einfluss auf SETX ????
Nein. SETX ist ein Programm das Umgebungsvariablenwerte in der Registry festlegt und das Explorer-Environment aktualisiert. Das hat überhaupt nichts miteinander zu tun.

Grüße
rubberman