Batch script multiple choice menu - windows

I have multimedia file viewing software that I call in a batch script to load files using an /LOADFILES argument. This argument accepts multiple files separated by semicolons ";".
What I would like is a menu from which I can select the files I want to open.
For example :
Sample_01
Sample_02
Sample_03
Sample_04
Sample_05
All
What is your choice ?
And what we have selected ends up stored in a variable which is interpreted by the /LOADFILES argument.
For now, my script is able to open all the existing samples one after the other :
#echo off
for /f "delims=" %%I in ('dir /a:d-h /b "%SystemDrive%\software\sample\*"') do (
"%SystemDrive%\software\Viewer.exe" /LOADFILES="%%I"
)
pause
exit
But I would like it to be able to read only the samples that I have selected from a menu, in separate instances of the program.
I have no specific idea of about how to achieve this.
Any help would greatly help me improve my script.
Thank you.

Here is a (very basic) script to show you the basic concept:
#echo off
setlocal
set "loadfiles="
:AddSamples
cls
echo current loadfiles: %loadfiles:~1%
echo add sample number
echo 1 - Sample_01
echo 2 - Sample_02
echo 3 - Sample_03
echo 4 - Sample_04
echo 5 - Sample_05
echo A - All and Go
echo G - Done and Go
choice /c 12345AG /m "What is your choice? "
if %errorlevel% == 1 set "loadfiles=%loadfiles%;Sample_01.mp3
if %errorlevel% == 2 set "loadfiles=%loadfiles%;Sample_02.mp3
if %errorlevel% == 3 set "loadfiles=%loadfiles%;Sample_03.mp3
if %errorlevel% == 4 set "loadfiles=%loadfiles%;Sample_04.mp3
if %errorlevel% == 5 set "loadfiles=%loadfiles%;Sample_05.mp3
if %errorlevel% == 6 set "loadfiles=;Sample_01.mp3;Sample_02.mp3;Sample_03.mp3;Sample_04.mp3;Sample_05.mp3" & goto :continue
if %errorlevel% == 7 goto :continue
goto :AddSamples
:Continue
set "loadfiles=%loadfiles:~1%"
"%SystemDrive%\software\Viewer.exe" /LOADFILES=%loadfiles%

Related

Creating a shop. Won't subtract money correctly

I expect to be able to buy items in the shop and have it do the correct subtraction. In the code below, you start out with 10 gold pieces, (gp), but whenever option 2 or 4, to spend 5gp or 1gp, is entered, it takes away all 10gp. I know that it's because it doesn't go past the first if %input%== 1 but I don't know how to fix it, I have tried almost everything, including if/else statements, but I may not have been doing them properly.
:shop
cls
echo You see a middle aged man behind the counter
echo of the shop as well as a younger man sweeping the floors.
echo "Hello young travelers. Welcome, is there anything
echo I can help you find?"
:purchase
echo --------------------------------------------------------
echo %name%
echo Gold: %gp%
echo --------------------------------------------------------
echo.
echo 1) Battleaxe 10gp Stats: 1d8(S) Versatile(1d10)
echo 2) Mace 5gp Stats: 1d6(B)
echo 3) L.Crossbow 20gp Stats: 1d8(P) Range 80/320
echo 4) 5 Bolts 1gp Equip with Crossbow
echo 5) Go Back
echo.
set /p input=Enter:
if %input%== 5 goto main
if %input%== 1
if %gp% LSS 10 goto nofunds
set /a gp= %gp% - 10
goto shopcont
if %input%== 2
if %gp% LSS 5 goto nofunds
set /a gp= %gp% - 5
goto shopcont
if %input%== 3
if %gp% LSS 20 goto nofunds
set /a gp= %gp% - 20
goto shopcont
if %input%== 4
if %gp% LSS 1 goto nofunds
set /a gp= %gp% - 1
goto shopcont
goto shop
:nofunds
cls
echo You don't have enough gold to purchase that item.
pause >nul
goto shop
:shopcont
cls
echo Would you like to purchase anything else?
goto purchase
I am still new at this so examples and explanations would be wonderful!
Please do not tell me to use choice.exe instead of Set /P, unless it will fix the actual issue.
In the below example, I have used Set /P under :purchase to satisfy your ill advised stipulation to not use choice.exe, (which I used under :shopcont instead).
:shop
ClS
Echo You see a middle aged man behind the shop counter, as well as a
Echo younger man sweeping the floor.
Echo(
Echo "Welcome young travellers, is there anything I can help you with?"
:purchase
Set "input="
Set "invalid=true"
Echo(
Echo ------------------------------------------------------------------
Echo(%name%
Echo Gold: %gp%
Echo ------------------------------------------------------------------
Echo(
Echo 1. Battleaxe 10gp [Stats: 1d8(S) Versatile(1d10)]
Echo 2. Mace 5gp [Stats: 1d6(B)]
Echo 3. L.Crossbow 20gp [Stats: 1d8(P) Range 80/320]
Echo 4. 5 Bolts 1gp [Equip with Crossbow]
Echo 5. Go Back
Echo(
Set /P "input=Enter: "
For /L %%A In (1,1,5) Do If "%%~A" == "%input:"=%" Set "invalid="
If Defined invalid ClS & GoTo purchase
If %input% Equ 5 GoTo main
If %input% Equ 4 If %gp% GEq 1 Set /A gp -=1 & GoTo shopcont
If %input% Equ 3 If %gp% GEq 20 Set /A gp -=20 & GoTo shopcont
If %input% Equ 2 If %gp% GEq 5 Set /A gp -=5 & GoTo shopcont
If %input% Equ 1 If %gp% GEq 10 Set /A gp -=10 & GoTo shopcont
Echo You do not have enough gold to purchase that item.
:shopcont
"%__AppDir__%choice.exe" /M "Would you like to purchase anything else"
If "%ErrorLevel%"=="1" ClS & GoTo purchase
Please note that I have tried to replicate that which you posted in your question, this assumes that %gp% and %name% are already defined prior to this code section and that the label :main exists elsewhere in your unposted code.
You asked for examples and explanations, but those are readily available under each command's usage information and via web searches, so I will not be pointlessly including such things.
The usage of command set /P is not recommended for a simple choice menu. A simple typing mistake by user of batch file can easily result in a syntax error on further processing of the batch file detected by Windows command processor resulting in an unexpected exit of batch file execution. A user playing this batch file game by double clicking on it will not be happy on typing for example by mistake " instead of 2 and suddenly the console window is closed because cmd.exe exited batch file processing because of a serious syntax error caused by " and not good coded batch file.
See also:
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Safe number comparison in Windows batch file
However, the main problem is the used syntax on all IF commands. The syntax of command IF can be seen by opening a command prompt, running if /? and reading the output help. if %input%== 1 without a command or a command block starting with ( and ending with matching ) to execute on condition is true on same line results in a syntax error on batch file execution. This can be seen on debugging the batch file.
The indentations have no meaning for cmd.exe regarding to process flow. Windows command processor is not Python. Windows command processor executes one command line respectively command block after the other independent on how many leading spaces or tabs are used to indent the command lines.
See also: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
An arithmetic expression is the string after set /A evaluated by cmd.exe on execution of the batch file. The help output on running set /? explains that within an arithmetic expression it is possible to reference the value of an environment variable by writing just its name without % or ! around variable name. That has two advantages:
If the environment variable does not exist at all, Windows command processor uses value 0 for not existing environment variable. Using %NotExistingVariable% in an arithmetic expression results in a syntax error because of this string is replaced by nothing which usually results in a missing operand error on evaluation of the arithmetic expression.
Environment variables can be modified with arithmetic expressions multiple times in a command block without usage of delayed expansion.
For that reason set /a gp= %gp% - 10 is not a recommended syntax to decrement the environment variable gp by 10. Better is using set /A gp=gp - 10 and best set /A gp-=10.
The DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ explains that echo. can fail to print an empty line into console window and that echo/ or echo( is better for this task.
A minimal, complete, and verifiable example for this task is following batch file:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "gp=50"
set "name=B1u3Soul"
:Shop
cls
echo You see a middle aged man behind the counter
echo of the shop as well as a younger man sweeping the floors.
echo "Hello young travelers. Welcome, is there anything
echo I can help you find?"
:Purchase
echo --------------------------------------------------------
echo %name%
echo Gold: %gp%
echo --------------------------------------------------------
echo/
echo 1) Battleaxe 10gp Stats: 1d8(S) Versatile(1d10)
echo 2) Mace 5gp Stats: 1d6(B)
echo 3) L.Crossbow 20gp Stats: 1d8(P) Range 80/320
echo 4) 5 Bolts 1gp Equip with Crossbow
echo 5) Go Back
echo/
%SystemRoot%\System32\choice.exe /C 12345 /N /M "Enter: "
if errorlevel 5 goto Main
if errorlevel 4 set "GoldAmount=1" & goto GoldInPurse
if errorlevel 3 set "GoldAmount=20" & goto GoldInPurse
if errorlevel 2 set "GoldAmount=5" & goto GoldInPurse
set "GoldAmount=10"
:GoldInPurse
if %gp% LSS %GoldAmount% goto NoFunds
set /A gp-=GoldAmount
echo/
%SystemRoot%\System32\choice.exe /C YN /N /M "Would you like to purchase anything else [Y/N]? "
cls
if errorlevel 2 goto Main
goto Purchase
:NoFunds
echo/
echo You don't have enough gold to purchase that item.
pause >nul
goto Shop
:Main
endlocal
See also single line with multiple commands using Windows batch file for an explanation of operator & as used in this batch file.
It would be of course possible to use just choice instead of %SystemRoot%\System32\choice.exe. But the usage of full qualified file name (drive + path + file name + file extension) makes the batch file independent on environment defined outside the batch file. For this batch file it does not matter how PATH and PATHEXT is defined on starting the batch file. It depends only on environment variable SystemRoot defined by Windows and which is not modified by applications or users in general.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
choice /?
cls /?
echo /?
endlocal /?
goto /?
if /?
pause /?
set /?
setlocal /?
See also:
What are the ERRORLEVEL values set by internal cmd.exe commands?
Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success?
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
Microsoft article about Using command redirection operators

I am using a Batch File to search a list of functions for an exact match, wondering if its possible to do a keyword search instead

I am using a Batch File to search a list of functions for an exact match, wondering if its possible to do a key word search, so right now i have to type "open cmd"
(variations on spacing and capital letters are accounted for)
Id like to switch it over to a system that can look for "cmd" and perform the action so "hey, open cmd please" would yield the same result as the old system
Old system:
setlocal
:: /STARTUP
set speech=start scripts\nircmd.exe speak text
cls
:begin
set TALK=TypeSomething
SET /P TALK=
set TALK=%TALK:?=%
call :%TALK: =% 2>NUL
if %errorlevel% equ 0 goto begin
exit /B 0
:unknown
echo Old function no longer supported
:opencmd
:BOSopencmd
:cmd
echo Command Prompt has now been opened in a new window, sir.
%speech% "Command Prompt has now been opened in a new window, sir."
start scripts\cmd.bat
exit /B 0
It is based of a chat bot i tried to make in middle school so the %speech% is not an important item, i can add that and the echo later. I just need a system that works like the old one if possible. The other i can have any number of functions with
:cmd
start cmd
Exit /B 0
or
:reddit
start http://www.reddit.com/
exit /B 0
at these need to be able to stack. I can transition to having scripts for each function in a separate batch files if needed. Ive tried trying findstr but it wasn't giving the desired results. Ive exhausted my knowledge on what i might be able to do but I've come up short lol, If you are having trouble understanding what i'm asking don't hesitate to let me know
I learn by taking things apart so partial code is appreciated but will not be much help until after I've figured out what does what .
Here's a sample of how you might approach it using ECHO, FINDSTR, and CALL (This is a modified example from the original per your request to be able to process multiple keywords):
#echo off
set TST_FNDFLG=FALSE
set TST_USRANS=
set /P TST_USRANS=Enter keywords:
if "%TST_USRANS%" == "" goto ENDIT
echo %TST_USRANS% | findstr /i "CMD" >NUL 2>&1
if ERRORLEVEL 1 goto TRYRED
call :DOCMD
:TRYRED
echo %TST_USRANS% | findstr /i "REDDIT" >NUL 2>&1
if ERRORLEVEL 1 goto TRYGOO
call :DORED
:TRYGOO
echo %TST_USRANS% | findstr /i "GOOGLE" >NUL 2>&1
if ERRORLEVEL 1 goto TRYEND
call :DOGOO
goto TRYEND
:DOCMD
if [%TST_FNDFLG%] == [FALSE] echo.
echo CMD was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:DORED
if [%TST_FNDFLG%] == [FALSE] echo.
echo REDDIT was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:DOGOO
if [%TST_FNDFLG%] == [FALSE] echo.
echo GOOGLE was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:TRYEND
echo.
if [%TST_FNDFLG%] == [TRUE] echo No more keywords found
if [%TST_FNDFLG%] == [FALSE] echo Did not find any known keywords
goto ENDIT
:ENDIT
echo.
set TST_USRANS=
set TST_FNDFLG=

Filtering for multiple results in batch using IF

I was writing a batch file replicating CMD but more customized. What I am trying to do is scan %input% for multiple different results leading to different actions. To help you envision what I mean, I tried doing this:
set /p input="%cd%>"
if "%input%" == "cls" (
GOTO reset
) else (
if "%input%" == freespace (
GOTO freespace
) else (
title %input%
%input%
GOTO A
Which just crashes the CMD window running the batch file. Is there anyway I can sort for these two responses (or possibly more) using IF statements? I realize this is SIMILAR to other questions called "using multiple if statements in batch" but they are just not the same format I am trying to put the IF statements in.
You appear to be running your batch by clicking on it, which means that you will not see error messages. It's better to run batch from the command-prompt so that the messages will be visible and persistent.
There are at least two problems with the code you have presented.
The first is that you have not closed the parentheses for the else clauses so there are two pending close-parentheses at the end of the batch.
format:
if x=y (dothis
) else (
if p==q (dosomethingelse
) else (
dosomethingelseentirely
)
)
The second problem is that if is very literal with a string-match. It includes the quotes in the strings-to-be-matched, so
if "%input%" == freespace (
can never be true as input is quoted but freespace is not (unlike cls in your first if)
BTW - if /i ... will perform a case-insensitive comparison.
You don't need multiple if commands to filter multiple results in this particular problem. This is the way I would do it:
#echo off
setlocal
:A
echo/
set "input="
set /p "input=%cd%>"
call :%input% 2> NUL
if errorlevel 1 echo "%input%" is not recognized as a command...
goto A
:cls
echo Reset command, parameters: "%*"
exit /B 0
:freespace
echo FreeSpace command, parameters: "%*"
exit /B 0
In this method a call :%input% command is directly executed, so if the label exists, then the corresponding code run; otherwise, the call :nolabel command returns an ERRORLEVEL equal 2.
Each one of the subroutines ends with exit /B 0 command, so in these cases the ERRORLEVEL is zero.
If you have any doubt about a particular command, I encourage you the review its command /? help screen or search the web looking for a more extensive description...

Allowing multiple choice selections for users using batch file [duplicate]

This question already has answers here:
Multiple choices menu on batch file?
(13 answers)
Closed 8 years ago.
I want to create a windows batch scripting whereby it allows the user to enter multiple choices at one go, and then after that the program will runs.
With reference to this website (Multiple choices menu on batch file?), I get to know it somehow works to allow multiple selection. However, this is in bash scripting. For example...
#echo off
setlocal enabledelayedexpansion
echo Which would you like to use?
echo 1. Hello.txt
echo 2. Byebye.txt
echo 3. ThisIsText.txt
echo 4. MyBatchScript.txt
echo 5. All
set /p op=Type the numbers of the names you want to use (separated by commas with no spaces. E.g: 1,3,2):
Until here, it works by prompting users to select one or more choices.
for /f "delims=, tokens=1-5" %%i in ("op") do (
set i=%%i
set j=%%j
set k=%%k
set l=%%l
set m=%%m
)
However, until here, I realised that the choices would be stored into a variable "op" and this would then be in i. And basically, j, k, l and m are not used. I'm not sure if I interpreted it wrongly. Hopefully I did not interpret the coding wrongly.
So for what I want is that...
When the user selects only 1 options,
It will insert the "Hello.txt" into a command (e.g.)
echo This is complicated > Hello.txt
But if the user selects more than 1 options (for example, user typed 1,2),
then it will insert
echo This is complicated > Hello.txt
echo This is complicated > Byebye.txt
And if the user selects option '5', it cannot be entered along with other numbers (since it is ALL). Then it will echo the This is complicated > Byebye.txt , Hello.txt , etc
Is there anyway to do it using batch scripting?
Edit: Can anyone explain this to me? I tried finding different websites but I still don't get it. Sorry, I am new to writing batch scripts. So the understanding of it is still not deep. Disclaimer: This is the coding I got from the website I mentioned above.
if %i%X neq X set last=1b & goto %i%
:1b
if %j%X neq X set last=2b & goto %j%
:2b
if %k%X neq X set last=3b & goto %k%
:3b
if %l%X neq X set last=4b & goto %l%
:4b
if %m%X neq X set last=%m% & goto %m%
goto next
:1
::Put the code for doing the first option here
goto %last%
:2
::Put the code for doing the second option here
goto %last%
:3
::Put the code for doing the third option here
goto %last%
:4
::Put the code for doing the fourth option here
goto %last%
:5
::Put the code for doing the fifth option here
goto %last%
I do not get how this helps to run multiple command. If I input 1,2,3 into the field, how does it gets me to part where I can run it all together?
You may make good use of the fact that the standard separators for items in flat FOR command (no /F option) are spaces, commas, semicolons and equal-signs:
#echo off
setlocal enabledelayedexpansion
echo Which would you like to use?
echo 1. Hello.txt
echo 2. Byebye.txt
echo 3. ThisIsText.txt
echo 4. MyBatchScript.txt
echo 5. All
:getOptions
set /p "op=Type the numbers of the names you want to use (separated by commas OR spaces): "
if "%op%" equ "" goto getOptions
if %op% equ 5 set op=1,2,3,4
for %%a in (%op%) do (
echo Process option %%a
call :option-%%a
)
goto :EOF
:option-1
echo 1. Hello.txt
exit /B
:option-2
echo 2. Byebye.txt
exit /B
:option-3
echo 3. ThisIsText.txt
exit /B
:option-4
echo 4. MyBatchScript.txt
exit /B
You wrote, you tried ('%op'), ("%op"), (%op) and variations.
It should be: ("%op%")
Only forvariables and Commandline-Parameters use <Percent><char> syntax.
op is a "normal" variable and it is used <Percent><name><Percent>: %op%

VBScript and Batch interaction

I am running a batch script and somewhere the user has to access a database.
At this moment, a window made in vbscript would prompt asking the user to type in the login and password. (OK, Cancel buttons)
If the credentials are correct after the OK, the batch would continue according to planA, otherwise the batch would do something else going to planB. If (Cancel), it would return to the batch and the main menu.
THIS IS WHAT I HAVE BEEN STRUGGLING WITH:
#echo off
:Ini
echo [1] Access database
echo [2] Main menu
echo:
set /p Quest= What do you prefer (1 / 2)?
if not '%Quest%'=='' set Quest=%Quest:~0,1%
if '%Quest%'=='1' goto VBS
if '%Quest%'=='2' goto BATCH
echo Invalid option, please try again
cls
goto Ini
:BATCH
echo Heading for main menu ...
goto Main
:VBS
:wscript.echo InputBox("Enter your password","VBScript-Batch")
findstr "^:" "%~sf0" | findstr /i /v ":Label" >temp.vbs
for /f "delims=" %%N in ('cscript //nologo temp.vbs') do set pass=%%N
del temp.vbs
:Label1
If %pass%=="okay" echo Valid Password ! & goto PLAN-A
If not %pass%=="okay" echo Invalid Password !! & goto PLAN-B
:PLAN-A
echo continue from here
:PLAN-B
echo do something else
(...)
-- How to capture the user information, validate it and go back to the batch for the planA or planB ??
As you see, if we eliminate the "& goto PLAN" stuff the script works. It sends the VBS input "pass" to the batch and the batch echoes "continue from here" or "do something else", from where the rest of your code should continue in the same batch.
However, it is not working ... Any help to make this really work ?
Your primary issue was you didn't set up the file properly to facilitate extracting the VBS from the batch file. Your VBS looks no different than a batch label. You filter out "Label" labels, but you still include lines like :ini, :BATCH, etc. Obviously those will trip up VBS. I solved the problem by prefixing your VBS with ::: and adapting your filter. There is no need to explicitly filter out any labels. I chose 3 colons because a single colon is used for a label, and 2 colons is frequently used for comments. You could have multiple independent VBS scripts embedded within your batch simply by varying the number of preceding colons.
I also restructured the code a small amount, and sprinkled in some EXIT /B statements so that code does not fall through. Also your :MAIN is not defined so I commented out the GOTO and replaced it with EXIT /B.
#echo off
:Ini
echo [1] Access database
echo [2] Main menu
echo:
set /p Quest= What do you prefer (1 / 2)?
if not '%Quest%'=='' set Quest=%Quest:~0,1%
if '%Quest%'=='1' goto VBS
if '%Quest%'=='2' goto BATCH
echo Invalid option, please try again
cls
goto Ini
:BATCH
echo Heading for main menu ...
::goto Main
exit /b
:VBS
:::wscript.echo InputBox("Enter your password","VBScript-Batch")
findstr "^:::" "%~sf0" >temp.vbs
for /f "delims=" %%N in ('cscript //nologo temp.vbs') do set pass=%%N
del temp.vbs
If "%pass%"=="okay" (
echo Valid Password !
goto PLAN-A
) else (
echo Invalid Password !!
goto PLAN-B
)
:PLAN-A
echo continue from here
exit /b
:PLAN-B
echo do something else
exit /b

Resources