Progress Indicator For Robocopy File - SS64 Forum

PHOTO EMBED

Fri Aug 26 2022 10:41:20 GMT+0000 (Coordinated Universal Time)

Saved by @pirate

    @echo off
    set "source=YOUR SOURCE HERE"
    set "target=YOUR DESTINATION HERE"
    set "rc=robocopy.exe"
    for /F %%A in ('echo prompt $H ^| cmd') do set "BS=%%A"

    set "rc.command=%rc% "%source%." "%target%." /s"

    REM make the bar as wide as possible
    for /f "usebackq tokens=2" %%a in (`mode con ^| find "Columns:"`) do set /a bar.width=%%a - 3

    REM or you can force the width on the next line (no sanity checking is done on this value)
    REM set "bar.width=80"
    set "bar.char=þ"
    set "bar.backchar=ú"
    set "bar.size=0"
    set "bar.back="
    set "bar.del="
    set "bar.position=0"
    set "bar.position.modifier=0"
    set "bar.check=0"
    set "loop.delay=3"

    set "done=0"
    set "total=-1"
    set "abort="

    set "window.title=%rc%_%date%_%time: =0%"

    echo:START

    REM spawn the robocopy command with a (hopefully) unique window title that we'll need later
    start "%window.title%" /min %rc.command%

    REM find the total number of files, so we can shrink the bar to fit the total, if necessary
    for /f "usebackq tokens=3,4,5 delims= " %%a in (`%rc.command% /l /njh /nfl /ndl ^| find "Files"`) do (
        set /a "total=%%a,done=%%c"
    )

    set /a "bar.check=bar.width / total" 2>nul

    if %bar.check% EQU 1 set /a bar.width=total

    REM draw the empty bar 
    for /l %%a in (1,1,%bar.width%) do (call set "bar.back=%%bar.back%%%bar.backchar%")
    call set "bar.del=%%bar.back:%bar.backchar%=%BS%%%"
    set /p "out=[%bar.back%]%bar.del%" <nul

    set /a loop.delay+=1

    title Please stand by...

    call :loop

    echo:

    if defined abort (echo:ABORT) ELSE (echo:END)

    pause

    goto :EOF
    :::::::::::::::::::::::::::::::::::::::::::::::::::::
    :loop
    :::::::::::::::::::::::::::::::::::::::::::::::::::::

    set bar=

    REM if all the files have been copied, draw a full bar (in case it didn't get filled
    REM on the previous iteration) and exit
    if %done% GEQ %total% (
        title %done% / %total%
        for /l %%a in (1,1,%bar.width%) do call set "bar=%bar.char%%%bar%%"
        call set /p "out=%%bar%%" <nul
        set abort=
        goto :EOF
    )

    REM if the robocopy child process wasn't running on the previous iteration and there
    REM are still files left uncopied then we assume that robocopy died unexpectedly
    if defined abort goto :EOF

    REM check for the robocopy child process (using out "unique" window title)
    tasklist /fi "imagename eq robocopy.exe" /fi "windowtitle eq %window.title%" /fo csv /nh 2>nul | findstr "," >nul

    REM if it's not found, set a flag (it'll be dealt with on the next interation)
    if errorlevel 1 set abort=1 & set loop.delay=1

    REM run a duplicate robocopy process with the "/L" switch to so we can extract
    REM the total number of files and those that have been copied from the output
    for /f "usebackq tokens=3,4,5 delims= " %%a in (`%rc.command% /l /njh /nfl /ndl ^| find "Files"`) do (
        set /a "remain=%%b,done=%%c"
    )

    REM figure out (roughly) how many files need to be copied to increase the progress
    REM bar by one step
    set /a bar.step=(total / bar.width) - 1

    REM in case its less than one...
    if %bar.step% LEQ 0 set bar.step=1

    REM calculate the bar modifier, which takes effect if the total number of files
    REM is significantly lower than the bar width.
    set /a bar.position.modifier=bar.width / total
    if %bar.position.modifier% LEQ 0 set /a bar.position.modifier=1

    REM calculate the position using the number of copied files and the step value
    set /a bar.position=(done / bar.step) * bar.position.modifier

    REM if for some reason the position is greater than the width, fix it
    REM (this would occur if the number of files is not much more than
    REM the defined bar width)
    if %bar.position% GTR %bar.width% set /a bar.position=bar.width

    REM draw the bar (we're redrawing the whole thing on each interation)
    for /l %%a in (1,1,%bar.position%) do call set "bar=%bar.char%%%bar%%%BS%"

    set /p "out=%bar%" <nul 

    title %done% / %total%

    REM delay before interating so that the script doesn't thrash the system
    ping 127.1 -n %loop.delay% -w 1000 >nul

    goto :loop
    :::::::::::::::::::::::::::::::::::::::::::::::::::::
content_copyCOPY

https://ss64.org/viewtopic.php?t