0

I need my code to loop through a subroutine until a key is pressed. I have no idea how to do this. Any help?

Jonathan Patton
  • 39
  • 1
  • 1
  • 1
  • 1
    Hi Jonathan, Stack Overflow works best for cases where you've tried something and have become stuck. Do you have any code you can add in here to give us an idea on where you're stuck? See [ask] for details. – jamesmortensen Sep 01 '14 at 02:44
  • Check out this Stack Overflow post: http://stackoverflow.com/questions/1223721/in-windows-cmd-how-do-i-prompt-for-user-input-and-use-the-result-in-another-com – jamesmortensen Sep 01 '14 at 02:45

5 Answers5

3

you could use the timeout and default extension for the Choice command EX:

:start
@echo off
cls
:loop1 
cls
echo press 1 for option 1 
echo press 2 for option 2 
echo press 3 for option 3 
echo press any other number key to tell the date
echo.
echo %time%
choice /t 1 /c 123456789q /d q >nul
if %errorlevel% EQU 10 goto loop1
if %errorlevel% EQU 1 goto 1
if %errorlevel% EQU 2 goto 2
if %errorlevel% EQU 3 goto 3
if %errorlevel% GEQ 4 goto end
goto loop1
:1
echo.
echo.
echo option 1 
echo.
pause 
exit 
:2
echo.
echo.
echo option 2
echo.
pause 
exit 
:3
echo.
echo.
echo option 3
echo.
pause 
exit 
:end
echo %date%
pause
Exit

in this case the Choice command is automatically selecting Q as the default choice every 1 second so if the user typed Q it'll just skip 1 second in the loop. However if they type any number key besides 1, 2, 3 the program will tell the date. if the user types 1 the program will do option 1 and same for 2 and 3 any other key won't do anything. The only downside is you have to wait 1 second max and you have to reserve one key for the loop

King Mat
  • 91
  • 1
  • 6
3

Or you can just type this:

@echo off
color 0a
title KeyStrokeSim
goto Start

:Start
cls
echo Press D or F to continue...
choice /c df /n
if %errorlevel%==1 goto Finished
if %errorlevel%==2 goto Finished

:Finished
echo You have Pressed D or F!
pause
goto Start
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • It only Detects key press inside the batch file so you have to click on the window and press the key due to the type of method ;D – JebTheSheep Oct 08 '17 at 08:45
1

Late answer, but DOES NOT use choice or SET /P, but replace instead.
This is the idea:

@echo off
SETLOCAL EnableDelayedExpansion
echo Press any key...

>keystroke.txt replace ? . /u /w
FOR /F delims^=^ eol^= %%K in (
'2^>nul findstr /R "^" "keystroke.txt"'
) do set "key=%%K"

del /f /q "keystroke.txt"
echo You pressed: [!key!]

The script takes advantage of the /W option of REPLACE.

Edit: Now supports ; (default eol)

ScriptKidd
  • 803
  • 1
  • 5
  • 19
  • 1
    One could ditch the temporary file altogether using the for loop directly on the command. `For /F "Usebackq Tokens=* Delims=" %%K in ('"replace ? . /u /w"') Do Set "Key=%%K"` – T3RR0R Apr 29 '20 at 16:45
  • with ' being replaced by ` – T3RR0R Apr 29 '20 at 16:47
  • @T3RR0R does not work with `;` though (my script also) – ScriptKidd Apr 30 '20 at 13:06
  • Solution is simple if `;` is desired. Define: `Set "SC=Press any key to continue . . .=;"` and Substring Modify Key: `Set Key=!Key:%SC%!` Still saves the requirement of an external file – T3RR0R Apr 30 '20 at 13:58
  • @T3RR0R no, i meant if the user pressed `;`, `!key!` will not be `;`. solved by disabling `eol` – ScriptKidd May 01 '20 at 10:07
  • 1
    With regards to your script, yes. There is also a solution to the loss of `!` in your script. Relocate the postion of Setlocal EnableDelayedExpansion to After Key is Set, and Before !Key! is echoed. – T3RR0R May 02 '20 at 04:45
  • @T3RR0R wait, will fix that – ScriptKidd May 02 '20 at 04:46
0

You could try this:

Stroke.bat

@echo off
Echo. > Temp.txt
:: You require choice.exe for this
choice /c 1234567890qwertyuiopasdfghjklzxcvbnm
Echo 1 > Temp.txt

Main.bat

@echo off
set var=
:: Code Prior to Loop


:: Loop starts below
start /b stroke.bat
:loop

::: Loop Code Goes here
:: 
:: You will not be able to take user-input in loop
:: Do not tamper with "var"
:: To force exit the loop just "goto end"
:: Note if you force exit the loop you will need to exit this bat
::   and start a new window (since Stroke will be running)
::
::: End of loop

<Temp.txt set /p var=
if "%var%" NEQ "1" goto loop
:end

:: Post loop code
Exit

And that should work with any Character or Number, but not punctuation or Enter, Space etc.

You could modify this to work only for enter by replacing choice with set /p:

@echo off
Echo. > Temp.txt
set /p v=
Echo 1 > Temp.txt

Which you can use for enter and if you do not have choice.exe

Monacraft
  • 6,510
  • 2
  • 17
  • 29
0

If you wish to define a default action if no key is pressed within a certain time, you can use choice as follows to define a keypress:

@Echo off
:ExampleLoop
    Echo.[A] Action [B] Alternate Action
    For /F "delims=" %%C in ('Choice /T 10 /N /C:ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 /D B') Do (
        CLS & Set "Choice=%%C" & Call :Choice[1-%%C] || (CLS & Echo. %%C is not a valid Choice)
    )
Goto :ExampleLoop

:Choice[1-A]
    Echo %~0
    Echo Elective Command
Exit /B 0
:Choice[1-B]
    ECHO %~0
    Echo Default Command
Exit /B 0

The above will return the literal key as opposed to the ErrorLevel (Note: will return all letters as upper case).

By using call with :Label subroutines, and defining all choice options, the annoying errortone can be avoided and a custom message output through the use of || conditional testing on the Call Outcome. The Label approach also avoids the need for complicated and typically messy conditional testing when multiple options are present.

T3RR0R
  • 2,747
  • 3
  • 10
  • 25