14} Help! My old batch files won't work since there is no choice.com
Q: When I try to run my old batch file as a CMD.EXE script I get
"'choice' is not recognized as an internal or external command,
operable program or batch file." What can I do?
A: The CHOICE command has been dropped because allegedly it can
cause collisions in the NT/2000/XP multi-tasking environment. Thus
the best choice (if you pardon the pun) is not try to find an old
version, but patiently write your scripts anew using SET /P. However,
choice is back on Vista. Anyway, below is a simple demonstration
of the set /p usage.
@echo off & setlocal enableextensions
:_again
set ask_=
set /p ask_="Please respond [y,n,q]?"
for %%a in (y n q) do if /i "%ask_%"=="%%a" goto _%%a
goto _again
::
:_y
echo Your input was Yes& goto :EOF
:_n
echo Your input was No& goto :EOF
:_q
echo Your input was Quit& goto :EOF
endlocal & goto :EOF
The same with a slightly different logic, and a
default.
@echo off & setlocal enableextensions
:_again
set ask_=
set /p ask_="Please respond [
Y,n,q]?"
if /i "%ask_%"=="q" goto _q
if /i "%ask_%"=="n" goto _n
if /i not "%ask_%"=="y" if not "%ask_%"=="" goto _again
goto _y
::
:_y
echo Your input was Yes& goto :EOF
:_n
echo Your input was No& goto :EOF
:_q
echo Your input was Quit& goto :EOF
endlocal & goto :EOF
The output could be e.g.
D:\TEST>cmdfaq
Please respond [Y,n,q]?n
Your input was No
The line
set /p ask_="Please respond [Y,n,q]?"
could alternatively be written as
(set /p ask_=Please respond [Y,n,q]?)
The response could also be written as a subroutine. (The usefulness of
the option would become more obvious if the script contained several
questions.)
@echo off & setlocal enableextensions
Call :AskQuestionWithYdefault "Please respond [Y,n,q]?" reply_
goto _%reply_%1
::
:_y1
echo Your input was Yes& goto :EOF
:_n1
echo Your input was No& goto :EOF
:_q1
echo Your input was Quit& goto :EOF
endlocal & goto :EOF
::
:: The question as a subroutine
:AskQuestionWithYdefault
setlocal enableextensions
:_askthequestionagain
set return_=
set ask_=
set /p ask_="%~1"
if "%ask_%"=="" set return_=y
if /i "%ask_%"=="Y" set return_=y
if /i "%ask_%"=="n" set return_=n
if /i "%ask_%"=="q" set return_=q
if not defined return_ goto _askthequestionagain
endlocal & set "%2=%return_%" & goto :EOF
The following version demonstrates the fact that
setclocal
only makes the environment variables within a
setclocal endlocal
pair unique, but the same does not go for the labels. Thus the label
_askthequestionagain can't appear in both
the subroutines without causing confusion. The labels must be unique.
@echo off & setlocal enableextensions
Call :AskQuestionWithYdefault "Please respond [Y,n,q]?" reply_
echo Your first reply: %reply_%
Call :AskQuestionWithNdefault "Please respond [y,N,q]?" reply_
echo Your second reply: %reply_%
endlocal & goto :EOF
::
:: The question as a subroutine
:AskQuestionWithYdefault
setlocal enableextensions
:
_asktheyquestionagain
set
return_=
set
ask_=
set /p ask_="%~1"
if "%ask_%"=="" set return_=y
if /i "%ask_%"=="Y" set return_=y
if /i "%ask_%"=="n" set return_=n
if /i "%ask_%"=="q" set return_=q
if not defined return_ goto
_asktheyquestionagain
endlocal & set "%2=%return_%" & goto :EOF
::
:AskQuestionWithNdefault
setlocal enableextensions
:
_askthenquestionagain
set
return_=
set
ask_=
set /p ask_="%~1"
if "%ask_%"=="" set return_=n
if /i "%ask_%"=="y" set return_=y
if /i "%ask_%"=="n" set return_=n
if /i "%ask_%"=="q" set return_=q
if not defined return_ goto
_askthenquestionagain
endlocal & set "%2=%return_%" & goto :EOF
The output could be e.g.
D:\TEST>cmdfaq
Please respond [Y,n,q]?q
Your first reply: q
Please respond [y,N,q]?x
Please respond [y,N,q]?
Your second reply: n
Consider a snippet from a real-life script for "whatever" actual task.
If Opera (a browser, as you know) happens to be running, one wants
to ensure the user's permission to do the "whatever". Else one just
performs the "whatever" outright. Also note the if construct, which
requires using delayed expansion. As for the
<CTRL-G>, it is the beep, i.e.
ASCII 7.
echo off & setlocal enableextensions enabledelayedexpansion
tasklist|find /i "opera.exe">nul
if !errorlevel! EQU 0 (
echo Opera is running<CTRL-G>
call :ContinueOrNot reply_
if "!reply_!"=="n" (endlocal & goto :EOF))
echo Do here whatever you intend to do
endlocal & goto :EOF
::
:: The question as a subroutine
:ContinueOrNot
setlocal enableextensions
:_askthequestionagain
set ask_=
set /p ask_="Continue nevertheless [y,N]?"
if /i "%ask_%"=="y" (endlocal & set "%1=y" & goto :EOF)
if not "%ask_%"=="" if /i not "%ask_%"=="n" goto _askthequestionagain
endlocal & set "%1=n" & goto :EOF
Anyway,
instead of the
SET /P you might try a
clone such as
CHOOSE.EXE "Ask questions
in batch/script files" from
tscmd.zip
@echo off & setlocal enableextensions
:: Note that choose.exe is incompatible with 64-bit Windows
if defined ProgramW6432 (
echo/
echo Exiting: %~f0 is incompatible with 64-bit Windows
goto :EOF)
choose /tq,5 /cynq "Give your answer "
if errorlevel==0 if not errorlevel==1 echo You effected a break
if errorlevel==1 if not errorlevel==2 echo Your input was Yes
if errorlevel==2 if not errorlevel==3 echo Your input was No
if errorlevel==3 if not errorlevel==4 echo Your input was Quit
if errorlevel==255 echo Error condition
endlocal & goto :EOF
Alternatively
@echo off & setlocal enableextensions
:: Note that choose.exe is incompatible with 64-bit Windows
if defined ProgramW6432 (
echo/
echo Exiting: %~f0 is incompatible with 64-bit Windows
goto :EOF)
choose /tq,5 /cynq /x "Give your answer "
for %%c in (call del) do %%c choose_.bat
if "%choose_%"=="0" echo You effected a break
if "%choose_%"=="1" echo Your input was Yes
if "%choose_%"=="2" echo Your input was No
if "%choose_%"=="3" echo Your input was Quit
if "%choose_%"=="255" echo Error condition
endlocal & goto :EOF
The output in both the cases might be e.g.
D:\TEST>cmdfaq
Give your answer [Y,N,Q]?Q
Your input was Quit
The obvious advantage of CHOOSE.EXE over the SET /P method is that
the former can handle timed default input.
If you want Microsoft's old CHOICE.EXE it seems to be available from
the Microsoft Windows 98 Resource Kit e.g. at
ftp://ftp.microsoft.com/Services/TechNet/samples/PS/Win98/Reskit/SCRPTING
(For the tools included with the Microsoft Windows 98 Resource Kit
see
http://support.microsoft.com/kb/247024).
Choice.exe is natively available e.g. in Windows 7 and Windows 10.