Page 2 of 2

Re: Utilities dealing with hosts files, WiFi, and system information

Posted: 29 Jul 2021 09:50
by T3RRY
YottaByte wrote:
29 Jul 2021 06:37
aGerman wrote:
29 Jul 2021 04:50
I make these utilities as entertainment, it is my "game".
This 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.)

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
I 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) .
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. :lol:

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

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