Catching keystroke during loop in batch - batch-file

As a small training for my batch programming I originally followed the idea to make up a small slotmachine. You can give your coins, the numbers rush through and when you hit a button, the numbers should stop at their current value. If they are all the same, boom, you won the jackpot!
My problem right now is the keystroke capture during the loop. I already thought something like a choice command, but then the program would stop at each loop waiting for keyboard input, not making the game just quite annoying to wait all the time, but as well boring as you could check if you want to hit a specific button to stop.
Another thought was putting
set /p foobar=
and then simulate an Enter-Stroke with !SendKeys! (with everything neccessary in the code), forgetting that the enter yould have been sended after input...
Is there a way to accomplish that in ONE batch file? Or do I have to come up with another one to simulate the keystrokes or is there anything else I have missed?
EDIT: To clearify: Is there any command that changes something on keystroke, but runs through if nothing is touched?
Thanks for help in advance!
Greetings
geisterfurz007

#echo off
setlocal EnableDelayedExpansion
rem Create an empty file
cd . > key.txt
rem Start a parallel process that wait for Enter key
rem and add a line to the empty file
start "" /B cmd /C "set /P = & echo line >> key.txt"
set "key="
:wait
cls
set "number=%random:~-4%"
echo %number%
echo/
echo Press Enter key to stop the numbers...
set /P key=< key.txt
if not defined key goto wait
echo The last number is: %number%

Related

send keys method cmd

I've been working on a batch file to perform several tasks and usually ask the user to enter 1, or 2 to choose between options.
This time, I'd like to use a different approach, keystrokes so that the user can select a choice by pressing the UP or DOWN arrow keys. This is where I want to include the UP/DOWN strokes for the user.
echo 1. go to the main menu?
echo 2. Go to the next backup?
echo.
set INPUT=
set /P INPUT=Type input: %=%
If "%INPUT%"=="1" goto start1
If "%INPUT%"=="2" goto start2
The above portion of code works for me. Now instead of using "1" or "2"
I'd like to use {DOWN} or {UP}
https://msdn.microsoft.com/en-us/library/8c6yea83(v=vs.84).aspx
I don't seem to make this work out in my batch by trying these lines:
If /I "%INPUT%"=="{UP}" goto start1
If /I "%INPUT%"=="{DOWN}" goto start2
Here:
batch file that detects keystrokes. how?
This article adresses the topic of choosing between keystrokes awsd and I've tested it, it works perfect only in my case I need for the arrow keys to perform the task.

how to detect change in .txt file using batch?

I made a simple LAN chat batch file, and i would like to know if
there is an command that checks if a specific txt file is updated.
The chat history is stored in log.dat and i want to have a sound notification or something like that when theres a new message.
#echo off
title LAN chat reader
call Color.bat
:read
call Color.bat
cls
type log.dat
timeout /t 3 /nobreak >nul
goto read
(im a noob, please tell me if this is possible)
To check the file date/time use for and %%~t prefix:
#echo off
title LAN chat reader
setlocal enableDelayedExpansion
:read
call Color.bat
cls
type log.dat
for %%a in (log.dat) do set filetimesize=%%~tza
:checkupdate
ping -n 1 -w 100 localhost >nul
for %%a in (log.dat) do if "!filetimesize!"=="%%~tza" goto checkupdate
echo updated
goto read
wOxxOm already gave a solution to check for an updated file.
Here is a way to produce a Sound:
copy con bell.txt
Then press the ALT-key enter 007 while keeping ALT pressed, then release the ALT key. ^G should appear on your Screen (= 0x07, which is a Bell), then press Ctrl-Z. This gives you a textfile with lenght = 1 Byte
Type bell.txt
will then beep.
EDIT an easier way to produce bell.txt: on commandline, enter echo ^G>bell.txt (to produce ^G press CTRL-G). This will create a three-byte-file (instead of the one-byte-file with the copy trick) (but that's only a line feed and should not disturb).

Clear a line/move the cursor, using the Timeout command or similar

I was trying to find a way to clear (CLS) a single line (see This Question), but found that the solutions, which involved moving the cursor, required extra software or modifications to files, which is not ideal.
However, I later noticed that the TIMEOUT command actually moves the cursor, which can be demonstrated with the following code:
#ECHO off
ECHO Notice how the cursor moves to the number.
ECHO Press [Ctrl]+[C] for an interesting result.
PAUSE
ECHO(
TIMEOUT 99999
PAUSE
If Ctrl+C is pressed after a couple of seconds, the "Terminate Batch Job" prompt overwrites the TIMEOUT output after the number. Any typing also continues to overwrite it.
What I am looking for, is any way to clear a line, change the line, or move the cursor somewhere, and also anything similar that could be useful. (I know this is a bit vague)
One idea was if it was possible to modify the stdout in such a way that the cursor still moved, it would at least be possible to get a changing number at one point in a custom line.
It might also be possible to asynchronously do both TIMEOUT and ECHO commands to have a similar effect to Ctrl+C.
Redirecting the TIMEOUT stdout to nul gives no LF character. This in conjunction with:
<nul SET /P var=#
REM echo without a LF character
...Could possibly be used to create progress bars.
Any thoughts, ideas, or other commands with similar effects are welcome.
Using answers from here you can have an increasing number printed.
It is important to insert the backspace character in place of insert_baskspace_here below.
You will need an editor that supports insertion of ASCII characters. I used Ultraedit but Notepad++ works too.
#echo off
setlocal enableextensions enabledelayedexpansion
set BS=insert_baskspace_here
Echo I printed 1 time
set /p "=I printed 2 times" <NUL
for /L %%I in (3,1,9) DO (
timeout /t 1 > nul
set /p "=!BS!!BS!!BS!!BS!!BS!!BS!!BS!%%I times" <NUL
)
The output starts as:
I printed 1 time
I printed 2 times
It changes each second and finishes with:
I printed 1 time
I printed 9 times
A few changes and you have a little progress spinner wheel:
#echo off
setlocal enableextensions enabledelayedexpansion
set BS=
set /p "=Processing.../" <NUL
for /L %%J in (0,1,9) DO (
for %%I in (-,\,^|,/,) DO (
timeout /t 1 > nul
set /p "=!BS!%%I" <NUL
)
)

Batch code: how to pass a parameter choosing from an input list?

I'm really new in this forum so I hope to respect all your rules, if not please forgive me!
I've just started studying something about batch files and I'm trying to execute a simple program from batch passing a parameter (the last aim is to submit a SAS program passing a date parameter).
Is it possible to activate a sort of list where I can choose some between pre-defined parameters?
--> This is the real aim of my work
I'm trying to "play" with this code:
#echo off
title Setting up execution period
echo Insert your date in the format GGMMMAAAA (es: '31DEC2003'D).
SET /p data_par=Insert the date to filter datas:
SET first_byte=%data_par:~1,1%
if "%first_byte%"=="" (
GOTO tag1
) else (
GOTO tag2
)
:tag1
msg * Missing value
:tag2
msg * Well done!
pause
I've tried in a lot of ways but it looks like the IF statement is not executed, I don't know where am I wrong.
Another question: why the prompt closes after i press "Enter" (afte the set/p command is executed)?
--> this has been resolved putting the "pause" command at the end of the script.
Thank you all for the attention,
Best regards!
Squotty
Put a pause at the end of your code to see the errormessages.
correct syntax for if when using else is:
if "a"=="b" (dosomething) else (dosemethingelse)
You can write it in several lines, but there are rules, where to set the paratheses:
if "a"=="b" (
echo this is code for something
rem more lines possible
) else (
echo this is code for something else
rem more lines possible
)
The first ( has to be on the same line than if.
) else ( have to be on one line.
If you press just enter with set /p, the variable remains unchanged (propably empty), so your code will go on with the code and hits the line else. Here it will tell you "else is not recognized as a command..."
at your tagx you should tell batch, where to stop execution. Use goto :eof to stop execution or goto somewhere to continue somewhere else. If you don't, it will just continue with the next lines.
Example:
:tag1
msg * Missing value
goto :eof
:tag2
msg * Well done!
goto :continue
pause
:continue
REM go on with the program...
(note: the pause will never be reached. I let it there to show you, how things work)
EDIT instead of just checking for some input you can check for the correct format:
echo %data_par%|findstr /r "[0-3][0-9][A-Z][A-Z][A-Z][1-2]0[0-9][0-9]">nul && (
echo correct format
goto continue
) || (
echo wrong format
goto startover
)
It's not bullet proof (eg. 38ABC2019 would be considered "correct"), but at least it checks for the correct format (e.g. 15.12.2019 or 12/15/2014 would be "not correct")
#ECHO OFF
SETLOCAL
SET "item1=date1"
SET "item2=date2"
SET "item3=date3"
SET "item4=date4"
FOR /l %%a IN (1,1,4) DO CALL ECHO(%%a. %%item%%a%%
ECHO(U. User-specified
choice /c 1234u
CALL SET selection=%%item%errorlevel%%%
IF NOT DEFINED selection (
SET /p selection="Your date-selection ? "
)
IF NOT DEFINED selection ECHO No selection made&GOTO :EOF
ECHO selection is %selection%
GOTO :EOF
This code may be of assistance.
It's normal to develop batch code using a batch window. Simply set up a shortcut to command prompt (Start>Programs>Accessories) which would allow you to run the script over and over and retain the results on-screen without using 'pause'. Editing can be accomplished by using notepad batchfilename.bat from the prompt (if you are using notepad for an editor - if using something better, then substitute that program's name). You can exit from the batch window by executing an exit command.
You can also get help on batch commands by using commandname /? - it's often cryptic and there are plenty of quirks. Extensive help available here on SO.

Changing Pause Message

Ok, so you know how when you type up pause in CMD, it will say 'Press any key to continue...'. How do I change that to say something like 'Press a key to proceed...'?
Lastly, I was coding a batch file. I want to know what's up if I have something like:
#echo off
cls
pause
pause
pause
pause
It seems to skip round about to pauses When you press a key. I'm curious as to know the rules of which the pauses are skipped.
Thanks.
Nearly the same as Deniz Zoeteman, except this version displays the blinking cursor on the same line as your custom message, as does the normal PAUSE command. The Deniz Zoeteman solution displays the blinking cursor below your message.
<nul set /p "=Press a key to proceed..."
pause >nul
You cannot change the text displayed when a pause command is executed. It's bound to the Windows installation's language pack. The only thing you can do is not letting it say anything by doing pause>nul.
Of course, there's different ways to simulate pause; see the example from the other answer, where set /p is used. With pause>nul however, you can do this:
echo Custom pause message
pause>nul
And that should work.
And for pause commands skipping, that's most likely due to the key still being pressed down while the next pause command already executed (small guess though - I don't recall exactly if that's the behaviour of the command).
You may want to try
set /p=your message
Note: you will have to hit the enter key to continue versus any key.
Option #1:
#echo off
echo Press any key to continue or Ctrl-C to abort.
pause > nul
Option #2
set /p=Press any key to continue or Ctrl-C to abort.
-->> I prefer the screen output of option #1.
This is one practical application:
set /p=Press ENTER key to proceed or Ctrl-C to abort.

Resources