Multiple Option Batch File [closed] - batch-file

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am trying to make an easy messenger program for our office.
I'm not sure what I am missing, but everytime I try running the code for options, it just messages my computer and not the one I am trying to message. I am able to message the other computer if I don't have the easy options.
Please Help!
I would like to just choose a number and have the program paste that choice to the prompt. ex the user chose 1, that is person a (code for person a is /server:ECRCL). The code "/server:ECRCL" is now showing on the prompt for the "c" in the msg code. (%c% %m%)*
Here is my code:
#echo off
Title Doodle's Messenger Program
echo Messenger
chdir /
echo Select a Person
echo 1) Person a
echo 2) Person b
echo 3) Person c
echo 4) Person d
:START
echo ========================================
set /p c=Choose the number of the person you would like to message:
if %c%=="1" echo /server:ECRCL
if %c%=="2" echo /server:ECRCB
if %c%=="3" echo /server:ECRCCI
if %c%=="4" echo /server:ECRCCO
:A
set /p m=Message:
msg * %c% %m%
GoTo A
:1
: echo %/server:ECRCL /time:300 /v /w%
:2
:/server:ECRCB
:3
:/server:ECRCCI
:4
:/server:ECRCCO
The following script does work for messaging but I would like to make it easier for others with typing 1, 2, 3, or 4
#echo Copy one of the following computers you would like to message and paste it where it asks for the computer name.
#echo person a - /server:ECRCL
#echo person b - /server:ECRCB
#echo person c - /server:ECRCCI
#echo person d - /server:ECRCCO
:START
set /p c=Enter Selection:
:A
set /p m=Message:
msg * %c% %m%
GoTo A

Here's an example which may assist you.
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Title Doodle's Messenger Program
Set "msg=%SYSTEMROOT%\System32\msg.exe"
If %PROCESSOR_ARCHITECTURE:~-2% Equ 86 If Defined PROCESSOR_ARCHITEW6432 Set "msg=%SYSTEMROOT%\SysNative\msg.exe"
For %%G In ("%msg%") Do If "%%~aG" Lss "-" (Set "msg=") Else If "%%~aG" GEq "d" Set "msg="
If Not Defined msg (Echo Error! The system file msg.exe is missing.
"%__AppDir__%timeout.exe" /T 3 /NoBreak 1> NUL
GoTo :EOF)
:Start
Echo(
Echo Messenger Selection List
Echo 1. Viktor [//ECRCL]
Echo 2. Rashi [//ECRCB]
Echo 3. Kian [//ECRCCI]
Echo 4. Cedric [//ECRCCO]
Echo(
"%__AppDir__%choice.exe" /C 1234 /N /M "Enter the number for the user you would like to message."
If %ErrorLevel% Equ 1 Set "Svr=ECRCL"
If %ErrorLevel% Equ 2 Set "Svr=ECRCB"
If %ErrorLevel% Equ 3 Set "Svr=ECRCCI"
If %ErrorLevel% Equ 4 Set "Svr=ECRCCO"
:AskMessage
Set "m="
Set /P "m=Please type your message, then press the enter key>"
If Not Defined m (
Echo Empty messages are not allowed!
"%__AppDir__%timeout.exe" /T 2 /NoBreak 1> NUL
GoTo AskMessage
)
%msg% * /server:%svr% %m%
GoTo Start

As Compo has stated, the choice command is the option for this style of menu, however it's possible to use the value returned by choice in a more direct fashion to enact the desired commands by combining indexed variables with associated variables and Delayed expansion with For loop metavariables to pull the server Id from the indexed recipient number.
#Echo Off& Setlocal DisableDelayedExpansion
rem // Macro Definitions
Set "MSG=%SYSTEMROOT%\System32\msg.exe * "
Set "List/D/V=Set "#$L=0"&Set "$$L="&For %%n in (1 2)Do if %%n==2 (For %%G in (!$L!)Do (Set "%%~G" > Nul &Set /A "#$L+=1"))Else Set $L="
Set "Div=---------------------------------------------------------------------------------------------"
Set "MENU=Echo/!Div!&(For /F "Tokens=1,2 Delims==[" %%X in ('Set $V') Do Set /A "CNT=!#%%~X!" & Set "Array=%%~Y") & Set "Choices=" & (For %%A in (!ARRAY!)Do For /L %%U in (1 1 !CNT!)Do Set "Choices=!Choices!%%U"&For %%S in ("!%%~A[%%U]!")Do Echo/%%~A[%%U] %%~S !%%~S!)&Echo/[E]xit&Echo/!Div!"
rem // ACTION/E Macro to utilise the value of an Array Element
Set "ACTION/E=For /F "Delims=" %%I in ('Choice /N /C:!Choices!E')Do IF "%%I"=="E" (Endlocal&Endlocal&Goto :Eof)Else For %%A in ("!Array![%%I]")Do $M !%%~A!"
rem // ACTION/S Macro to utilise a value assigned to the value of an Array Element (Sub value)
Set "ACTION/S=For /F "Delims=" %%I in ('Choice /N /C:!Choices!E')Do IF "%%I"=="E" (Endlocal&Endlocal&Goto :Eof)Else For %%A in ("!Array![%%I]")Do For %%O in ("!%%~A!")Do $M !%%~O!"
Setlocal EnableExtensions EnableDelayedExpansion
rem // Define associated variables between recipients and servers to enable Access to the values from indexed variables
%List/D/V:$L=Users%"recipient[1]=Person 1" "recipient[2]=Person 2" "recipient[3]=Person 3" "recipient[4]=Person 4"
%List/D/V:$L=Servers%"Person 1=/server:ECRCL" "Person 2=/server:ECRCB" "Person 3=/server:ECRCCI" "Person 4=/server:ECRCCO"
:Loop
CLS
%MENU:$V=Users%
rem // examples of different command usage for ACTION macros. $M is substituted with the required command/s to executed on the value retrieved from the array
rem ::: %ACTION/E:$M=Echo/%
Set "Input="&Set /P "input=Enter Message: "
rem ::: if not "!input!"=="" ((If /I "!input!"=="E" (Exit /B 0)Else Echo/Select Recipient & %ACTION/S:$M=Echo/!Msg!% !input! 2> Nul) || Echo/!Msg! not installed)Else Echo/Input required
if not "!input!"=="" ((If /I "!input!"=="E" (Exit /B 0)Else Echo/Select Recipient & %ACTION/S:$M=!Msg!% !input! 2> Nul) || Echo/!Msg! not installed)Else Echo/Input required
Pause
Goto :Loop
The above has been modified to make the macro's more Generic for different Menu usages. The $M substring of the ACTION macros is substituted with the command to be executed on the value returned through choice selection for the selected index

Related

How to list all files in folder then select multiple files [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I would like to be able to:
Put my .bat script in some folder with files and run it
In CMD, script should list all files in that folder with select-able numbers
In user prompt, user should be able to choose two or more files for further processing, by entering their numbers separated by commas, spaces or whatever
Below is what I have so far. It can choose one file only.
I am not developer, this was copy/pasted/edited and cannot figure out how to enhance it to work with multiple files.
The final goal is to have names of chosen files in .txt file, one name per new line
Many thanks in advance.
echo off
:START
cls
cls
setlocal enabledelayedexpansion
set count=0
:
:: Read in files
for %%x in (*.*) do (
set /a count=count+1
set choice[!count!]=%%x
)
:
echo.
echo Please choose file by number:
echo.
:
:: Print list of files
for /l %%x in (1,1,!count!) do (
echo %%x] !choice[%%x]!
)
echo.
:
:: Retrieve User input
set /p select=?:
echo.
echo !choice[%select%]! > my-choice.txt
echo TYPE ANY KEY TO GO BACK IN START MENU ...
pause >NUL
goto START
You almost have it :)
echo off
:START
cls
setlocal enabledelayedexpansion
set count=0
:: Read in files
for %%x in (*.*) do (
set /a count=count+1
set choice[!count!]=%%x
)
echo.
echo Please choose files by number:
echo.
:: Print list of files
for /l %%x in (1,1,!count!) do (
echo %%x] !choice[%%x]!
)
echo.
:: Retrieve User input
set /P selected="select file numbers: "
for %%i in (%selected%) do (
echo !choice[%%i]! >> my-choice.txt
)
echo.
echo TYPE ANY KEY TO GO BACK IN START MENU ...
pause >NUL
goto START
Please note that this does not check for valid numbers or anything else.
I would generally suggest this methodology for the task, you've laid out.
#Echo Off
SetLocal EnableExtensions
:Menu
ClS
For /F "Delims==" %%G In ('(Set File[^) 2^> NUL') Do Set "%%G="
For /F "Tokens=1,* Delims=[]" %%G In ('(Set PATHEXT^=^) ^& %__AppDir__%where.exe ".":"*" 2^> NUL ^| %__AppDir__%find.exe /N /V ""') Do Set "File[%%G]=%%~nxH" & Echo %%G. %%~nxH
If Not Defined File[1] GoTo :EOF
:Select
Set "#="
Set /P "#=Choose a file from the list by entering its item number. "
For /F "Tokens=1,* Delims==" %%G In ('(Set File[%#%]^) 2^> NUL ^| %__AppDir__%find.exe "="') Do Set "File[#]=%%H"
If Not Defined File[#] GoTo Select
:Main
(Echo %File[#]%) 1> "my-choice.txt"
Echo Press any key to go back to the menu. . .
Pause 1> NUL
GoTo :Menu
This could obviously be simplified for the task you're performing, but, I'm going to assume that you've dumbed down the task for the purposes of your question.
[EDIT /]
Please note, that this does ensure the end user can only input valid information. Also it does not use delayed expansion at all, so unlike in your example, files named using ! characters will not be problematic.

Include another option/file While selecting specific Options

I made a simple batch file to execute a executable via some options which are provided upon launch.
Some thing like this :
:A
Echo Option 1
Echo Option 2
Set /p set1=Choice :
if %set1%==1 set A=Set1_1
if %set1%==2 set A=Set1_2
goto Set_2
:B
Echo Option A
Echo Option B
Set /p set2=Choice :
if %set2%==A set B=Set2_A
if %set2%==B set B=Set2_B
goto launch
:launch
program.exe -%A% -%B%
So basically this works. But what i need to have is a way to include another launch parameter for my program if both "Option 1" and "Option A" are selected. Not in "Option 2" and "Option B".
so that my launch look like this
program.exe -%set1% -%set2% -%if1_A%
Edit : i've made some mistakes here on this command line but i won't correct it since #avery_larry pointed it out.
I'm sorry if i made this confusing, please let me know if need to clarify or elaborate further. :)
untested
If a variable is not set to anything, then it will expand to nothing. Setup your 3rd variable and make sure it's not set if the conditions aren't met. Something like this:
set if1_a=
if "%set1%"=="1" (
if "%set2%"=="A" (
set "if1_a=-option"
)
)
program.exe -%set1% -%set2% %if1_A%
Note that I made the hyphen part of the variable. Also it's probably supposed to be:
program.exe -%A% -%B% %if1_A%
and finally you probably want to use if /i to make it case insensitive.
Whilst your question may have been using the input options just for the purposes of the question, and not real world ones; as they are known options, I've decided to provide a solution which uses the more robust built-in choice.exe command:
#Rem Undefine any existing variables to be used.
#For /F "Delims==" %%G In ('Set Opt[ 2^>NUL')Do #Set "%%G="
#Rem Request first argument.
#"%__APPDIR__%choice.exe" /C 12 /M "First argument"
#Rem Define the first argument with the value chosen.
#Set "Opt[1]=%ERRORLEVEL%"
#Rem Request second argument.
#"%__APPDIR__%choice.exe" /C AB /M "Second argument"
#Rem Define the second argument with the value chosen.
#If ErrorLevel 2 (Set "Opt[2]=B")Else (Set "Opt[2]=A"
Rem Define third argument if first chosen was 1
If %Opt[1]% Equ 1 Set "Opt[3]=-"Third option string"")
#Rem Launch program with required options.
#Echo program.exe -"%Opt[1]%" -"%Opt[2]%" %Opt[3]%
#Rem Prevent cmd window from possibly closing early.
#Pause
Problems with user input can be avoided through the use of an input validation function, as exampled here:
#Echo off & CD "%~dp0"
TITLE %~n0 & Setlocal
::: / Creates variable /AE = Ascii-27 escape code.
::: - http://www.dostips.com/forum/viewtopic.php?t=1733
::: - https://stackoverflow.com/a/34923514/12343998
:::
::: - /AE can be used with and without DelayedExpansion.
Setlocal
For /F "tokens=2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
Endlocal
Set "/AE=%%a"
)
::: \
%= Remark =%
(Set LF=^
%= NewLine variable to split set /p input line =%)
%= create blank batch file to store and retrieve variables in for automatic reload =%
If not Exist "inputlog.bat" (Echo(#Echo Off>inputlog.bat & Goto :main)
For %%A in ( "%/AE%[36m[%/AE%[34mN%/AE%[36m]ew" , "[%/AE%[34mL%/AE%[36m]oad%/AE%[0m" )Do Echo.%%~A
Choice /N /C nl >nul
If errorlevel 2 (Goto :load)
Goto :Main
:Input <VarName> <Optional - define valid values with each additional parameter>
Set "variable=%~1"
Setlocal EnableDelayedExpansion
IF not "%~2"=="" For %%A in (%*) Do (If not "%%~A"=="%1" (Set "valid=%%~A !valid!"))
:Confirm
%= allow input of variable, test input, store for reloading. =%
Echo(%/AE%[35m
Set /P "input=!variable!!LF!%/AE%[36m{> %/AE%[33m"
IF "!input!"=="" (
Echo(%/AE%[31m!variable! required.
Goto :Confirm
)
IF "%~2"=="" (
ECHO(Set "!variable!=!input!">>inputlog.bat
Endlocal & Set "%variable%=%input%"
Exit /B
)
For %%A in (!valid!) Do (
If /I "!input!"=="%%~A" (
ECHO(Set "!variable!=!input!">>inputlog.bat
Endlocal & Set "%variable%=%input%"
Exit /B
)
)
Echo(%/AE%[31m!variable! required.
Echo(%/AE%[36mSelect from:
For %%A in (!valid!) Do (Echo(%/AE%[33m%%~A%/AE%[0m)
Goto :Confirm
:main
%= define variable (parameter 1) and restrict definition of variables to specified values (additional parameters) =%
Call :Input language english spanish
%= Define multiple variables at once =%
For %%A in ("name" "age" "location" "job" "hobbies") Do (Call :Input %%A)
%= undefine local variables =%
endlocal
%= Display that variable definitions have been removed =%
For %%A in ("language" "name" "age" "location" "job" "hobbies") Do Set %%A
:load
%= Reload the variables from the input Log and display. =%
Call inputlog.bat
%= Demonstrate that variables have been reloaded =%
Setlocal EnableDelayedExpansion
For %%A in ("language" "name" "age" "location" "job" "hobbies") Do (Echo(%/AE%[37m%%~A:!LF!%/AE%[36m%/AE%[33m!%%~A!%/AE%[32m%/AE%[0m)
pause

How to map numbers to a variable

I have the following script but I want to map the numbers to the variable but do not know how to. So if a user enters 0, I want it to search for the event name NewUser.
#echo off
mode con:cols=40 lines=40
set /p customerID="Enter Customer ID: "
CLS
:MENU
ECHO.
ECHO ...............................................
ECHO PLEASE SELECT THE EVENT FROM THE MENU BELOW
ECHO ...............................................
ECHO.
ECHO Event Code Event Name
ECHO.
ECHO 0 NewUser
ECHO 1 ExistingUser
ECHO 2 EmailAdded
ECHO 3 AccountProblem
ECHO 4 Lost
ECHO.
SET /P event=Type the event code and then press ENTER:
IF %event%==0 set event=NewUser GOTO find
IF %M%==1 set event=ExistingUser GOTO find
IF %M%==2 set event=EmailAdded GOTO find
IF %M%==3 set event=AccountProblem GOTO find
IF %M%==4 set event=Lost GOTO find
pause
:find
pause
setlocal enableextensions disabledelayedexpansion
pause
set "sourceFolder=C:\test"
set "targetFolder=C:\test2"
pause
set "customerID=%customerID%"
set "NewUser=%Event%"
pause
for /f "delims=" %%a in ('
findstr /m /s /l /c:"%customerID%" "%sourceFolder%\*"
^| findstr /f:/ /m /l /c:"%event%"
') do (
copy "%%~fa" "%targetFolder%"
)
pause
The first version of your code was closer to correct solution than current one; you need to use two nested for /F loops as follows:
for /f "delims=" %%a in ('
findstr /I /m /s /l /c:"%customerID%" "%sourceFolder%\*.txt"
') do for /f "delims=" %%A in ('
findstr /I /m /l /c:"%event%" "%%~fa"
') do (
rem 'copy' command is merely displayed using ECHO for debugging purposes
ECHO copy "%%~fa" "%targetFolder%"
)
Next commented code snippet could help to improve the script:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "customerID="
:customerID
set /p customerID="Enter Customer ID: "
if not defined customerID goto :customerID
REM instead of above test, you could apply next statement about `set /P`:
REM If the user does not enter anything (just presses return)
REM then the variable will be unchanged and an ERRORLEVEL will be set.
rem CLS
:MENU
ECHO.
ECHO ...............................................
ECHO PLEASE SELECT THE EVENT FROM THE MENU BELOW
ECHO ...............................................
ECHO.
ECHO Event Code Event Name
ECHO.
ECHO 0 NewUser
ECHO 1 ExistingUser
ECHO 2 EmailAdded
ECHO 3 AccountProblem
ECHO 4 Lost
ECHO.
REM SET /P M=Type the event code and then press ENTER:
choice /C 01234 /M "Type the event code"
REM 0 means that an user's reply to "Terminate batch job (Y/N)?" was not "y"
IF %ERRORLEVEL% EQU 0 echo "Ctrl-C" or "Ctrl-Break" pressed&goto :NoSearch
REM 255 means another error
IF ERRORLEVEL 255 goto :MENU
REM ERRORLEVEL number Specifies a true condition if the last program run
REM returned an exit code EQUAL TO OR GREATER THAN the number
REM specified.
IF ERRORLEVEL 1 set "event=NewUser"
IF ERRORLEVEL 2 set "event=ExistingUser"
IF ERRORLEVEL 3 set "event=EmailAdded"
IF ERRORLEVEL 4 set "event=AccountProblem"
IF ERRORLEVEL 5 set "event=Lost"
REM Note that in above code, ERRORLEVEL parameters are tested in INCREASING order
REM Used only in this special case
REM (no need of GOTO statement, 'event' variable is set correctly)
REM
REM although CHOICE /? says:
REM When you use ERRORLEVEL parameters in a batch program,
REM list them in decreasing order.
:NOTE
set "sourceFolder=D:\test"
set "targetFolder=D:\test2"
rem ??? set "customerID=%customerID%"
rem ??? set "event=%event%"
rem debugging output
echo looking for "customerID=%customerID%" "event=%event%"
for /f "delims=" %%a in ('
findstr /I /m /s /l /c:"%customerID%" "%sourceFolder%\*.txt"
') do for /f "delims=" %%A in ('
findstr /I /m /l /c:"%event%" "%%~fa"
') do (
rem 'copy' command is merely displayed using ECHO for debugging purposes
ECHO copy "%%~fa" "%targetFolder%"
)
:NoSearch
pause
Change your For loop like this and retest:
FOR /F "DELIMS=" %%A IN (
'FINDSTR/MSC:"%customerID%" "%sourceFolder%\*"^|FINDSTR/MIF:/ /C:"%event%"'
) DO COPY "%%A" "%targetFolder%"
EDIT
I have added a modified version of your script to include the new requirement of a three digit event code. Just adjust it's value in the script as necessary, (lines nineteen to twenty three).
#ECHO OFF
MODE CON:COLS=52 LINES=40
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
(SET sourceFolder=C:\test)
(SET targetFolder=C:\test2)
SET /P "customerID=Enter Customer ID: "
:MENU
CLS
ECHO=
ECHO= ..................................................
ECHO= PLEASE SELECT THE OPTION FROM THE EVENT MENU BELOW
ECHO= ..................................................
ECHO=
ECHO= Option Event Name Event Code
ECHO=
ECHO. 1. NewUser A00
ECHO. 2. ExistingUser A01
ECHO. 3. EmailAdded A02
ECHO. 4. AccountProblem A03
ECHO. 5. Lost A04
ECHO=
CHOICE /C 12345 /M "CHOOSE AN OPTION"
SET "Option=%ERRORLEVEL%"
FOR /F "TOKENS=1-4 DELIMS=. " %%A IN ('FINDSTR/BC:"ECHO. " "%~f0"'
) DO IF "%%B"=="%Option%" (SET "Name=%%C" & SET "Code=%%D")
FOR /F "DELIMS=" %%A IN (
'FINDSTR/MISC:"%customerID%" "%sourceFolder%\*"^|FINDSTR/MIF:/ /C:"%Name%"'
) DO COPY "%%A" "%targetFolder%"
PAUSE
Please make sure that %sourceFolder% is a full path and %targetFolder% already exists, (see line six).

How to make a batch SET /P statememt not require an enter

I'm making my own console based off batch because I want more then what cmd offers but have the key features that batch has.
One of the most important things is to prompt the user for the command:
:prompt
#echo off
title JDOS command line
echo.
echo.
SET /P command="%FDIR%>"
rem SECTIONS/COMMANDS
rem /I means the if statement is not case-sensitive. USE IT AT ALL TIMES!
if /I "%command%"=="add" goto add
if /I "%command%"=="subtract" goto subtract
goto prompt
(This is just a small portion of all the options but you get the idea)
:add
title Calculator/Add
SET /P Add_A=Please enter the first number:
SET /P Add_B=Please enter the second number:
SET /A sum=%Add_A% + %Add_B%
echo The sum is %sum%
timeout /t 10 >nul
goto prompt
But this is timewasting and sort of idiotic (at least in my opinion).
So, can I execute goto add without the user pressing enter ?
Edit:
I'm thinking an approach similar to CHOICE but with the option to have more than 1 key be pressed (so for example instead of 1/2/3/4/ it would be restart/shutdown/lock/logoff/
I modified my accepted answer at this post and adjusted it for this request. Here it is:
#echo off
setlocal EnableDelayedExpansion
set "commands=add subtract"
for %%a in (%commands%) do set "com[%%a]=1"
for /F %%a in ('echo prompt $H ^| cmd') do set "BS=%%a"
for /F %%a in ('copy /Z "%~F0" NUL') do set "CR=%%a"
set "command="
:nextKey
set "key="
for /F "delims=" %%K in ('xcopy /W "%~F0" "%~F0" 2^>NUL') do if not defined key set "key=%%K"
if "!key:~-1!" equ "!CR!" goto endCommand
if "!key:~-1!" equ "!BS!" (
if defined command (
set "command=%command:~0,-1%"
set /P "=.!BS!!BS! !BS!!BS!" < NUL
)
) else if "!key:~-1!" neq " " (
set "command=%command%!key:~-1!"
set /P "=!key:~-1!" < NUL
if defined com[!command!] goto endCommand
)
goto nextKey
:endCommand
echo/
echo/
echo command read: "%command%"
Note: The mechanism used in this method does not allow to insert spaces! This code should be modified in large parts in order to read spaces.

Can only write one word on chat batch file

The code below is the part of my program. My problem is that when i enter my message it works perfectly if its 1 word. but if it is more it says goto was expected. the Q and R options are needed to refresh the chat and pop up a quit prompt.
set /p M=Enter Your Message:
if %M%==Q goto B
if %M%==q goto B
if %M%==R goto A
if %M%==r goto A
echo %U%: %M% >>%S%.txt
What should i do?
ps. this is my first quistion on here sorry if formating is wrong)
If the input has more than one word, the parser will see, after variable replacement
if this is a test==Q goto B
which is an invalid command.
Simplest solution is to use quotes
if "%M%"=="Q" goto B
....
will be interpreted as
if "this is a test"=="Q" goto B
edited to adapt to comments
This is a skeleton of a chat script with "auto update" in the terms indicated in the comments.
#echo off
setlocal enableextensions disabledelayedexpansion
rem Configuration
set "chatFile=c:\temp\chat.txt"
set "lastSize=-1"
:selectOption
rem Update screen
call :refresh
rem retrieve user selection
>nul choice /c rqw /n /t 3 /d r /m ""
rem Check what has been selected
if errorlevel 3 call :write & goto :selectOption
if errorlevel 2 goto :quit
rem Select another option
goto :selectOption
:refresh [bForceRefresh]
rem Check if refresh is being forced
if not "%~1"=="" set "lastSize=-1"
rem Ensure we have a file
if not exist "%chatFile%" >"%chatFile%" echo(
rem Check if we can skip the refresh.
rem If file has no changed its size there are no changes in content
for %%a in ("%chatFile%") do if %%~za leq %lastSize% (
goto :skipRefresh
) else (
set "lastSize=%%~za"
)
rem Paint the screen
cls
type "%chatFile%"
rem Show the options
echo(
<nul set /p ".=[R]efresh [Q]uit [W]rite ?"
:skipRefresh
goto :eof
:write
setlocal
rem Ask message
echo(
echo(
set "message="
set /p "message=What do you want to say? >"
rem If there is a message, write to output file,
rem else force screen refresh to remove the message question
if defined message (
setlocal enabledelayedexpansion
>>"%chatFile%" echo(%time% :[ %username% ]: !message!
endlocal
) else (
call :refresh forceRefresh
)
endlocal
goto :eof
:quit
cls
exit /b

Resources