I perfectly understand your position as a hobbyist batch programmer, as that is what I'd describe myself as. Most of the scripts I write are games, simply to see what I can achieve. I lack the time to delve deeper into programming, so tinkering with batch is brain excercise to me.YottaByte wrote: ↑29 Jul 2021 06:37I appreciate your professional advice and I understand what you say, but I do not understand the controversy about a "fake progress bar" that delays the execution of the utility by a few seconds instead of focusing on the utility of the utility (forgive the redundancy) .aGerman wrote: ↑29 Jul 2021 04:50This is an important information because it tells a lot about the aim of your utilities. Until now my asumption was that your goal is to develop tools which are helpful to gather information for a user. In this case you should write it from the perspective of the user. As to what I understand now is that you rather try to explore the opportunities of Batch scripting and test your skills. And obviously that's the reason for your "installation" of the scripts, even though they would work without. And that's the reason why you try to simulate a progress bar, even though you're completely reversing the sense of a progress bar. (Calling it a lie sounds harsh, however you know it's the truth.)I make these utilities as entertainment, it is my "game".
Speaking of progress bars:
- Notice the user if and only if there is a risk that the user thinks the script might be frozen. That is, a task takes noticeable longer than 5 seconds.
- In such cases it should be good enough to just print a message like "Please be patient, this might take a while." before you start the time consuming task.
- If you still want to animate something, do it in parallel while the task is running. That's the expection of the users. Once they recognize that you waste their time, they will not use your tool anymore.
- Don't use a progress bar unless you can divide the task into logical subtasks, and you can advance the bar once a subtask is finalized. A progress bar should indicate the current progress of the task. If this is not possible you could still animate something else. Like a spinner:
viewtopic.php?p=59838#p59838
But still only do it if the task takes longer than 5s and definitely only do it at the same time the task is running.
Steffen
Respectfully, I repeat: if anyone is bothered by that little "bar" delay, feel free to edit the batch or not use the utility. It's that easy.
Hey! I need someone to defend me.
Eduardo
Below is an approach to using a spinner animation via a second thread while the main script body still progresses.
Code: Select all
:# Author: T3RRY Created: 03/06/2021
:# - Purpose: Spinner animation for load / waiting indication while script continues to run.
:# - Utilises a second thread to display animation while the main script continues executing.
:# - Execution and termination of the thread is controlled using a value stored in an alternate data
:# stream of this file:. 1 = run ; 0 = stop
@Echo off & CD /D "%~dp0"
======:# Runs spinner Thread on relaunch
If /I "%~1" == "Thread" Goto %1
Cls
====================:# OS Requirement tests
:# Verify NTFS drive
(Echo(verify.NTFS >"%~f0:Status") || (Echo(This file must be located on an NTFS drive as it utilises alternate data streams.&Exit /B 1)
=====:# Store codepage to restore on script completion
For /f "tokens=4 Delims=: " %%1 in ('CHCP')Do Set "active.cp=%%1"
==================:# macros start and stop Thread via t/f flag written to alternate data stream.
:# Start.Thread - Save current Codepage;
:# Remove status thread from this file if present;
:# Notify command has started;
:# Flag status 1 in Stream :status;
:# Use start /b with params to relaunch this script and execute second thread
Set "Start.Thread=(For /F "tokens=2 Delims=:" %%G in ('CHCP')Do Set "restore.CP=CHCP %%G")&((Echo(1)>"%~f0:Stream") & Start /AboveNormal /b "executing." "%~f0" Thread"
:# End.Thread - Flag status 0 in Stream :Status;
:# Execute a small delay to ensure 2nd thread has time to enable cursor display and clear animation.
:# [Delay of approx. 1/66th of a second]
Set "End.Thread=((Echo(0)>"%~f0:Stream")&For /L %%i in (1 1 750)Do ((Call ))"
===:# Usage Examples. Multiple examples used to show thread is suitable for use with
:# commands of any execution time.
:# Example of running spinner animation while another command executes.
:# NOTE: Commands with output must be redirected to a stream or file
:# and output to the console using More or Type AFTER using the 'End.Thread' macro,
:# as the spinner animation moves the cursor and console output that
:# occurs during spinner animation will displace; and be displaced by; the animation.
%Start.Thread% Example 1
For /l %%i in (1 1 100000)Do Set "var=%%i"
%End.Thread%
Echo([%var%] iterations actioned.
Timeout /t 1 > Nul
%Start.Thread% Example 2
For /l %%i in (1 1 10000)Do Set "var=%%i"
%End.Thread%
Echo([%var%] iterations actioned.
Timeout /t 1 > Nul
%Start.Thread% Example 3
Set "var=1"
%End.Thread%
Echo([%var%] iterations actioned.
======================================:# End script cleanup
Powershell -c "remove-item -path '%~nx0' -Stream '*'"
CHCP %active.cp% > nul
Pause
Goto :Eof
===========================================================
:Thread - Animation; spinner
:# Animation sequence. Symbols may not display correctly with certain fonts
:# Recommended font: Lucida Console
:# Alt 205 ═ 186 ║ 187 ╗ 200 ╚ 188 ╝ 201 ╔
:# ╔═╗╔═╗╔═╗╔═╗
:# ║/║║-║║\║║|║
:# ╚═╝╚═╝╚═╝╚═╝
:#
:# Framerate: ~ 25 fps. ('Delay' assigned as 4/100ths of a second.)
Set ^"Params=%*"
Setlocal EnableDelayedExpansion
Set "Params=!Params:%~1 =!"
TITLE !Params!
CHCP 65001 > nul
Set "T2[L]=0" %= Rem Spinner Loop count =%
Set "T2[chars]= |/-\" %= Rem Spinner characters =%
Set "Delay=4" %= Framerate in Centiseconds =%
:# frame control via elapsed time by Dave Benham - https://www.dostips.com/forum/viewtopic.php?f=3&t=4741
For /l %%. in ()Do (
%= Check completion status flagged in status stream of this file; =%
(For /F "UsebackQ Delims=" %%G in ("%~f0:Stream")Do if %%G EQU 0 (
%restore.CP% > nul %= restore codepage =%
Cls
Echo(!Params! Complete. %= Notify completion =%
(TITLE )
Exit %= exit thread =%
))2> nul
%= Calculate time elapsed =%
for /f "tokens=1-4 delims=:.," %%a in ("!time: =0!") do set /a "t2=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100, tDiff=t2-t1"
if !tDiff! lss 0 set /a tDiff+=24*60*60*100
if !tDiff! geq !delay! (
%= delay has expired ; display frame =%
Set /A T2[L]+=1 %= Increment index point of spinner string =%
%= Output Spinner frame. Overwites previous output using saved cursor position =%
For /f "Delims=" %%v in ("!T2[L]!")Do (
Cls
Echo(Executing: !Params!
Echo(╔═╗╔═╗╔═╗╔═╗╔═╗╔═╗
Echo(║!T2[chars]:~%%v,1!║║!T2[chars]:~%%v,1!║║!T2[chars]:~%%v,1!║║!T2[chars]:~%%v,1!║║!T2[chars]:~%%v,1!║║!T2[chars]:~%%v,1!║
Echo(╚═╝╚═╝╚═╝╚═╝╚═╝╚═╝
)
If !T2[L]! EQU 4 Set "T2[L]=0" %= Reset index point of spinner string =%
set /a t1=t2
)
)