How to make the SET command not wait for answer? - batch-file

I've made a chat program and it works great, the only problem I have is that the SET /P command will wait until you press something and then press ENTER. There's my code that I got problems with:
:CHAT
CLS
SET TEXT=
TYPE "%FILESDIR%\Files\CHAT.cht" << I need this line active all the time.
ECHO.
SET /P TEXT=Text:
IF NOT "%TEXT%"=="" ECHO %USERNAME%: %TEXT% >> "%FILESDIR%\Files\CHAT.cht"
PING LOCALHOST -n 1 > nul
GOTO CHAT
I want to update the TYPE command all the time, but you need to type something. Is there anyway I can get around this?
EDIT: I really don't want another cmd screen

Suppose you did have the text updated continuously, in real time. What happens when the user begins to enter text, and then the other user sends text to be displayed at the same time. You only have one window - so you get a jumbled mess (assuming you could figure out how to make it happen technically).
You are a long way from having a functional chat program - you haven't completely thought out the issues.
1) You need two windows that are updated independently:
An input window where the user can enter text
A dialog window that displays the running dialog of all participants, in real time.
Windows batch doesn't support multiple windows. But you can emulate it by having two batch processes running for each user, one for input, the other for dialog output. A single batch script can be used for both processes. The parent script can launch multiple batch processes using the START command. Each batch process will get its own console window.
2) Only one person (process) can write to the text file at a time. What do you think happens if two people try to write at the same time? One will succeed, and the other will fail. You need a method to detect failure and automatically try again until success. I describe a simple method to achieve this at How do you have shared log files under Windows?.
3) SET /P will simply return the previous entry if the user presses <Enter> without typing anything. You should clear the text variable prior to your SET /P statement. EDIT - I now see the OP already had this in a place I did not expect
4) You don't want to retype the entire dialog from the beginning every time there is an update. You only want to dispaly the newly appended lines. It is possible to redirect input to an endless FOR /L loop, and within the loop you can use SET /P to read the most recent line. If nothing has been appended, then it will return nothing (assuming the variable was cleared before SET /P). You simply don't ECHO anything if nothing was received.
Here is a very crude working example that demonstrates the above concepts. There is no way to exit the program. You will have to close both console windows to quit.
#echo off
setlocal enableDelayedExpansion
set "dialog=dialog.txt"
if "%~1" equ ":input" (
title Chat Input
goto :input
)
start "" "%~f0" :input
title Chat Dialog
::Show Dialog
<"%dialog%" ( for /l %%N in () do (
set "text="
set /p "text="
if defined text echo(!text!
))
:input
cls
set "text="
set /p "text=>"
:write
2>nul (
>>"%dialog%" (
echo(%username%: !text!
(call )
) || goto :write
)
goto :input
There is still a long way to go before this is a truly useful chat program. But it is a good starting point. Some additional things that could still be added.
5) A way to start a new dialog file for each independent chat.
6) A way to invite one or more users to join the chat.
7) A clean way to exit the program, including closing of the additional console window. This requires interprocess communication. I demonstrate this in my SNAKE.BAT game at http://www.dostips.com/forum/viewtopic.php?t=4741. Warning - there are a lot of advanced concepts in that script, so extracting the relevent information might be a challeng ;-)
8) It would be nice to have the dialog window have a scrollable display buffer. The user can control the size of the buffer via the console properties, but it would be nice to control it programmatically. Native batch cannot do this, but I show how hybrid PowerShell/batch can do this at CMD: Set buffer height independently of window height

Related

Run batch script resized

I made a simple batch script with two diff options, it kinda annoys me that it covers my whole screen although there are 2 lines visible. It would be cool if someone teaches me how to edit the script so that it opens in a smaller (resized window). This is my current script:
#echo off
title Changing Configs..
:main
echo 1 = trade time
echo 2 = grind time
set /p ibo=
if %ibo% == 1 goto trade
if %ibo% == 2 goto grind
:trade
ren "config.yml" "config - nakano.yml"
ren "config - senpai.yml" "config.yml"
pause
exit
:grind
ren "config.yml" "config - senpai.yml"
ren "config - nakano.yml" "config.yml"
pause
exit
I want it to look like this if I run it without resizing it manually
Not sure if there is a way to change the window's size, run mode, or whatever it is called from the batch script itself. It really doesn't matter since you can either control it via shortcut, or just avoid the situation all together.
If you look at the comments on your question, Compo mentioned using a shortcut - this is the most direct answer to your question. Do the following to create desired shortcut:
Create a shortcut by opening windows explorer and navigating to where your batch file is.
Start a drag-n-drop operation by grabbing the batch file with the mouse and moving the mouse off of the file, but DO NOT let go yet. Hold down the CTRL+Shift and the icon you are dragging, or the text under it, will change to indicate you are about to create a link (A.K.A. shortcut). Letting go in the same folder will work, but you may want to move the shortcut later. Alternatively, you could try bringing up a context menu on the batch file by moving the mouse over it and using the secondary click, and then select "create shortcut", which should be found fairly far done on the context menu.
Select the newly created shortcut with the mouse and on the keyboard type Alt+Enter - a properties window should appear. If for some reason that fails. you can use the mouse to bring up a context menu on the newly created shortcut (same way as described in step 2) and select "Properties" (Should be at bottom of context menu).
Go to the "Shortcut" tab in the "Properties" windows, select "Normal windows" from "Run:" section, and click the "OK" button (See image below).
The resulting icon can be moved to the desktop or pinned to the taskbar by dragging to the taskbar.
Or instead, you could rewrite your code so it doesn't ask any questions and just does the job. If you only have 2 choices, why not check which is current, change to the other, and report which one is now the current option?
The following code:
Verifies that copies of both the senpai and nakano configs exist before making any changes.
Checks if the file "Nakano.Active" exist, if so then it does the code to switch to senpai, else it assumes senpai is active and does the code to switch to nakano.
Replaces the current "config.yml" file with the desired configuration.
Deletes the current "{Mode}.Active" file, "Nakano.Active" or "Senpai.Active", as needed.
Creates a new Active file, or flag, to indicate the current mode. That is , creates "Senpai.Active" or "Nakano.Active", as needed.
Echos/reports out what mode it just switch to.
Waits for 2.25 seconds, giving you the time to see what mode it switched to. Change the 225 to the number of centiseconds you want the code to wait before continuing.
Executes EXIT which closes the window.
#ECHO OFF
IF NOT EXIST "config - senpai.yml" GOTO :DoExit
IF NOT EXIST "config - nakano.yml" GOTO :DoExit
IF EXIST Nakano.Active (
COPY /Y "config - senpai.yml" "config.yml" >NUL
DEL Nakano.Active 2>NUL
ECHO;Senpai >Senpai.Active
ECHO;Senpai Mode
) ELSE (
COPY /Y "config - nakano.yml" "config.yml" >NUL
DEL Senpai.Active 2>NUL
ECHO;Nakano >Nakano.Active
ECHO;Nakano Mode
)
REM Pause for 2.25 seconds
SET Centiseconds=225
SET "NOWTIME=%TIME:00.=%"
SET "NOWTIME=%NOWTIME:.=%"
FOR /F "TOKENS=1-3 DELIMS=:" %%G IN ("%NOWTIME::0=:%") DO SET /A "StartCentiseconds=(%%G*60+%%H)*6000+%%I"
SET /A EndCentiseconds=StartCentiseconds+Centiseconds
:GetNow
SET "NOWTIME=%TIME:00.=%"
SET "NOWTIME=%NOWTIME:.=%"
FOR /F "TOKENS=1-3 DELIMS=:" %%G IN ("%NOWTIME::0=:%") DO SET /A "NowCentiseconds=(%%G*60+%%H)*6000+%%I"
IF %NowCentiseconds% LSS %StartCentiseconds% SET /A NowCentiseconds=NowCentiseconds+8640000
IF %NowCentiseconds% LSS %EndCentiseconds% GOTO :GetNow
:DoExit
EXIT
As per comments simply add mode 40,10 or similar at start of file
#echo off & mode 40,10
title Changing Configs..
......

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.

Catching keystroke during loop in batch

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%

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).

Batch file exits when command run internally finishes

I'm creating a simple command line using Batch for a personal project. However, whenever I try to execute a batch file in it, the command line closes as soon as the batch file completes. Why is that, and how can I fix it?
This is the relevant bit of source (also an SSCCE):
#echo off
:loopstart
set /p comnd=%cd%^>
%comnd%
goto loopstart
I have comments but must give you an answer, so couple things:
The /p option in Set generates a prompt for user input, so it's waiting for an answer but you are not handling any user response.
You have set up an infinite loop with the goto at the end (but that doesn't necessarily cause CMD window to close).
Rem out the goto at end and add a pause and you should be able to track down the problem.
EDIT: New answer per user's comments ---------------------------------------
Use call in this bat and exit /b at end of each bat you're running from this prompt.
:loopstart
set /p comnd=%cd%^>
call %comnd%
goto loopstart

Resources