4

I have been trying for days and can seem to get this to work. I found an example but it uses a (CryEcho) which will not work. I just wanted to add this to let the user know something is going on while im pinging IP addresses. I did find some code on here but it was confusing to me since im just starting to mess around with batch files for fun.

Anyway, I wanted to have something that used something like the example below but with text like (Waiting...[spinner]). Thanks!

@echo off
setlocal

set COUNT=0
set MAXCOUNT=10
set SECONDS=1

:LOOP
title "\"
call :WAIT
title "|"
call :WAIT
title "/"
call :WAIT
title "-"
if /i "%COUNT%" equ "%MAXCOUNT%" goto :EXIT
set /a count+=1
echo %COUNT%
goto :LOOP

:WAIT
ping -n %SECONDS% 127.0.0.1 > nul
ping -n %SECONDS% 127.0.0.1 > nul
goto :EOF

:EXIT
title FIN!
endlocal

AND I found this code as well:

@echo off
rem Example showing how to use CryEcho to produce a spinning wheel to show activity.

CryEcho Working ... 
call :DoSomeWork
call :SpinAlive
call :DoSomeWork
call :SpinAlive
call :DoSomeWork
call :SpinAlive
call :DoSomeWork
call :SpinAlive
call :DoSomeWork
call :SpinAlive
call :DoSomeWork
call :SpinAlive
call :DoSomeWork
call :SpinAlive
call :DoSomeWork
call :SpinAlive
call :DoSomeWork

cryecho \s\nFinished.

goto :eof

:DoSomeWork
ping -n 1 localhost > nul
goto :eof

:SpinAlive
if "%Spinner%" == "2" (cryecho \\\b) 
if "%Spinner%" == "3" (cryecho -q "|"\b) 
if "%Spinner%" == "4" (cryecho /\b set Spinner=0) else (cryecho -\b set Spinner=1)
set /A Spinner=%Spinner%+1
goto :eof
demongolem
  • 9,474
  • 36
  • 90
  • 105
SoggyCashew
  • 69
  • 1
  • 4
  • 15
  • I guess this comes down to being able to output a sole carriage-return (without the line feed), which I think is not possible in pure batch without external tools. – Joey Feb 05 '13 at 16:36
  • @Joey All is possible :-) Nearly every character can be created in batch with `forfiles`,`copy` and `prompt` – jeb Feb 05 '13 at 16:53
  • [Very similar](http://stackoverflow.com/q/368041/218597), tho' @jeb's answer is a little neater, IMO. – icabod Feb 05 '13 at 17:46
  • @icabod Yes paxdiabolo uses a `backspace`, but I don't like to embedd a control character into the batch file, as you need a special editor – jeb Feb 05 '13 at 17:58

2 Answers2

10

The main trick is here to move the cursor back on the same line.
This can be done with a carriage return or a backspace characters.

@echo off
setlocal EnableDelayedExpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"

FOR /L %%n in (1,1,10) DO (
    call :spinner
    ping localhost -n 2 > nul
)
exit /b

:spinner
set /a "spinner=(spinner + 1) %% 4"
set "spinChars=\|/-"
<nul set /p ".=Waiting !spinChars:~%spinner%,1!!CR!"
exit /b

The <CR> character is created from the output of copy /z.
The output is done by set /p, as this omits the output of CR/LF at the end.
The !CR! is output each time to force the cursor to move back to the first column.
But as Win7 and Vista removes all whitespaces and also CR from the leading output of set /p, it's placed at the end.

jeb
  • 78,592
  • 17
  • 171
  • 225
  • Nice solution, but on WinXP this outputs `/W` for the `/`, I guess due to the fix for Win7/Vista. A solution (for XP) is to make the set: `=!CR!W!CR!Waiting !spinChars:~%spinner%,1!". Not tried that in Vista/Win7 mind. – icabod Feb 05 '13 at 17:37
  • Thanks, a few questions though. Why does it look like (Waiting /|\W) with a "W" at the end? Also, is the (1,1,10) how many times it spins? – SoggyCashew Feb 05 '13 at 17:40
  • @icabod I fixed the output, @user1875160 `(1,1,10)` lets the `FOR/L` loop count from 1 to 10 – jeb Feb 05 '13 at 17:49
  • icabod, One more question, How can I incorporate this into a menu? I have a menu with 9 choice with goto. Would I have to put the code in each GOTO to show the waiting spinner or can I call the spinner. Can you point me in the right direction? Thanks! – SoggyCashew Feb 05 '13 at 18:31
  • @user1875160: You're better off asking jeb, as he posted the answer :) – icabod Feb 05 '13 at 20:02
0
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
CALL :BACKSPACE $BS
SET /A FULL_COUNT=75
SET /A MAX_COUNT=160
SET /A Spin_Delay=60
SET "_MSG=Process running..."
SET /A CTR=0
IF NOT [%1]==[] SET "_MSG=%~1"
IF NOT [%2]==[] SET /A FULL_COUNT=%2
IF NOT [%3]==[] SET /A SPIN_DELAY=%3
IF %FULL_COUNT% GTR %MAX_COUNT% SET /A FULL_COUNT=%MAX_COUNT%
<nul SET/P="%_MSG%*"
SET "SPINNER=³/Ä\"
FOR /L %%A IN (1,1,%FULL_COUNT%) DO (
  CALL :DELAY %SPIN_DELAY%
  <nul CALL SET/P="%$BS%%%SPINNER:~!CTR!,1%%"
  SET /A CTR=%%A %% 4
)
<nul SET/P="%$BS%*"
ENDLOCAL & EXIT /B %CTR%

:BackSpace
setlocal
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
endlocal&call set %~1=%BS%&exit /b 0

:Delay msec
setlocal
set/a correct=0
set/a msecs=%1+5
if /i %msecs% leq 20 set /a correct-=2
set time1=%time: =%
set/a tsecs=%1/1000 2>nul
set/a msecs=(%msecs% %% 1000)/10
for /f "tokens=1-4 delims=:." %%a in ("%time1%") do (
  set hour1=%%a&set min1=%%b&set sec1=%%c&set "mil1=%%d"
)
if /i %hour1:~0,1% equ 0 if /i "%hour1:~1%" neq "" set hour1=%hour1:~1%
if /i %min1:~0,1% equ 0 set min1=%min1:~1% 
if /i %sec1:~0,1% equ 0 set sec1=%sec1:~1%
if /i %mil1:~0,1% equ 0 set mil1=%mil1:~1% 
set/a sec1+=(%hour1%*3600)+(%min1%*60)
set/a msecs+=%mil1%
set/a tsecs+=(%sec1%+%msecs%/100)
set/a msecs=%msecs% %% 100
::    check for midnight crossing
if /i %tsecs% geq 86400 set /a tsecs-=86400
set/a hour2=%tsecs% / 3600
set/a min2=(%tsecs%-(%hour2%*3600)) / 60
set/a sec2=(%tsecs%-(%hour2%*3600)) %% 60
set/a err=%msecs%
if /i %msecs% neq 0 set /a msecs+=%correct%
if /i 1%msecs% lss 20 set "msecs=0%msecs%"
if /i 1%min2% lss 20 set "min2=0%min2%"
if /i 1%sec2% lss 20 set "sec2=0%sec2%"
set "time2=%hour2%:%min2%:%sec2%.%msecs%"
:wait
  set timen=%time: =%
  if /i %timen% geq %time2% goto :end
goto :wait
:end
for /f "tokens=2 delims=." %%a in ("%timen%") do set num=%%a
if /i %num:~0,1% equ 0 set num=%num:~1%
set/a err=(%num%-%err%)*10
endlocal&exit /b %err%
  • `SET "SPINNER=³/Ä\"` isn't correct. And why are you doing a lot of things while he only needs a spinning wheel? A code-only result isn't suitable here. Some explanation and comment would help – phuclv Jul 09 '16 at 05:15