I want to use a real time progress bar where it updates as code is written or installing something or loading a file.
Example:
@echo off
:main
echo Updating file...
[PROGRESS BAR HERE]
The "PROGRESS BAR HERE" indicates the part that I want the real time progress bar to be placed at.
Just a skelleton. Adapt as needed.
The basic idea is to output the line with the progress bar with an ending carriage return to return to the start of the line and be able to repaint the next state over the previous one.
All "problematic" code wrapped into subroutines so you only need to call :drawProgressBar percentValue "operationText"
@echo off
setlocal enableextensions disabledelayedexpansion
for /l %%f in (0 1 100) do (
call :drawProgressBar %%f "up test with a long text that will not fit on screen unless you have a lot of space"
)
for /l %%f in (100 -1 0) do (
call :drawProgressBar %%f "going down test"
)
for /l %%f in (0 5 100) do (
call :drawProgressBar !random! "random test"
)
rem Clean all after use
call :finalizeProgressBar 1
call :initProgressBar "|" " "
call :drawProgressBar 0 "this is a custom progress bar"
for /l %%f in (0 1 100) do (
call :drawProgressBar %%f
)
endlocal
exit /b
:drawProgressBar value [text]
if "%~1"=="" goto :eof
if not defined pb.barArea call :initProgressBar
setlocal enableextensions enabledelayedexpansion
set /a "pb.value=%~1 %% 101", "pb.filled=pb.value*pb.barArea/100", "pb.dotted=pb.barArea-pb.filled", "pb.pct=1000+pb.value"
set "pb.pct=%pb.pct:~-3%"
if "%~2"=="" ( set "pb.text=" ) else (
set "pb.text=%~2%pb.back%"
set "pb.text=!pb.text:~0,%pb.textArea%!"
)
<nul set /p "pb.prompt=[!pb.fill:~0,%pb.filled%!!pb.dots:~0,%pb.dotted%!][ %pb.pct% ] %pb.text%!pb.cr!"
endlocal
goto :eof
:initProgressBar [fillChar] [dotChar]
if defined pb.cr call :finalizeProgressBar
for /f %%a in ('copy "%~f0" nul /z') do set "pb.cr=%%a"
if "%~1"=="" ( set "pb.fillChar=#" ) else ( set "pb.fillChar=%~1" )
if "%~2"=="" ( set "pb.dotChar=." ) else ( set "pb.dotChar=%~2" )
set "pb.console.columns="
for /f "tokens=2 skip=4" %%f in ('mode con') do if not defined pb.console.columns set "pb.console.columns=%%f"
set /a "pb.barArea=pb.console.columns/2-2", "pb.textArea=pb.barArea-9"
set "pb.fill="
setlocal enableextensions enabledelayedexpansion
for /l %%p in (1 1 %pb.barArea%) do set "pb.fill=!pb.fill!%pb.fillChar%"
set "pb.fill=!pb.fill:~0,%pb.barArea%!"
set "pb.dots=!pb.fill:%pb.fillChar%=%pb.dotChar%!"
set "pb.back=!pb.fill:~0,%pb.textArea%!
set "pb.back=!pb.back:%pb.fillChar%= !"
endlocal & set "pb.fill=%pb.fill%" & set "pb.dots=%pb.dots%" & set "pb.back=%pb.back%"
goto :eof
:finalizeProgressBar [erase]
if defined pb.cr (
if not "%~1"=="" (
setlocal enabledelayedexpansion
set "pb.back="
for /l %%p in (1 1 %pb.console.columns%) do set "pb.back=!pb.back! "
<nul set /p "pb.prompt=!pb.cr!!pb.back:~1!!pb.cr!"
endlocal
)
)
for /f "tokens=1 delims==" %%v in ('set pb.') do set "%%v="
goto :eof
It is much simpler to show the progress bar in the Window title:
@echo off
setlocal EnableDelayedExpansion
rem Count the number of files in this dir (just as an example)
set n=0
for %%f in (*.*) do set /A n+=1
rem Fill "bar" variable with 70 characters
set "bar="
for /L %%i in (1,1,70) do set "bar=!bar!X"
rem Fill "space" variable with filler spaces
set "space="
for /L %%i in (1,1,110) do set "space=!space!_"
rem "Process" the files and show the progress bar in the title
set i=0
echo Processing files:
for %%f in (*.*) do (
set /A i+=1, percent=i*100/n, barLen=70*percent/100
for %%a in (!barLen!) do title !percent!%% !bar:~0,%%a!%space%
echo !i!- %%f
ping -n 1 localhost > NUL
)
title MS-DOS
Perhaps you have to adjust the lenght of bar and space variables a little...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With