Reputation: 7785
I'm new to Windows batch commands and I want to achieve the progress bar like in the picture.
First you have to initialize the process value and the calculate the percentage of it and you have to display it using the progress bar.
You can do Alt+219 and Alt+176 for progress bar
Here's what i have done so far.
echo off
cls
SetLocal EnableDelayedExpansion
set processValueString=200
set a/ processValue=200
set a/ percentage=0
echo Process value: %processValueString%
for /l %%a in (1,1, %processValue%) do (
set a/ percentage = %%a / %processValue% * 100
echo Percent: !percentage! %
echo Processing: !a! / %processValue%
)
Upvotes: 2
Views: 9517
Reputation: 851
Use a combination of ANSI sequences and the ability of FORFILES
to print ASCII characters
@echo off
^
%=-----------DO NOT REMOVE THIS LINE-----------=%
Y
%= Y to abort when Ctrl-C is pressed =%
%= N to ignore =%
SETLOCAL EnableDelayedExpansion
::Defaults
( set LF=^
%=-----------DO NOT REMOVE THIS LINE-----------=%
)
FOR /F %%C in ('copy /Z "%~f0" nul') do set "CR=%%C"
FOR /F %%E in ('prompt $E ^& ^<nul cmd /k') do set "ESC=%%E"
::SETTINGS
color a
>nul chcp 65001
mode CON: COLS=120 LINES=31
::INITIALIZE
call :init 0xDB] 0xB0 40 200
echo Starting at %time%
<nul set/p=[
>nul 2>nul call :progessBar
echo Finished at %time%
exit /b
:init bar tbd length processvalue
::Custom parameters defined by user
set "bar=%~1"
set "tbd=%~2"
set /a "barlength=%~3"
set /a "processvalue=%~4"
::Default values
if NOT DEFINED bar set "bar=0xDB"
if NOT DEFINED tbd set "tbd=0xB0"
::Set bar & tbd
>hex.tmp <hex.tmp (
FOR %%V in (bar tbd) do (
FORFILES /P "%~dp0." /M "%~nx0" /C "cmd /c echo(!%%V!"
set/p"%%V=" CLEAR VARIABLE
set/p"%%V=" SET VARIABLE
))
del hex.tmp
exit /b
:main
>&3 (
echo(
for /L %%N in (0 1 %barlength%) do echo(!LF!%ESC%[2A%ESC%[%%NC%tbd%
for /L %%N in (0 1 %processvalue%) do (
set/ashowBar=%%N*barlength/processvalue,percentage=%%N*100/processvalue
echo(Percent: !percentage!%%!LF!Processing: %%N / %processvalue%!LF!%ESC%[3A%ESC%[!showBar!C%bar%
)
echo(!LF!
)
exit /b
:progessBar
<"%~f0" call :main
Sources:
Edit: This answer is limited to 1 bar/second, but is compatible across all versions of windows from 7. (On some the /NOBREAK
switch is unsupported.)
At DosTips, @Aacini discovered TIMEOUT
redirected to CON
brings the cursor home! @jeb also showed that the output can be eliminated via piping |
(normally TIMEOUT
does not support piping, so SET /P
is used.) However, it is (nearly) impossible to remove the countdown at the top.
@echo off
====SETLOCAL EnableDelayedExpansion EnableExtensions
cls
::SETTINGS
color a
>nul "%__APPDIR__%CHCP.COM" 65001
"%__APPDIR__%MODE.COM" CON: COLS=120 LINES=31
::INITIALIZE
::Custom parameters defined by user
set "bar_ASCII=0xDB"
set "tbd_ASCII=0xB0"
set/a"#len=40,#totalValue=200,#newlines=1" %====# of newlines to echo before progressBar, >0====%
::DEFAULTS
set "overwrite=x"
FOR /L %%# in (1,1,6) do set "overwrite=!overwrite!!overwrite!"
%= CLEAR VARIABLES =%
set "loaded="
set "remain="
set "progressBar="
::Set LOADED & REMAIN
>hex.tmp <hex.tmp (
"%__APPDIR__%FORFILES.EXE" /P "%~dp0." /M "%~nx0" /C "cmd /c echo(!bar_ASCII!!tbd_ASCII!"
set/p"=" SKIP empty line
set/p"_=" GET 2nd line
)
del hex.tmp
set "loaded=!_:~0,1!"
set "remain=!_:~1!"
::Set $NEWLINES
FOR /L %%L in (2,1,%#newlines%) do set ^"$newlines=!$newlines!^
%====DO NOT REMOVE ME====%
"
echo(
for /L %%N in (0,1,%#len%) do set "progressBar=!progressBar!!loaded!"
for /L %%N in (0,1,%#totalValue%) do (
set/a"percentage=%%N*100/#totalValue"
echo(!$newlines!
echo(Percent: !percentage!%%
echo(Processing: %%N / %#totalValue%
echo(!progressBar:~0,%%N!
>con "%__APPDIR__%TIMEOUT.EXE" /t 1 /nobreak %====Time delay in SECONDS, do not set to 0====%|"%ComSpec%"/Q /C "FOR /F %%C in ('copy /Z "%~f0" nul') do set/p"=_%%C%overwrite%""
)
====ENDLOCAL
exit /b
Upvotes: 2
Reputation: 126
If you want , you can print ascii codes easily with this application :
https://mega.nz/file/2AZA3Y5T#y8z1aIKJHPiHmnlkgv-dYmn0J2fozz83uGdXS7umyLE
There are also a lot of characters for progress bars.
the syntax is simple :
char [ascii code] [ascii code]
For example:
char 186 186 201 186
You can also add empty characters :
char 186 " " 186
I hope it helps
Upvotes: 1
Reputation: 67256
This works here (very fast!):
EDIT: Code modified for "bar with variable steps"
@echo off
SetLocal EnableDelayedExpansion
rem Define the "amounts" of each one of the (7) steps that comprise this job
set "amounts= 10 6 2 9 3 7 4"
set width=60
set "off="
set "on="
for /F "tokens=1,2" %%X in ('FORFILES /M "%~nx0" /C "cmd /c echo 0xDB 0xB0"') do (
for /L %%i in (1,1,%width%) do set "on=!on!%%X" & set "off=!off!%%Y"
)
rem Get CR, BS and TAB ASCII control characters:
for /F %%a in ('copy /Z "%~f0" nul') do set "CR=%%a"
for /F %%a in ('echo prompt $H ^| cmd') do set "BS=%%a"
set "TAB="
rem First, try the method for Windows XP
for /F "skip=4 delims=pR tokens=2" %%a in ('reg query hkcu\environment /v temp' ) do set "TAB=%%a"
rem Then, the method for newer versions
rem http://www.dostips.com/forum/viewtopic.php?f=3&t=1733&p=6840#p6853
for /F "tokens=2 delims=0" %%a in ('shutdown /? ^| findstr /BC:E') do if not defined TAB set "TAB=%%a"
rem String to go up one line in SET /P command
set "LineUp=%TAB%!BS!!BS!!CR!"
cls
echo Percentage of values processed
echo/
echo %TAB%%off%
echo %TAB%Percent: 0%%
echo %TAB%Processing: 0/%processValue%
set /A "processValue=0, summa=0"
for %%a in (%amounts%) do set /A processValue+=%%a
for %%N in (%amounts%) do (
set /A "summa+=%%N, Percent=summa*100/processValue, PercentOn=Percent*width/100
for %%i in (1,1,4) do set /P "=.!LineUp!" < nul
for %%p in (!PercentOn!) do echo %TAB%!on:~0,%%p!
echo %TAB%Percent: !Percent!%%
echo %TAB%Processing: !summa!/%processValue% (current: %%N^)
timeout /T %%N > nul
)
For details on the method to "go up one line", see Move cursor to any position using just ECHO command
NOTE: The method to move cursor up one line works in all Windows versions excepting Windows 10 using the new console. You need to enable "Legacy mode" in the cmd.exe window console in order for this method to work...
Upvotes: 2
Reputation: 56228
With some minor changes to HackingAddict1337's code, it's possible to have a fixed (choosable) total length of the bar:
@echo off
cls
SETLOCAL EnableDelayedExpansion
set /a "processValue=200"
set "bar=0xDB" Character used by progress bar (SUPPORTS HEX)
set "tbd=0xB0"
set "barLength=40"
( set LF=^
%=-----------DO NOT REMOVE THIS LINE. the LF variable is for future use in a function, it's currently useless-----------=%
)
FOR /F %%B in ('FORFILES /P "%~dp0." /M "%~nx0" /C "cmd /c echo(!bar!"') do set "bar=%%B"
FOR /F %%B in ('FORFILES /P "%~dp0." /M "%~nx0" /C "cmd /c echo(!tbd!"') do set "tbd=%%B"
FOR /F %%B in ('copy /Z "%~f0" nul') do set "CR=%%B"
FOR /F %%B in ('prompt $E ^& ^<nul cmd /k') do set "ESC=%%B"
for /l %%N in (0,1,%barLength%) do set "emptybar=!emptybar! "
echo Starting at %time%!LF!
for /l %%N in (0 1 !barLength!) do echo(!LF!%ESC%[2A%ESC%[%%NC%tbd%
for /L %%N in (0 1 %processValue%) do (
set /a showBar=%%N*barLength/processValue
set /a percentage=%%N*100/processValue
echo(Processing: %%N / %processValue% = !percentage!%%!LF!%ESC%[2A%ESC%[!showBar!C%bar%
ping -4 -n 1 127.0.0.1 >nul
)
echo !LF!Finished at %time%
pause>nul
ENDLOCAL
(adapted to HackingAddicts faster code)
Joseph's concerns:
You lack the looks of the "measurement bar", this should look like the ALT+176, this is I think this code "echo [%emptybar%]".
adapted to look as you want it:
Another thing you lack is very simple just the percentage, ex: Percentage: 10%.
also adapted:
Starting at 15:58:44,10
██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
Processing: 32 / 200 = 16%
processValue
equal to barLength
or an integer multiple. Upvotes: 1