I was writing this small cmd script at work to test connectivity when users encounter network issues. It runs a few tests and configuration tools that are built into Windows XP to output a textfile that the user can e-mail back to me and my colleague. But the more tools I added into it the more useless the user-friendly messages I printed back to the users became:
Just wait a sec...
Hang on a minute..
Hold that thought..
Working some more..
Our Work is Never Over!
Only the first 3 lines reflect the original script.. You could say I should never turn echo off. But a lot of my users are seriously afraid of the command-line, and they’ll rather pluck their eyes out with a pencil than have to suffer through commands and syntax flashing across the monitor. So @ECHO OFF is the first line in all my scripts. But I need something to prevent the user from closing the window!
I realized this wouldn’t escape my inner geek in a million years and I set out to find a progress bar for Windows XP CMD.
I was not very lucky. I did find this question at stackoverflow.org: How to animate the command line? It points to wget, and yes, the tools of GNU/Linux does have a lot of nice CLI animations without resorting to curses (read: cursor optimization, such as ncurses). Inspired by wget I set out to create my own Progress bar for Windows XP’s CMD, and three hours later voilà:
The text is customizable of course.. :)
The Progress Bar Subroutine for CMD (Windows XP)
Download the Progress Bar Subroutine v2 here: progbar_sub.rar (13KB)
License: GNU Lesser General Public License, version 3
It does not require PowerShell, using only built-in XP functions.
First of all: It is not a real progress bar! It does not calculate the remaining time based on the current I/O, file operations or whatever it is that you do in your program. It is simply a script that counts down from 6 to 1 with the first being 0% and the latter 100% completed based on the number of times called by the program.
It comes in 2 versions: the simple one (progressbar-ez.cmd) and the customizable (progressbar-adv.cmd). The former works best in linear situations where you can just cut and paste the parts into the workflow, such as my network testing script above. The latter is better suited for insertion into larger programs with several routines and subroutines. Simply place the advanced subroutine near the end of file and follow the instructions 0-3. I’ve included a small demonstration called testaction.cmd, which was the basis for the screenshot above. (The color change is not a part of the subroutines..) And remember: Don’t play with your progress bar or you’ll go blind.
Update November 10th 2010: Version 2
After some bugfixes I re-wrote the entire subroutine. Version 2 does not require any configuration whatsoever, but you must remember to use the _returnto parameter when you CALL it; namely the section you want to return to. For example:
this is where something beautiful happens, and you want to show it!
CALL :barloop Section_2
This is another part of the program. Could be anywhere
The .rar package also includes a simple version (cut and paste into a chronological program) and the testaction.cmd demo. The former works best in linear situations where you can just cut and paste the parts into the workflow, such as my network testing script above. The script checks the progress stepper to see what output to show, ranging from 0 (0%) to 10 (100%), and increments by 1 each time the progress bar is called to update.
I’m planning a further release that allows calling the loop with two additional parameters: a) add more than 1 point for this round, and b) manually define a percentage to show; to allow for more versatility.
Update November 11th 2010: Version 3.1 (FINAL)
I sat up last night implementing the planned changes, and this morning I added the last piece of the puzzle to make as much of the progress bar function/subroutine fully configurable (and possible to run without configuration at all). I also removed the "simple edition" which content was added into the readme.txt file instead.
The routine now takes the following parameters: next sub, add and define
CALL :barloop <next_sub> #add #define
You must specify the next sub (required), and you can optionally either a) add to existing or b) manually define progress level, which makes the subroutine a lot more interesting for re-use within the same program. I also tried to implement a parameter to set the header "Current progress:" dynamically, but CMD would not let me input strings unfortunately. Especially since I tried to avoid GOTOs. Please help me out with that one if you’re an NT wizard!
I hope some good will come from this. But first I need dinner!