Simple Progress bar demo written in batch

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Simple Progress bar demo written in batch

Post by MigrationUser »

19 Jul 2012 13:11
Gustaaf

Hi all,

Perhaps a progress bar for batch has been achieved before. Here is my contribution for this.
This demo uses a function to detect MSIEXEC running (it does launch it for demo sake), it then displays a progress bar waiting for the MSIEXEC to close..

Code: Select all

@echo off
:: *****************************************************************************
:: * Script Name: DetectMSI_v1.0.cmd                                           *
:: * Author: Gustaaf von Pickartz.                                             *
:: * Date Created: 19th July, 2012.                                            *
:: * Internal Version: Version 1.0                                             *
:: * ------------------------------------------------------------------------- *
:: * Notice:                                                                   *
:: * This program is provided as is and for fair use distribution.             *
:: * Give credit where credit is due to the author in your own script.         *
:: * ------------------------------------------------------------------------- *
:: * Purpose:                                                                  *
:: * Detect current active MSIEXEC instances using a function for repeatable   *
:: * calls within a script and display a progress bar...                       *
:: * ------------------------------------------------------------------------- *
:: * Updated by: -------                                                       *
:: * Date: 19-07-2012                                                          *
:: * Change1: "Initial script version."                                        *
:: * ------------------------------------------------------------------------- *
:: *****************************************************************************
SETLOCAL ENABLEDELAYEDEXPANSION

 SET PRG0=[*         ]
 SET PRG1=[#*        ]
 SET PRG2=[##*       ]
 SET PRG3=[###*      ]
 SET PRG4=[####*     ]
 SET PRG5=[#####*    ]
 SET PRG6=[######*   ]
 SET PRG7=[#######*  ]
 SET PRG8=[########* ]
 SET PRG9=[#########*]
SET PRG10=[##########]
:: Please note there are special ASCII insertions in the SET BKSPC= declaration below. 80x backspace characters are inserted. ASCII Value 08=[BS]
:: Be sure to verify they are still there when you cut and paste from the web with your text editor (Notepad++ or PsPad). Insert them if missing, otherwise this script will not work...
SET BKSPC=

:Begin_Main
  :: For the sake of the demonstration, start MSIEXEC minimized.
  START /MIN MSIEXEC

  :: Call our function.
  CALL :Fnc_Msi

  :: Waste a little time...  
  PING -n 7 localhost >nul  
  ECHO Exited the FIRST MSIEXEC detection function and progress bar demo.
  ECHO.
  ECHO.
  ECHO A function can't be a function if it cannot be re-used right?
  
  :: For the sake of the demonstration, start MSIEXEC minimized.
  START /MIN MSIEXEC
  
  :: Call our function.
  CALL :Fnc_Msi  
  ECHO Exited the SECOND MSIEXEC detection function and progress bar demo.
  echo.
  echo.
  pause
  GOTO :EOF
:: -----------------------------------------------------------------------------

:: Below code is setup to run as a Function to be called anywhere in your script.
:: It will wait 10 loops at 7 sec intervals anytime it is called. Primarily written to detect active MSI installers.
:: The Menu counter and Progress bar is in the function for fun.
::
:: Usage: CALL :Fnc_Msi
2
:Fnc_Msi
       CALL ECHO [.....] %%date%% %%time%% Testing for active MSI instances.

       :catchit
       IF NOT DEFINED CatchMSI SET CatchMSI=0
       IF %CatchMSI% EQU 5 (
          ECHO Waited 5 loops {15sec.} to detect MSI activities. Now resuming further MSI evaluation.
          goto evalmsi
        )
       FOR /F "TOKENS=2* DELIMS=:" %%I IN ('TASKLIST /V /FI "IMAGENAME EQ MSIEXEC.EXE" /FO LIST 2^>NUL ^|FIND /I /V "N/A" ^|FIND /I "WINDOW TITLE:"') DO (SET MSI=%%I)
       IF DEFINED MSI SET MSI_APP=%MSI:~1%
       IF DEFINED MSI_APP goto msi_active
       >NUL PING -n 3 localhost
       SET /A CatchMSI+=1
       goto :catchit

       :evalmsi
       IF NOT DEFINED MSI_APP (
          ECHO [OKAY.] No active MSIEXEC installer running. It is safe to continue.
          SET CatchMSI=
          SET MSI_APP=
          SET CNT=
          SET COUNT=
          SET TIC=
          GOTO :EOF
        )

       :msi_active
       SET CNT=0
       ECHO [ALERT] Installer "%MSI_APP%" is active. Waiting maximum 10 counts.

       :loop
       IF NOT DEFINED COUNT SET COUNT=0
       IF %COUNT% LEQ 9 (SET TIC=0%COUNT%) ELSE (SET TIC=%COUNT%)
       IF %count% EQU 10 (
          <NUL (SET/P Z=[%tic%/10] PROGRESS: !PRG%CNT%!)
          :: Feel free to adjust the PING -n 3 value to say 30sec waits. 
          >NUL PING -n 3 localhost
          TASKKILL /F /FI "WINDOWTITLE eq %MSI_APP%*" >>myprogress.log
          <NUL SET/P Z=%BKSPC%
          SET MSI_APP=
          SET CatchMSI=
          SET MSI_APP=
          SET CNT=
          SET COUNT=
          SET TIC=
          GOTO :EOF
        )
        <NUL (SET/P Z=[%tic%/10] PROGRESS: !PRG%CNT%!)
        :: Feel free to adjust the PING -n 3 value to say 30sec waits. 
        >NUL PING -n 3 localhost
        <NUL SET/P Z=%BKSPC%
          :: Here we write to a log file and call tasklist.exe to do interval checks on the MSIEXEC status.
          :: Demonstrated is that the progress bar is not affected when code is run in the loop. 
          :: Do keep in mind to "suppress to >nul 2>nul" any output that may disrupt the progress bar activty.
          ECHO [%tic%/10] Waiting for "%MSI_APP%" to complete. >>myprogress.log
          TASKLIST.EXE /V | FIND /I "%MSI_APP%">NUL 2>NUL
          IF %ERRORLEVEL% EQU 1 (
             >NUL PING -n 7 localhost
             SET CatchMSI=
             SET MSI_APP=
             SET CNT=
             SET COUNT=
             SET TIC=
             GOTO :EOF
           )
           SET /A CNT+=1
		   SET /A COUNT+=1
       goto loop
GOTO :EOF
:: -----------------------------------------------------------------------------
----------------------------

#2 20 Jul 2012 13:01
bluesxman


There's a script I wrote here (though this was specifically for Robocopy):

https://ss64.org/viewtopic.php?f=2&t=87

The script will probably need BKSP characters putting back in, since the forum software Simon now uses no longer seems to support them.

cmd | *sh | ruby | chef

----------------------------

#3 22 Jul 2012 22:21
Gustaaf


Having a bit more fun with progress bar and animated star.

Before saving this to a CMD script...

Step 1] Create a new CMD script in the "UTF 8" format. (PsPad or Notepad++ editors can do this)
Step 2] Leave an empty blank line on the very first line. The UTF 8 header is stored there.
Step 3] Copy paste the code below.
Step 4] Be sure to "insert" 80x backspace ASCII [https://web.archive.org/web/20080817141 ... /ascii.htm] characters at the SET BKSPC={BkSpChar}
Step 5] Be sure you set your CMD console font to the True Type font, not the raster.

Code: Select all

@echo off
CHCP 65001
:: *****************************************************************************
:: * Author: Gustaaf von Pickartz.                                             *
:: * Date Created: 22nd July, 2012.                                            *
:: * ------------------------------------------------------------------------- *
:: * This program is provided as is and for fair use distribution.             *
:: * Give credit where credit is due to the author in your own script.         *
:: * ------------------------------------------------------------------------- *
:: *****************************************************************************
SETLOCAL ENABLEDELAYEDEXPANSION

:: Progress Bar
 SET PRG0=[░░░░░░░░░░]
 SET PRG1=[▓░░░░░░░░░]
 SET PRG2=[▓▓░░░░░░░░]
 SET PRG3=[▓▓▓░░░░░░░]
 SET PRG4=[▓▓▓▓░░░░░░]
 SET PRG5=[▓▓▓▓▓░░░░░]
 SET PRG6=[▓▓▓▓▓▓░░░░]
 SET PRG7=[▓▓▓▓▓▓▓░░░]
 SET PRG8=[▓▓▓▓▓▓▓▓░░]
 SET PRG9=[▓▓▓▓▓▓▓▓▓░]
SET PRG10=[▓▓▓▓▓▓▓▓▓▓]

:: Star
 SET STR1=/
 SET STR2=--
 SET STR3=\
 SET STR4=^|
  
:: Please note there are special ASCII insertions in the SET BKSPC= declaration below. 80x backspace characters are inserted. ASCII Value 08=[BS]
:: Be sure to verify they are still there when you cut and paste from the web with your text editor (Notepad++ or PsPad). Insert them if missing, otherwise this script will not work...
SET BKSPC=


:Begin_Main
echo.
echo.
Echo Simple Animated star.
FOR /L %%I IN (1,1,400) DO (
<NUL (SET/P Z= PROGRESS: │)
<NUL (SET/P Z=%BKSPC%)
<NUL (SET/P Z= PROGRESS: /)
<NUL (SET/P Z=%BKSPC%)
<NUL (SET/P Z= PROGRESS: ─)
<NUL (SET/P Z=%BKSPC%)
<NUL (SET/P Z= PROGRESS: \)
<NUL (SET/P Z=%BKSPC%)
)

echo.
echo.
Echo Simple Progress bar indicator
FOR /L %%I IN (0,1,10) DO (
IF %%I LEQ 9 (SET TIC=0%%I) ELSE (SET TIC=%%I)
<NUL (SET/P Z=[!TIC!/10] PROGRESS: !PRG%%I!)
>NUL PING -n 2 localhost
<NUL (SET/P Z=%BKSPC%)
)

echo.
echo.
Echo Combined Progress bar and animated star...
FOR /L %%I IN (0,1,10) DO (
IF %%I LEQ 9 (SET TIC=0%%I) ELSE (SET TIC=%%I)
<NUL (SET/P Z=[!TIC!/10] PROGRESS: !PRG%%I!)
<NUL (SET/P Z=%BKSPC%)
    FOR /L %%J IN (1,1,400) DO (
    <NUL (SET/P Z=[!TIC!/10] PROGRESS: !PRG%%I! │)
    <NUL (SET/P Z=%BKSPC%)
    <NUL (SET/P Z=[!TIC!/10] PROGRESS: !PRG%%I! /)
    <NUL (SET/P Z=%BKSPC%)
    <NUL (SET/P Z=[!TIC!/10] PROGRESS: !PRG%%I! ─)
    <NUL (SET/P Z=%BKSPC%)
    <NUL (SET/P Z=[!TIC!/10] PROGRESS: !PRG%%I! \)
    <NUL (SET/P Z=%BKSPC%)
    )
<NUL (SET/P Z=%BKSPC%)
)
----------------------------

#4 23 Jul 2012 11:43
jeb

Why do you try to put the backspace character hardcoded into the batch?
You could create it "on the fly" with a simple trick

Code: Select all

for /F "tokens=1 delims=# " %%a in ('"prompt #$H# & echo on & for %%b in (1) do rem"') do set "DEL=%%a"
echo ab%DEL%c
----------------------------

#5 23 Jul 2012 15:22
Gustaaf

Hi,

I am essentially redrawing the entire printed line, that is why I use 80 backspace. I tried your method, and it does work for a single char deletion.

This also works to set the Backspace Char. Note, I do need 80 characters on 1 line.

Code: Select all

FOR /F "TOKENS=1 DELIMS=# " %%A IN ('"PROMPT #$H# & ECHO ON & FOR %%B IN (1) DO REM"') DO SET "BKSPC=%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A"
I tried to throw %%A in CALL SET BKSPC=%%A%BKSPC% loop using FOR /L %%I in (1,1,80) do (CALL SET "BKSPC=%%A%BKSPC%")
Did not work out, i could not append 80x the %DEL% character as it will do exactly that, delete itself.

Agreed, this would have been more elegant approach.

----------------------------

#6 23 Jul 2012 22:20
jeb
Gustaaf wrote:

I tried to throw %%A in CALL SET BKSPC=%%A%BKSPC% loop using FOR /L %%I in (1,1,80) do (CALL SET "BKSPC=%%A%BKSPC%")
Did not work out, i could not append 80x the %DEL% character as it will do exactly that, delete itself.
No, a backspace can't

Code: Select all

delete
characters in code, only on the screen, but even on the screen the backspace itself doesn't delete anything, it only moves the cursor one character to the left.

Your code can't work, as the call will not have any effect, you need to use two percents around BKSPC

Code: Select all

for /F "tokens=1 delims=# " %%A in ('"prompt #$H# & echo on & for %%b in (1) do rem"') do (
	FOR /L %%I in (1,1,80) do (CALL SET "BKSPC=%%A%%BKSPC%%")
)
But if you need 80 backspaces it seems to be better to use one CR (carriage return) character to move back the cursor to the first position in the line.

Code: Select all

for /F "usebackq" %%a in (`copy /Z "%~dpf0" nul`) DO (
   set "cr=%%a"
)
setlocal EnableDelayedExpansion
echo asfasdhlfashflkashflksa!CR!***
The CR character can only be echo'd or used with delayed expansion, as it will be normally removed in one of the first phases of the parser.

----------------------------

#7 22 Aug 2013 18:16
Richie086


Hi all,

Code: Select all

I get the following error when I try to run this batch script

C:\Users\rjtroiax\Desktop>
'' is not recognized as an internal or external command,
operable program or batch file.
Active code page: 65001


Simple Animated star.
PROGRESS: PROGRESS: PROGRESS:PROGRESS: PROGRESS: PROGRESS:PROGRESS: PROGRESS: PROGRESS:PROGRESS: PROGRESS: PROGRESS:PROGRESS: PROGRESS: PROGRESS:PROGRESS: PROGRESS: PROGRESS:PROGRESS: PROGRESS: PROGRESS:PROGRESS: P
I have saved the file in UTF-8 in Notepad++. I have left the first line blank as instructed. I have changed the font to non raster. I am trying to run the script in Windows Server 2008 R2 x64 if that matters.

----------------------------

#8 23 Aug 2013 08:49
bluesxman


Did you re-insert the BS characters (ASCII 08) as mentioned in the comments near the top?

Last edited by bluesxman (23 Aug 2013 13:31)

cmd | *sh | ruby | chef

----------------------------

#9 23 Aug 2013 15:12
foxidrive


Batch files should be saved as ANSI and a UTF-8 won't work UIAM.

Last edited by foxidrive (23 Aug 2013 15:13)
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Re: Simple Progress bar demo written in batch

Post by MigrationUser »

related: Progress bar using ESENTUTL.exe : oldforum/viewtopic.php?id=1727
Post Reply