2

I'm new to dos 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%
)
Joseph
  • 7,042
  • 23
  • 83
  • 181

4 Answers4

2

ANSI sequences were added as a part of the Redstone Update, so it will only work from Windows 10+


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
ScriptKidd
  • 803
  • 1
  • 5
  • 19
  • 1
    …this is the wrong color! but more importantly, as the OP didn't specify an OS, it is important to note that ANSI escape sequences are not available in earlier versions of Windows, you're using [tag:windows-10]. – Compo May 02 '20 at 10:45
  • 2
    My point, is not that there are alternatives, _I'm sure I could whip one up, (if I was childish enough to need it)_. My point was, that when your solution is limited to only the most recent OS version, and the OP hasn't used a specific version tag, or mentioned it in their title or body text, it isn't clear that your current answer will not work in other versions. Currently, whilst one of the linked pages does mention Windows 10, you'd have to scroll to find it, and you should not expect that of future readers. Just make it clear in your answer, or provide an alternative for earlier OS'es. – Compo May 02 '20 at 11:05
  • @HackingAddict1337. Good2. Can you put the '%' above the 'Processing' word just like in the picture? – Joseph May 03 '20 at 02:48
  • the variable names are self-explanatory, so yes, you can. just don't forget to redirect it to stream3 `>&3`. (the script aborts immediately when ctrl-c is pressed when the bar is loading) – ScriptKidd May 03 '20 at 05:31
  • @HackingAddict1337. I put &3 echo(Percentage: !percentage! % and it runs multiple lines after this – Joseph May 03 '20 at 06:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/213003/discussion-between-hackingaddict1337-and-joseph). – ScriptKidd May 03 '20 at 07:51
  • @HackingAddict1337. Pls check this video link. imgur.com/a/rK6DOQE. I need something like this. The progressbar's number sometimes skips whatever number just like what a normal app do, if the internet goes fast then the loading's number will skip a lot of numbers – Joseph May 03 '20 at 13:09
  • @HackingAddict1337 Did you get it like in the video? – Joseph May 04 '20 at 15:25
  • what's different from my code than the video i've watched a thousand times, are you trying to really `measure` something or just create ascii art? i didn't... what happened to _Let us continue this discussion in chat_? btw, it's better to just `paste` the link into your question – ScriptKidd May 05 '20 at 13:53
  • @HackingAddict1337. I don't know what the video is trying to do. BUT you have seen in the video that the speed of progress is not constant, so how would you accomplish that? – Joseph May 08 '20 at 12:39
  • so you want to change the speed of the progress bar?⊙__⊙ – ScriptKidd May 08 '20 at 12:43
  • @HackingAddict1337. Yes and of course the speed of the progress is not constant, it changes from time to time as what you have seen in that video – Joseph May 08 '20 at 14:42
  • @HackingAddict1337 Did you get it? – Joseph May 09 '20 at 02:43
  • @Compo @Robert I provided an alternative. The new answer is compatible to nearly all versions of windows (where `TIMEOUT` is supported). – ScriptKidd May 23 '20 at 23:48
2

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

)

enter image description here

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...

Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Good but in my pc, it doesn't look like this. It writes a lot of lines – Joseph May 02 '20 at 13:16
  • Are you using Windows 10? Enable Legacy Console as indicated in the answer... You may test it in any other Windows version – Aacini May 02 '20 at 13:17
  • Yes i'm using windows 10. Can i just do it without enabling legacy console? Pls also check the comment i wrote on other people's answers. I think you're missing my number 3 problem there. Thanks – Joseph May 02 '20 at 13:45
  • Sorry, I don't know what you are talking about "my number 3 problem". It is easier to write "my problem is...". Note that I modified my code in order to use Alt.216 and Alt-176 characters. If you want green letters over black background, use `COLOR A` command. – Aacini May 02 '20 at 13:52
  • Here the number 3 problem. The speed of progress bar stick is variable which means the speed per step is not constant. – Joseph May 02 '20 at 14:01
  • By the way, this is the output of your code in my pc. https://imgur.com/yAexJzV – Joseph May 02 '20 at 14:05
  • I am afraid I dont understand. I _assume_ that you will use this method to review the progress of a real process comprised of 200 steps (for example). If each step takes a variable amount of the total, then you just need to specify what is the amount of each step. This is the only way to manage a variable-speed progress bar... I am also using Windows 10 and my code works OK here. I suggest you to enable Legacy Console and test the program (as I said 3 times now). – Aacini May 02 '20 at 14:14
  • I modified the code for "bar with variable steps". Please, review it... – Aacini May 02 '20 at 14:35
  • Question: is this "progress bar" just for fun? It is just a bar that walks on the screen that really measure nothing? If so, just change the 200 steps by the number of characters in the bar. In this way, the bar speed will be constant. Otherwise, if the bar will measure a _real_ process, then there is no way that the bar have a constant speed, unless each one of the 200 steps takes _exactly_ the same time... For example, if each step process a file, then a big file will take more time than a small file... – Aacini May 02 '20 at 14:59
  • Pls check this video link. https://imgur.com/a/rK6DOQE. I need something like this. The progressbar's number sometimes skips whatever number just like what a normal app do, if the internet goes fast then the loading's number will skip a lot of numbers – Joseph May 02 '20 at 15:16
  • Please answer: this is just for fun? Your Batch file is measuring nothing real? – Aacini May 02 '20 at 15:21
  • But you have to make sure that if loading is 70% it looks like the loader 70%. Can you also revise your code. I dont to run legacy console. Just look like the other peoples answers. They did run without legacy console. They run normally. Tnx – Joseph May 02 '20 at 15:30
  • Did you get it like in the video? – Joseph May 04 '20 at 17:00
1

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:

  1. 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:

  2. 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%
  1. The speed of progress bar stick is variable which means the speed per step is not constant.
    that's because of rounding. Nothing we can do about it, except we make processValue equal to barLength or an integer multiple.
Stephan
  • 53,940
  • 10
  • 58
  • 91
  • @HackingAddict1337: if you want to include that into your code, you're welcome. I'll delete my answer then. – Stephan May 02 '20 at 12:22
  • You're code is nearest to the output that i wanted. Just minor fixes needed . 1. You lack the looks of the "measurement bar", this should look like the ALT+176, this is i think this code "echo [%emptybar%]". 2. Another thing you lack is very simple just the percentage, ex: Percentage: 10%. 3. The speed of progress bar stick is variable which means the speed per step is not constant. – Joseph May 02 '20 at 13:13
  • @Stephan i was overcomplicating stuff and now i have a much faster version, i'll post that – ScriptKidd May 02 '20 at 13:16
  • @HackingAddict1337. Great. Just take note of the 3 problems here – Joseph May 02 '20 at 13:17
  • Pls check this video link. https://imgur.com/a/rK6DOQE. I need something like this. The progressbar's number sometimes skips whatever number just like what a normal app do, if the internet goes fast then the loading's number will skip a lot of numbers. Can you also put the 16% above the processing word? Just like in my question/video link here. Then its all good. Thanks – Joseph May 02 '20 at 15:17
  • @Stephan Did you get the video? – Joseph May 04 '20 at 19:03
1

If you want , you can print ascii codes easily with this application :

download url :

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

Community
  • 1
  • 1
Ale865
  • 116
  • 9