Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
Adrianvdh
- Posts: 177
- Joined: 16 May 2013 13:00
#1
Post
by Adrianvdh » 13 Oct 2013 08:55
Hi everyone...
I have a simple question. I need to run a look and it must have user input to quit when the user enters Q
So i.e:
Code: Select all
:loop
REM some code
echo HELLO
echo press q to quit
REM some sort of set /p= or choice here
if defined VAR goto exit
goto loop
Any idea? Thanks

-
aGerman
- Expert
- Posts: 4743
- Joined: 22 Jan 2010 18:01
- Location: Germany
#2
Post
by aGerman » 13 Oct 2013 09:12
I assume your requirement is not to stop the loop while SET /P or CHOICE is waiting for user input?
Well Batch doesn't support multithreading.
Regards
aGerman
-
penpen
- Expert
- Posts: 2009
- Joined: 23 Jun 2013 06:15
- Location: Germany
#4
Post
by penpen » 13 Oct 2013 11:53
It is not complete impossible, the snake batch game does something similar:
viewtopic.php?f=3&t=4741the pure game code <--> your loop
the game controller code <--> your input part
penpen
-
Adrianvdh
- Posts: 177
- Joined: 16 May 2013 13:00
#5
Post
by Adrianvdh » 13 Oct 2013 14:14
After studying the Snake.bat code carefully for the last 15 minutes I have no idea how it works. I can only pick up small stuff but the other fancy stuff is to
difficult for me :'(.
How do I extract code, if I can from the controller function? i just don't understand that fancy xcopy stuff and the other code.
A bit off topic, how do I learn how to do that fancy stuff? Is there a really well documented website that teaches people?
I have only been playing around and creating batch files for the last 3 years. It is frustrating unable to learn from crap videos on the YouTubes.
Like OMG come on. Where can I learn properly?
Thanks for your time...
-
aGerman
- Expert
- Posts: 4743
- Joined: 22 Jan 2010 18:01
- Location: Germany
#6
Post
by aGerman » 13 Oct 2013 16:50
Forget about the XCOPY. It's a replacement for CHOICE that you don't need since it is available under your OS.
Basically you have to run two instances of your batch file asynchronously. Both instances use a temporary file as an interface for informations. While one instance permanently reads the content of the file in a loop the other instance changes the informations via writing into the file.
Code: Select all
@echo off &setlocal
:: if the batchfile was started with argument ch goto label :_choice
if "%~1"=="ch" goto _choice
:: the interface file
set "interface=%temp%\interface_%time::=_%.tmp"
:: initial values
set /a "var=0"
>"%interface%" echo 0
:: run a second instace of the batch file with argument ch
start "" cmd /c "%~f0" ch
:loop
:: read the value from the interface file
2>nul (<"%interface%" set /p "n=")
2>nul set /a "var=%n%"
:: display it (as an example)
echo value in the interface file: %var%
:: check the value
if "%var%"=="1" goto _exit
:: some other code here
:: iterate
goto loop
:_exit
:: delete the interface file
del "%interface%"
:: just to see what happened
echo q was entered
pause
goto :eof
:_choice
:: choice command
choice /c q /n /m "press q to quit"
:: if q was entered overwrite the interface file with value 1
>"%interface%" echo 1
goto :eof
The code of dbenham is much more complex for safe writing and reading and to enable the execution of both instances in the same window.
Regards
aGerman
-
Adrianvdh
- Posts: 177
- Joined: 16 May 2013 13:00
#7
Post
by Adrianvdh » 14 Oct 2013 07:37
Thanks I will test that in a sec but how can I use xcopy instead choice?
Mainly for menu?
Any idea? Cause i need my batch file to support XP
-
einstein1969
- Expert
- Posts: 976
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
#8
Post
by einstein1969 » 14 Oct 2013 09:24
Hi,
try
Code: Select all
@echo off &setlocal
:: if the batchfile was started with argument ch goto label :_choice
if "%~1"=="ch" goto _choice
:: the interface file
set "interface=%temp%\interface_%time::=_%_%random%.tmp"
:: initial values
set "Oldvar= "
set "var="
>"%interface%" echo(%var%
:: run a second instace of the batch file with argument ch
start "" /B cmd /c "%~f0" ch
:loop
:: read the value from the interface file
2>nul (<"%interface%" set /p "n=")
2>nul set "var=%n%"
:: display it (as an example)
If Not "%Oldvar%" == "%Var%" (
echo value in the interface file changed to: %var%
set "OldVar=%var%"
)
:: check the value
if /I "%var%"=="q" goto _exit
:: some other code here
:: passive wait com3 about 250 ms ping about < 100 ms
ping 127.0.0.1 -n 1 -w 1 >nul
echo(>Com3:
:: iterate
goto loop
:_exit
:: delete the interface file
del "%interface%"
:: just to see what happened
echo q was entered
pause
goto :eof
:_choice
:: choice command
rem choice /c:q /n "press q to quit"
set "Key="
for /f "delims=" %%A in ('xcopy /w "%~f0" "%~f0" 2^>nul') do if not defined key set "key=%%A"
set "key=%key:~-1%"
rem echo "%key%" & pause
::overwrite the interface file with value of key
>"%interface%" echo(%key%
:: optional close if q key pressed
if /I Not "%key%" == "q" goto :_choice
goto :eof
Einstein1969
-
Adrianvdh
- Posts: 177
- Joined: 16 May 2013 13:00
#10
Post
by Adrianvdh » 14 Oct 2013 11:53
So aGerman... Is it safe for me to take out the beep character?
Something like this? (Sorry I do not know how to add color/colour tags in code tags?)
:choice
setlocal DisableDelayedExpansion
set "n=0" &set "c=" &set "e=" &set "map=%~1" &set beep=%~2"
if not defined map endlocal &exit /b 0
for /f "delims=" %%i in ('2^>nul xcopy /lw "%~f0" "%~f0"') do if not defined c set "c=%%i"
set "c=%c:~-1%"
if defined c (
for /f delims^=^ eol^= %%i in ('cmd /von /u /c "echo(!map!"^|find /v ""^|findstr .') do (
set /a "n += 1" &set "e=%%i"
setlocal EnableDelayedExpansion
if /i "!e!"=="!c!" (
echo(!c!
for /f %%j in ("!n!") do endlocal &endlocal &exit /b %%j
)
endlocal
)
)
endlocal & if "!beep!"=="0" <nul set /p "=" &goto choice
-
aGerman
- Expert
- Posts: 4743
- Joined: 22 Jan 2010 18:01
- Location: Germany
#11
Post
by aGerman » 14 Oct 2013 12:56
Looks OK to me unless you missed a quotation mark (
&set "beep=%~2"). Just enclose the IF statement into parentheses to not confuse the command interpreter where the next ampersand belongs to.
Code: Select all
endlocal &(if "!beep!"=="0" <nul set /p "=") &goto choice
Regards
aGerman