如何使用Batch在可滚动菜单中进行一系列拨动开关?

如何解决如何使用Batch在可滚动菜单中进行一系列拨动开关?

我已经花了几个小时这样做。

@echo off
set list = 0 0 1 1
:loop
cls
echo Program Select
echo --------------
set "el=0"
for %%a in (%list%) do ( 
    set /a "el+=1"
    if %%a equ 0 echo "[ ] Program %el%"
    if %%a equ 1 echo "[X] Program %el%"
)
echo ----------------------------------------------------
echo W = Up  /  S = Down  /  L  = Toggle  /  H  = Confirm
choice /C WSLH /N >nul
if %ERRORLEVEL% equ 1 set key=UP
if %ERRORLEVEL% equ 2 set key=DN
if %ERRORLEVEL% equ 3 set key=SL
if %ERRORLEVEL% equ 4 set key=CN
echo %key%
pause >nul
goto loop

现在key变量可以正常工作,并且我还没有实现滚动,因为我什至无法获得它来呈现文本。

目标是获得这样的输出

Program Select
--------------
[ ] Program 1
[ ] Program 2
[X] Program 3
[X] Program 4
----------------------------------------------------
W = Up  /  S = Down  /  L  = Toggle  /  H  = Confirm

但是,我只是获得了程序选择和控件。我想念什么?

解决方法

这是您的代码的更“完善”版本:

@echo off
SETLOCAL enabledelayedexpansion


:: Program names used

set "program[1]=Program one"
set "program[2]=Program two"
set "program[3]=Program three"
set "program[4]=Program four"
set /a maxprogs=4

:: symbols used for statuses

set "symbols= X"
set "symbolsc=-+"

:restart
:: Set original list status. 0=not selected,1=selected;

set "list=0 0 1 1"
set /a cursor=1

:loop
cls
echo Program Select
echo --------------
set /a el=0
for %%a in (%list%) do ( 
    set /a el+=1
    if !el!==%cursor% (set "ds=!symbolsc:~%%a,1!") else (set "ds=!symbols:~%%a,1!")
    call set "progname=%%program[!el!]%%"
    echo [!ds!] !progname!
)
echo ----------------------------------------------------
choice /C WSLHQ /N /M "W = Up  /  S = Down  /  L  = Toggle  /  H  = Confirm / Q = Quit "
set /a key=%errorlevel%
if %key%==5 goto :eof
if %key%==4 goto confirm
if %key%==3 goto toggle
if %key%==2 if %cursor%==%maxprogs% (set /a cursor=1) else set /a cursor+=1
if %key%==1 if %cursor%==1 (set /a cursor=%maxprogs%) else set /a cursor-=1

goto loop

:confirm
echo Confirmed!
set "runany="
set /a el=0
for %%a in (%list%) do ( 
    set /a el+=1
    if %%a==1 (
     set /a runany+=1
     call set "progname=%%program[!el!]%%"
     echo Run !progname!
    )
)
if not defined runany echo None selected :(

timeout /t 5 /nobreak
goto restart

:toggle
set "newlist="
set /a el=0
for %%a in (%list%) do ( 
    set /a el+=1
    if !el!==%cursor% (
     if %%a==0 (set "newlist=!newlist! 1") else (set "newlist=!newlist! 0")
    ) else set "newlist=!newlist! %%a"
)
set "list=%newlist%"
goto loop

评论:

SETLOCAL enabledelayedexpansion允许!var!在循环内访问var的更改值(%var%在循环开始前访问原始值执行)。

我使用maxprogs是为了使列表的扩展很直观-只需跟随弹跳球...

由于光标是静态的,因此我使用symbols来表示未选择/选定的状态,使用symbolsc来表示“光标”处于状态时的状态,因此+是光标在这里被选中,-在这里被选中

list的用法与您的版本类似-cursor用于当前的光标行。

在“显示选择和程序名称”部分,请注意使用!el!在循环中访问el修改

这里最棘手的是call set "progname=%%program[!el!]%%"语句。这使用解析技巧来获取程序名称el的值。例如,假设el的当前值为2,则通过将set "progname=%program[2]%"解释为转义的%%,在子外壳中执行命令%。替换el current 值。该子Shell继承了其调用者的环境,因此从计算出的值中分配了目标变量。

我修改了choice命令以提示输入图例,并添加了Q作为退出的标准。我本来会用UDTRQ来进行上/下/切换/运行/退出,但有一些告诉我您不一定使用英语。

我将errorlevel设置为key,以避免必须特别注意保持其值,然后测试了key仅有的五个感兴趣的值;在其他人身上发出哔哔声(从choice到现在)。

退出很明显;光标移动只需递增或递减cursor并检查边界条件以进行滚动。

另外两个例程只是对display-list例程的修改; run显示程序名称,因为我不知道您要串行还是并行运行程序。

toggle例程使用相同的技术来重建list,同时切换第cursor个元素。

,

我可以理解设置菜单显示格式的愿望-但是,我不建议您考虑使用该方法。让用户滚动到所需的选项,然后确认它并没有使脚本更易于用户使用。

对于用户而言,只需一次按键就可以从列表中选择一个选项。您可以在选择之后轻松地添加确认,这对于确认操作至关重要。

我已经为菜单(对于Windows 10 )开发了一个模板,如果愿意,可以轻松编写脚本并操作菜单选项。使用模板的实用GUI脚本示例为here

以更简单的方式完成与您想要的输出更加一致的事情:


更新-向后兼容版本:

增强功能:

  • 用于菜单选项的数组总共支持36个选择选项
  • 颜色模式选择-现在可以在运行时禁用颜色。
  • 将旧式操作系统的Findstr颜色输出转换为宏,以加快执行速度。
::: Multi-Use Menu :: Author - T3RRY ::  Version 4.2 :: October 2020 ::
::: %Menu% macro - accepts up to 36 options for selection as quoted Args in list form.
::: parameters to call functions with via a given menu can be supplied using Substring modification as exampled.
::: - Multiple selection of menu items achieved using loops.
::: Tests if a menu option is a label and calls if true.
::: Builds a list of selected options [ that can be deselected ] when used in a loop.
@Echo off & Goto :Main
:::::::::::::::::::::::::: [* Balances Environment stack on script completion *]
:End [Endlocal ^& Set "_End=Y" ^& Exit /B 0]
 Color 07 & %CLOSE%
:::::::::::::::::::::::::::::::::::::::::::::: Findstr based Colorprint function
::: No longer used within menu macro
::: Unsupported Chars: "<" ">" ":" "\" "/" "?" "&"
:C_out [BG:a-f|0-9][FG:a-f|0-9] ["Quoted Strings" "to print"]
 Set "Str_=%*" &  Set "_Str=" & For %%G in (!Str_!)Do Set "_Str=!_Str! %%~G"
 Set "C_Out=%~1"
 Set "_Str=!_Str:%1 =!" & For /F "Delims=" %%G in ("!_Str!")Do Set "_Str=%%~G"
 For %%G in (!_Str!) Do Set ".Str=%%G"
  If /I "!.Str!" == "Exit"  (Set "C_Out=04") Else If /I "!.Str!" == "Next" (Set "C_Out=02") Else If /I "!.Str!" == "Continue" (Set "C_Out=02") Else If /I "!.Str!" == "Back" (Set "C_Out=05") Else If /I "!.Str!" == "Return" (Set "C_Out=05")
    <nul set /p ".=%DEL%" > " !_Str!"
    findstr /v /a:!C_Out! /R "^$" " !_Str!" nul
    del " !_Str!" > nul 2>&1
    Echo/
Exit /B 0
::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Key variable and Macro definition
:main
::::::::::::::::::::: [ For readablities sake - %Menu% macro is built from the following ]:
rem ::: Order of definition must be preserved.
rem [* prepare default findstr color for non windows 10 users *]
 For /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (set "DEL=%%a")
rem [* default color args for Picked / Not Picked options. Overriden to Echo with Ascii Escape codes if Windows 10 *]
rem [* Color /? for the full combination of colors - BG + FG colors must differ. [BG:a-f|0-9][FG:a-f|0-9] *]
 Set "ColText=For %%l in (1 2)Do if %%l==2 (Set "_Str="&(Set "C_Out=!Oline:~0,2!" & Set "_Str=!Oline:~3!")&(For %%s in (!_Str!)Do Set ".Str=%%s")&(If /I "!.Str!" == "Exit"  (Set "C_Out=04") Else If /I "!.Str!" == "Next" (Set "C_Out=02") Else If /I "!.Str!" == "Continue" (Set "C_Out=02") Else If /I "!.Str!" == "Back" (Set "C_Out=05") Else If /I "!.Str!" == "Return" (Set "C_Out=05"))&( <nul set /p ".=%DEL%" > " !_Str!" )&( findstr /v /a:!C_Out! /R "^$" " !_Str!" nul )&( del " !_Str!" > nul 2>&1 )& Echo/)Else Set Oline="
 Set "_Win10="
 Set "_End="
rem [* Test if Windows 10 If true Overide defaults _nP and _P with Echo and VT codes for faster execution with windows 10 *]
 wmic OS get OSArchitecture,caption | FIND "10" >nul && ((For /F %%a in ('echo prompt $E ^| cmd')do Set "\E=%%a")&Set "_Win10=_")
  If Defined _Win10 (
   Set "_nP=Echo/%\E%[90m"& Set "_P=Echo/%\E%[33m"
   Echo/Menu Color mode: [L]egacy [W]indows [D]isabled & For /F "Delims=" %%C in (' Choice /N /C:LWD ')Do (
    If "%%C" =="L" (
     Set "_nP=For %%l in (1 2)Do if %%l==2 (Set "_Str="&(Set "C_Out=!Oline:~0,2!" & Set "_Str=!Oline:~3!")&(For %%s in (!_Str!)Do Set ".Str=%%s")&(If /I "!.Str!" == "Exit"  (Set "C_Out=04") Else If /I "!.Str!" == "Next" (Set "C_Out=02") Else If /I "!.Str!" == "Continue" (Set "C_Out=02") Else If /I "!.Str!" == "Back" (Set "C_Out=05") Else If /I "!.Str!" == "Return" (Set "C_Out=05"))&( <nul set /p ".=%DEL%" > " !_Str!" )&( findstr /v /a:!C_Out! /R "^$" " !_Str!" nul )&( del " !_Str!" > nul 2>&1 )& Echo/)Else Set Oline=08"
     Set "_P=For %%l in (1 2)Do if %%l==2 (Set "_Str="&(Set "C_Out=!Oline:~0,2!" & Set "_Str=!Oline:~3!")&(For %%s in (!_Str!)Do Set ".Str=%%s")&(If /I "!.Str!" == "Exit"  (Set "C_Out=04") Else If /I "!.Str!" == "Next" (Set "C_Out=02") Else If /I "!.Str!" == "Continue" (Set "C_Out=02") Else If /I "!.Str!" == "Back" (Set "C_Out=05") Else If /I "!.Str!" == "Return" (Set "C_Out=05"))&( <nul set /p ".=%DEL%" > " !_Str!" )&( findstr /v /a:!C_Out! /R "^$" " !_Str!" nul )&( del " !_Str!" > nul 2>&1 )& Echo/)Else Set Oline=06"
    )
    If "%%C" =="D" (Set "_nP=Echo/"& Set "_P=Echo/")
   )
  ) Else (
    Set "_nP=For %%l in (1 2)Do if %%l==2 (Set "_Str="&(Set "C_Out=!Oline:~0,2!" & Set "_Str=!Oline:~3!")&(For %%s in (!_Str!)Do Set ".Str=%%s")&(If /I "!.Str!" == "Exit"  (Set "C_Out=04") Else If /I "!.Str!" == "Next" (Set "C_Out=02") Else If /I "!.Str!" == "Continue" (Set "C_Out=02") Else If /I "!.Str!" == "Back" (Set "C_Out=05") Else If /I "!.Str!" == "Return" (Set "C_Out=05"))&( <nul set /p ".=%DEL%" > " !_Str!" )&( findstr /v /a:!C_Out! /R "^$" " !_Str!" nul )&( del " !_Str!" > nul 2>&1 )& Echo/)Else Set Oline=08"
    Set "_P=For %%l in (1 2)Do if %%l==2 (Set "_Str="&(Set "C_Out=!Oline:~0,2!" & Set "_Str=!Oline:~3!")&(For %%s in (!_Str!)Do Set ".Str=%%s")&(If /I "!.Str!" == "Exit"  (Set "C_Out=04") Else If /I "!.Str!" == "Next" (Set "C_Out=02") Else If /I "!.Str!" == "Continue" (Set "C_Out=02") Else If /I "!.Str!" == "Back" (Set "C_Out=05") Else If /I "!.Str!" == "Return" (Set "C_Out=05"))&( <nul set /p ".=%DEL%" > " !_Str!" )&( findstr /v /a:!C_Out! /R "^$" " !_Str!" nul )&( del " !_Str!" > nul 2>&1 )& Echo/)Else Set Oline=06"
    Echo/Menu Color mode: [L]egacy [D]isabled & For /F "Delims=" %%C in (' Choice /N /C:LD ')Do If "%%C" =="D" (Set "_nP=Echo/"& Set "_P=Echo/")
   )
  )
rem [* Menu supports 36 choices using _O array index with substring modification on _Cho var to index choice selection of Array Elements *]
 Set "_Cho=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 Set "DisplayArray=(Echo/!#Sel!| Findstr /LIC:"%%~G" > Nul 2> Nul && ( %_P% [!_Cho:~%%z,1!] X %%~G ) ) || ( %_nP% [!_Cho:~%%z,1!] - %%~G )"
 Set "#Sel=_Nil"
 Set "ClearArray=(For /F "Tokens=1,2 Delims==" %%i in (' Set Opt[ 2^> Nul ')Do "Set %%i=")"
 Set "ResetVars=(Set "#L=F" &  Set "OptL=" & Set "_O=0")"
 Set "CLOSE=POPD & Endlocal & Set "_End=Y" & Exit /B 0"
 Set "BuildArray=((If !_O! GTR 35 (Call :C_Out 04 "Maximum options [!_O!] Exceeded" & (Timeout /T 5 /NOBREAK) & %CLOSE%))&Set "OptL=!OptL!!_Cho:~%%z,1!"&Set "Opt[!_Cho:~%%z,1!]=%%~G")"
 Set "MakeChoice=(For /F "Delims=" %%C in ('Choice /N /C:!OptL!')Do findstr.exe /BLIC:":!Opt[%%C]!" "%~F0" > nul 2> nul && Call :!Opt[%%C]! "Param" 2> Nul || ((Echo/"!#Sel!"| Findstr /LIC:"!Opt[%%C]!" > Nul 2> Nul && (For /F "Delims=" %%r in ("!Opt[%%C]!")Do If Not "!#Sel!" == "" (Set "#Sel=!#Sel:"%%r"=!")Else (Set "#Sel=_Nil"))) || (Set "#Sel=!#Sel! "!Opt[%%C]!"")))"
 Set "Return=For /L %%s in (0 1 4)Do (If not "!#Sel!" == "" (If "!#Sel:~0,1!" == " " (If "!#L!" == "F" (Set "#Sel=!#Sel:~1!"))Else (Set "#L=T"))Else (Set "#Sel=_Nil"))&if not "!#Sel!" == "_Nil" if not "!#Sel!" == "" (Set "#Sel=!#Sel:_Nil=!")"
 Set "Menu=(If defined _End Goto :End) &For %%n in (1 2)Do if %%n==2 (%ClearArray% & %ResetVars% &(For %%G in (!Options!)Do For %%z in (!_O!)Do %BuildArray% & %DisplayArray% &Set /A "_O+=1")& %MakeChoice% & %Return% )Else Set Options="
 For %%M in ( ClearArray ResetVars BuildArray DisplayArray MakeChoice Return )Do Set "%%M="
 IF NOT EXIST "%TEMP%\colorize" md "%TEMP%\colorize"
 PUSHD "%TEMP%\colorize" || (Echo/"%TEMP%\colorize" Could not be found & %CLOSE%)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 Setlocal EnableExtensions EnableDelayedExpansion & REM [* required to be activated AFTER definition of Macro's. *]
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Commence script main body | Demonstration of usages
:Loop
rem [* doublequoting of options recommended - Required for strings containing standard delimiters. *]
 If not defined _End cls
 If not defined _End %ColText%05 Make a selection.
rem [* Param Substring modification examples passing parameters to labels called when selected - Optional feature. *]
 Set /A "PRM=!Random! %%100 + 100" & Rem [* Example param only *]
 %Menu:Param=PRM% "Exit" "Next" "Option 1" "Option 2" "Option 3" "Option 4"
 Echo/"!#Sel!" | Findstr.exe /LIC:"Exit" > Nul 2> Nul && (Goto :End)
Goto :Loop
 
:Next
rem [* Selection of a single option occurs by using the macro without a loop or resetting the #Sel variable
rem - between %menu% use and next iteration of a loop *]
rem [* Process #Sel items using the !#Sel! variable - then ** SET "#Sel-_Nil" prior to next usage of Menu macro** *]
 Set "Menu1Opts=!#Sel!"
 Set "#Sel="
 Cls
 Call :C_Out 03 "[Demo - Parameter usage.  %%1 ~ '%1' == '!%~1!' ] Selected =" !Menu1opts!
 %Menu% "Exit" " + Continue" ".. Back"
 Echo/!#Sel! | Findstr.exe /LIC:".. Back" > Nul 2> Nul && (Set "#Sel=!Menu1opts!"& Exit /B 0)
 Echo/!#Sel! | Findstr.exe /LIC:"Exit" > Nul 2> Nul && (%CLOSE%)
 Set "#Sel="
 Echo/!Menu1opts! | Findstr.exe /LIC:"_Nil" > Nul 2> Nul && (Call :C_Out 04 "Selection Required."&(Pause & Exit /B 0)) || Call :C_Out 02 "Confirmed=" !Menu1opts!
 Call :C_Out 02 "Example complete."
 Pause
rem [* to exit at end of script or by user selection *]
 %CLOSE%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: End of example

输出:

selection differentiation

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-