1

I'm really new to Batch and I was making a game but I was trying to run 2 things at once. For example I wanted to run this:

:loading
CLS
echo LOADING.
TIMEOUT /T 0 > nul
CLS
echo LOADING..

And so forth... But I also wanted to run this at the same time:

:choice
choice /c ab /n /m ">"
if %errorlevel%==1 (goto call)
if %errorlevel%==2 (goto server)

I heard of the "call" command and I searched it up on the internet but couldn't find much that really helped. Any answers would be great, thanks!

Kumquat
  • 52
  • 9
  • Welcome to Stack Overflow. If you found my answer below helpful, please consider marking it as accepted. [See this page](https://meta.stackexchange.com/a/5235/275822) for an explanation why this is important. – rojo Jul 20 '17 at 02:38
  • [Parallel execution of shell processes](https://stackoverflow.com/q/672719/995714), [Waiting for parallel batch scripts](https://stackoverflow.com/q/12577442/995714), [How to run multiple DOS commands in parallel?](https://stackoverflow.com/q/11010834/995714) – phuclv Jul 20 '17 at 02:49

1 Answers1

1

The direct answer to your question is that start /b will let you fork another thread into the same window, so you can have two instructions running at the same time in the same window. The problem with that, though, is that the forked thread will no longer be affected by keystrokes or user input. Anything launched with start /b will run in the background, and will no longer be interactive -- and therefore, no easy way to kill it. You could possibly set up some communication between the parent thread and the child by using waitfor, but that will get pretty convoluted and hard to maintain.

I think a better solution would be for you to use the /t switch in your choice command. That way you can have both a timer and a listener for user input in a single command.

A neat trick you can use as an alternative to clearing the screen on every loop iteration is to output a carriage return to return the text caret to the beginning of the line, and repeatedly overwrite that line while you're waiting for user input. This will let you keep your > as a prompt at the end of the line while adding dots to LOADING..., all without having to include cls in the loop.

Try this script and see whether it provides the user experience you're trying to create.

@echo off & setlocal

echo Press either A for call or B for server.  Do it now.

set "str=LOADING."
rem // capture an extended character as a default option for "choice"
for /f %%I in ('forfiles /p "." /m "%~nx0" /c "cmd /c echo 0x99"') do set "char=%%~I"
rem // capture a carriage return to overwrite the same line
rem // credit: https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/AUXP8XbRAJA
for /f %%a in ('copy /Z "%~dpf0" nul') do set "\r=%%a"

:prompt
setlocal enabledelayedexpansion
rem // Output a carriage return + "Loading..." with increasing dots + ">" without new line
set /P "=.!\r!%str% > " <NUL
endlocal
rem // On timeout, default to a (probably) untypeable character. Add a dot and loop again
choice /t 1 /c ab%char% /d %char% /n /m "" >NUL
if errorlevel 3 (
    set "str=%str%."
    goto prompt
)
echo;
if errorlevel 2 goto server
rem // default is to go to :call

:call
echo I'm at call.
exit /b

:server
echo I'm at server.
exit /b
rojo
  • 24,000
  • 5
  • 55
  • 101