Batch file - Make Variable Menu

前端 未结 1 1275
既然无缘
既然无缘 2021-01-26 07:22

I have a menu here that you can navigate using keys using the choice command. The problem is that I want this menu to have a variable number of options. At the moment, if there

1条回答
  •  离开以前
    2021-01-26 08:14

    Should anyone be looking for a variable menu navigation through choice (Or Dynamic Menu for general purposes), it is easily possible to build a variable menu using choice, String concatenation and substring modification.

    The below is an example script that demonstrates a macro that builds and outputs the options available for the current menu. The command to be executed on the selected option is supplied using substring modification as exampled.

    @Echo off
    ::: ************************************************************** ||   Macro Definitions
    ::: Delayed expansion must be enabled AFTER definition of macros, and BEFORE their use.
    ::: Menu Building Macro
    ::: Usage: %Menu:$CMD=command to be executed referencing !option!%Options as String List
    ::: !!! Limitation: Options and Labels beginning with the same Character cannot be used within the same menu
    ::: Define Command/s to be executed upon selection of a string option using substring modification to replace $CMD
    :::  - Commands cannot use `%` or `=` characters. Selected string is accessed using the !Option! return variable
        Set "Menu=Echo/!DIV!&For %%n in (1 2)Do if %%n==2 ((Set "CHCS="&For %%G in (!Options!)Do (Set "Opt=%%~G"& Set "CHCS=!CHCS!!Opt:~0,1!"&Set "Opt[!Opt:~0,1!]=%%~G"& Set "Opt=[!Opt:~0,1!]!Opt:~1!"& Echo/!Opt!))&Echo/!DIV!& For /F "Delims=" %%o in ('Choice /N /C:!CHCS!')Do (For %%C in (!Opt[%%o]!)Do (Set "OPTION=%%C"& $CMD)))Else Set Options="
    ::: ************************************************************** ||   End of Macro Definitions
     Setlocal EnableExtensions ENABLEdelayedexpansion & Rem //      Required for Macro Usage.
    ::: Build Dividing line based on actual console dimensions.
     for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| findstr Columns`) do Set "Console_Width=%%%W"
     Set "DIV="&For /L %%i in (2 1 %Console_Width%)Do Set "DIV=!DIV!-"
    ::: ************************************************************** ||   Script Body (Usage examples)
    :MainMenu
     Cls
     Echo/- Call example
     %Menu:$CMD=Call :!Option! TF%Title Color
     Echo/- aqcuisition menu example
     %Menu:$CMD=Set /A !Option!+=1%Water Food
     Echo/!Option! = !%Option%!
     Echo/- Goto example
     %Menu:$CMD=Goto :!Option!%Title Color Exit
    ::: ************************************************************** ||   Script Break
    :Title
     Echo/ Title %0
     Timeout 1 > Nul
    ::: return if Called Else (Goto :label) -Alternative option is to allow script continuation
     If not "%~1"=="" (Exit /B 0)Else Goto :MainMenu
    :Color
     Echo/ Color %0
     Timeout 1 > Nul
     If not "%~1"=="" (Exit /B 0)Else Goto :MainMenu
    :Exit
     Echo/ Exit %0
    Exit /B 0
    

    Below is a pratical application of the above, minus the remarks, with a colortext function to add color to each menu option.

    @ECHO Off & Goto :main
    :ColorMenu
     rem Set /A "RR=!random! %%195 + 60","GG=!random! %%195 + 60","BB=!random! %%195 + 60"
     rem Set "%~1=%/E%38;2;!RR!;!GG!;!BB!m!%~1!%/E%0m"
     Set "rV="& IF "!#A!"=="" (Set #A=32)
     (For %%C in ("!%~1!")Do Set "rv=!rV!%/E%!#A!m%%~C%/E%0m"& Set /A "#A+=1"& IF "!#A!"=="37" (Set #A=31)) & Set "%~1=!rV!"
    Exit /B 0
    :main
    (Set LF=^
    
    
    %= empty lines above are required. =%)
    For /F eol^=^%LF%%LF%^ delims^= %%A in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09"') do Set "TAB=%%A"
     For /F %%a in ('echo prompt $E ^| cmd')do (Set "/E=%%a[")
     Set "ChoList=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     Set "Menu=For %%n in (1 2)Do if %%n==2 (!DIV!&Set "CH#=0"&(Set "CHCS="&For %%G in (!Options!)Do For %%i in (!CH#!)Do (Set "CHCS=!CHCS!!ChoList:~%%i,1!"&Set "Opt[!ChoList:~%%i,1!]=%%~G"& Set "Opt=%%~G" &Call :ColorMenu Opt & Nul ')Do Set "%%G=" > Nul 2> Nul ))"
     Set "GetFiles=(For /F "Delims=" %%O in ('Dir /B *.$E /O:-D')Do %DEF/array%"%%~fO")"
     Set "SelectFile=%DEL/array% & %GetFiles% & If "!#$E!"=="" (!DIV!&Echo/No $E files in !CD!&!DIV!&Goto :Eof)Else For %%n in (1 2)Do If %%n==2 (Set "Ext=$E"&Set "FN="&(If /I "!#$E!"=="-1" (Echo/No $E Files found. & Exit /B 0))& (For /L %%i in (0 1 !#$E!) Do If Not "!$E[%%i]!"=="" Echo/%%i:!TAB!!$E[%%i]!)&!DIV!&Echo/[%/E%36mExit%/E%0m] or Select a $E file number [%/E%36m0%/E%0m-%/E%36m!#$E!%/E%0m]:&!DIV!&Set /P "FN=FN: "&For %%v in ("!FN!")do (If /I "!FN!"=="Exit" (Exit /B 0)Else If /I "!FN!"=="E" (Exit /B 0)Else If not "!$E[%%~v]!"=="" (Set "PATH[$E]=!$E[%%~v]!"&!DIV!&Echo/!$E[%%~v]! Selected)Else (Echo/invalid file index&!DIV!& Timeout 1 /Nobreak > Nul & Goto :!rLabel! )))Else Set rLabel="
     Set "GetFolders=%DEL/array% & Set "#$E="&For /F "Delims=" %%O in ('Dir /B /A:D')Do %DEF/array%"%%~fO""
     Set "SelectFolder=Set "FN="&(If /I "!#$E!"=="-1" (Echo/No Folders found in !CD!.))& (For /L %%i in (0 1 !#$E!) Do If Not "!$E[%%i]!"=="" Echo/%%i:!TAB!!$E[%%i]!)&!DIV!&Echo/[%/E%36mExit%/E%0m ^| %/E%36m..%/E%0m] Select a $E number [%/E%36m0%/E%0m-%/E%36m!#$E!%/E%0m]:&!DIV!&Set /P "FN=$E #: "&For %%v in ("!FN!")do (If /I "!FN!"=="Exit" (Exit /B 0)Else If /I "!FN!"=="E" (Exit /B 0)Else If "!FN!"==".." (CD .. &!DIV!&Echo/!CD!&!DIV!&Exit /B)Else If not "!$E[%%~v]!"=="" (Set "$E=!$E[%%~v]!"&!DIV!&Echo/!$E[%%~v]! Selected)Else (Echo/invalid index&!DIV!& Timeout 1 /Nobreak > Nul & Goto :Dir ))"
     Set "Do=Set "FN="&If /I "!Option!"=="Exit" (Goto :Eof)Else IF /I "!Option!"=="Ren" (For %%P in ("!Path[$E]!")Do (Set /P "FN=New Name: " & If "!FN!"=="" (!DIV!%/E%31mFilename required%/E%0m&!DIV!& Goto :!rLabel!)Else If Not exist "!FN!.$E" (Ren %%~nxP !FN!.$E)Else (!DIV!&Echo/%/E%31m"!FN!.$E" Already exists.%/E%0m&!DIV! & Goto :!rLabel!)) & !DIV!&Echo/%/E%32mRename Succesful.%/E%0m&!DIV! & Goto :!rLabel!)Else IF /I "!Option!"=="View Info" (Echo/Modified:!TAB!!TAB!Size:!TAB!Attribs:!TAB!Location:&!DIV! & For %%I in ("!Path[$E]!")Do (Echo/%%~tI!TAB!%%~zI!TAB!%%~aI!TAB!%%~dpI))Else (For %%i in ("!Path[$E]!")Do IF /I Not "!Option!"=="View Info" Echo/[!Option!] !Path[$E]!&!DIV!&!Option! "%%~i")"
     Set "Wait= Echo/&!DIV!&For %%n in (1 2) Do If %%n==2 (Set "$S=Str"& Call :ColorMenu $S & Echo/!$S!&!DIV! & Timeout !TO! > Nul 2> Nul )Else Set TO="
     Setlocal EnableDelayedExpansion
     for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| findstr Columns`) do Set "Console_Width=%%%W"
     Set "DIV="&For /L %%i in (2 1 %Console_Width%)Do Set "DIV=!DIV!-"
     Set "DIV=Echo/%/E%33m!DIV!%/E%0m"
     If exist "%userprofile%\Desktop\" (Set "SourceDir=%userprofile%\Desktop\") Else (Set "SourceDir=%~dp0")
     PUSHD "%SourceDir%" && cls || (Echo/You lack write permission in %~dp0 & Exit /B 1)
    %Wait:Str=[!CD!]%0
    :menu
     Title %~n0
     %Menu% Exit "Dir Change" Batch Text Vbs Cls "All Files" "User specified command" "Attribs"
     If /I "!Option!"=="Exit" (POPD & Endlocal & Endlocal & Goto :Eof) Else If "!Option!"=="Cls" (Cls)Else Call :!Option! 2> Nul
     Set "#A=32"
     %Wait:Str=!CD!%0
     %DEL/array:$E=Bat% & %DEL/array:$E=Txt% & %DEL/array:$E=Vbs%
    Goto :menu
    :Dir Change
     %GetFolders:$E=DirPath%
     %SelectFolder:$E=DirPath%
      PUSHD "%DirPath%"
    Exit /B
    :Batch
     %SelectFile:$E=Bat%Batch
     (%Menu% "Exit /B" Type Call "Start """ "Ren" "Del /P" Notepad.exe "View Info" "User Specified Command") && If "!Option!"=="User Specified Command" ( Call :!Option! 2> Nul )Else %Do:$E=Bat%
     %Wait:Str=Continue %50
    Goto :Batch
    :Text
     %SelectFile:$E=Txt%Text
     (%Menu% "Exit /B" Type "Ren" "Del /P" Notepad.exe "View Info" "User Specified Command") && If "!Option!"=="User Specified Command" ( Call :!Option! 2> Nul )Else %Do:$E=Txt%
     %Wait:Str=Continue.%50
    Goto :Text
    :Vbs
     %SelectFile:$E=Vbs%Vbs
     (%Menu% "Exit /B" Type "Ren" "Del /P" "Start """ Notepad.exe "View Info" "User Specified Command") && If "!Option!"=="User Specified Command" ( Call :!Option! 2> Nul )Else %Do:$E=Vbs%
     %Wait:Str=Continue.%50
    Goto :Vbs
    :All Files
    Set "Spacer=                                                  "
     Echo/%/E%4m%/E%32mModified:%TAB%%TAB%%/E%90mSize:%TAB%%TAB%%/E%31mAtrribs:%TAB%%/E%34mType:%TAB%%/E%36mName:%/E%0m&Echo/
    For /F "Delims=" %%G in ('Dir /B *.* /O:-D /T:W /A:-D') Do (
     SETLOCAL DISABLEdelayedExpansion
     Set "T=%%~tG" & Set "S=%%~zG%Spacer%" & Set "A=%%~aG%Spacer%" & Set "X=%%~xG%Spacer%" & Set "N=%%~nG"
     SETLOCAL ENABLEdelayedExpansion
     

    0 讨论(0)
提交回复
热议问题