AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#1 Post by Aacini » 09 Feb 2022 14:31

AutoMenu.bat is a program that implements a method to create fully working multi-level multi-option menu systems in a simple way. A menu is assembled inside a folder via three types of nodes:

- Sub-menus, defined just via sub-folders
- Command execution, defined via .bat Batch files
- Text display, defined via .txt Text files

In this way, to assemble a full "menu-tree" you just need to define subfolders at the appropriate places, create text files to display information and create Batch files to perform the final actions. The first character in subfolder and file names define both their order in the menu and the key used to select they via CHOICE command, so this character must be unique; the second character must be a hypen.

This scheme allows you to create your own menus in a very simple way. Also, this method allows to add/modify/delete menu options with no confusion about the place/level of a given option or sub-menu. In order to keep the code simpler, the program does not limit the maximum number of allowed elements in each sub-menu level nor the maximum number of characters allowed in each name. In this way, is up to you to produce the correct appareance in the final menu layout.


AutoMenu.zip
AutoMenu.bat program and "Windows-DOS Commands Help" menu
(48.67 KiB) Downloaded 1580 times


In addition to the AutoMenu.bat file, the .zip file also includes an extensive example of a menu system called "Windows-DOS Commands Help" that displays help descriptions about cmd.exe commands arranged in a consistent way that makes it easy to navigate. Also, several basic-level descriptions about Batch-file programming are included. I taken all this information from an old project of mine, so it includes some ancient and obsolete commands (that I want not to delete for historic reasons) and does not include a few modern ones. To open this menu, run AutoMenu.bat with the name of the folder as parameter or drag-and-drop the folder over the Batch file.

A small drawback in the scheme used is that the maximum lenght of nested names (260 characters) may be reached if you use very long names with several levels deep. If the "Windows-DOS Commands Help" menu system don't show full names or don't works correctly, try to move it to an upper level folder.

I hope you enjoy this menu system! 8)

EDIT 2022/02/12: New version of AutoMenu.bat program

AutoMenu-v1.2.zip
AutoMenu.bat version 1.2 and updated revision of "Windows-DOS Commands Help" menu
(50.99 KiB) Downloaded 1772 times

You may review the changes in this new version at this post.

Antonio

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#2 Post by miskox » 10 Feb 2022 14:27

Antonio! Thank you! Very good. Lightweight. Easy to use. I am strugling to get thru the code to add something: I would like to display letter M before subfolders. To get something like this:

Code: Select all

M  1- SCREEN          Commands for Screen control
M  2- FILE            Commands for File management
M  3- DIRECTORY       Commands to create, change and remove Directories
M  4- DISK            Commands for Disk maintenance
M  5- PROCESS         Commands to execute, view or cancel Programs
M  6- COMMUNICATIONS  Commands to manage inter-computer Communications
M  7- ACCESSORIES     Commands to start standard Windows Accessories
M  8- BATCH           Commands, Values and Modifiers used in Batch files
M  9- VARIOUS         Commands that does not fit in any previous subdivision
and then:

Code: Select all

         2-FILE            Commands for File management

M  1- WHOLE     Commands to manage files as a Whole
M  2- CONTENTS  Commands to process text file Contents
and with selection 8:

Code: Select all

   1- INTRODUCTION  Introduction to Batch file programming
M  2- COMMANDS      Commands for Batch file programming
   3- CHARACTERS    Special Characters used in DOS commands and Batch files
   4- ERRORLEVEL    Description of the ERRORLEVEL value
   5- VARIABLES     Dynamic Batch Variables and enhanced expansions
   6- MODIFIERS     Enhanced expansions for (replaceable) parameters
   
Something like this - so I know when there is a submenu or when something will be executed when selected. I hope you understand.

Thanks again! Very useful.

Update: first change: I changed

Code: Select all

for /F "tokens=2-4 delims=[]=." %%a in ('set option[') do echo    %%a- %%b
to

Code: Select all

for /F "tokens=2-4 delims=[]=." %%a in ('set option[') do echo    %%a- %%~b
so extensions are not displayed.

update2:

changed line

Code: Select all

choice /N /C %choices% /M "Select the desired option (0 to exit):"
to

Code: Select all

set txtchoice=&rem
if not "!level!"=="0" set txtchoice= this submenu
choice /N /C %choices% /M "Select the desired option (0 to exit%txtchoice%):"
so CHOICE displays '0 to exit' when at the top or '0 to exit this submenu'.

Still trying to figure out the best way to add 'M' to the (sub)menus (here somewhere

Code: Select all

for /F "tokens=2-4 delims=[]=." %%a in ('set option[') do echo    %%a- %%~b
I will add new variable just right of the ECHO...

Saso

Jer
Posts: 177
Joined: 23 Nov 2014 17:13
Location: California USA

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#3 Post by Jer » 11 Feb 2022 14:54

What would be an example command to AutoMenu.bat?
My entry on a Windows 10 PC in the cmd window from the directory where your files are stored c:\AMenu

automenu c:\temp 2- FILE
Environment variable option[ not defined
followed by continuous looping of the error message.
Thanks.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#4 Post by Aacini » 11 Feb 2022 22:46

Jer wrote:
11 Feb 2022 14:54
What would be an example command to AutoMenu.bat?
Aacini wrote:
09 Feb 2022 14:31
To open this menu, run AutoMenu.bat with the name of the folder as parameter
For example:

Code: Select all

automenu "Windows-DOS Commands Help"
or drag-and-drop the "Windows-DOS Commands Help" folder over the Batch file...

Antonio

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#5 Post by Aacini » 12 Feb 2022 09:21

miskox wrote:
10 Feb 2022 14:27
Antonio! Thank you! Very good. Lightweight. Easy to use. I am strugling to get thru the code to add something

@miskox,

Thanks a lot for your suggestions, I included they in the new version 1.2 of AutoMenu.bat

miskox wrote:
10 Feb 2022 14:27
I would like to display letter M before subfolders. To get something like this:

Code: Select all

M  1- SCREEN          Commands for Screen control
M  2- FILE            Commands for File management
M  3- DIRECTORY       Commands to create, change and remove Directories
M  4- DISK            Commands for Disk maintenance
M  5- PROCESS         Commands to execute, view or cancel Programs
M  6- COMMUNICATIONS  Commands to manage inter-computer Communications
M  7- ACCESSORIES     Commands to start standard Windows Accessories
M  8- BATCH           Commands, Values and Modifiers used in Batch files
M  9- VARIOUS         Commands that does not fit in any previous subdivision

I like your idea. However, I dont like the "M" letter to indicate a submenu. I used the ">" character instead. If you don't like it, just change it in this line:

Code: Select all

   if "!descrip[%%a]:~-4,1!" equ "." (set "type[%%a]= ") else set "type[%%a]=>"


miskox wrote:
10 Feb 2022 14:27
changed line

Code: Select all

choice /N /C %choices% /M "Select the desired option (0 to exit):"
to

Code: Select all

set txtchoice=&rem
if not "!level!"=="0" set txtchoice= this submenu
choice /N /C %choices% /M "Select the desired option (0 to exit%txtchoice%):"
so CHOICE displays '0 to exit' when at the top or '0 to exit this submenu'.

Good idea, but I used "0 to go back" to exit from a submenu, and "0 to exit" to exit from the main menu.

I completed several small changes to get a better performance. The current menu option is now displayed in the window title. When a .txt file is displayed or a .bat file is executed, the menu is cleared and just the current option is shown as header in the screen (if you want the former behavior, change the value described in the code).

The most important change in this version is that the names of the folders and files not longer needs to include filler spaces for alignment. The names now must have this format: K-NAME-Description of this option so the program will search for the longest name and adjust the rest accordingly. This feature not just makes easier to write a menu but also decreases the total lenght of the nested names, so it can help to avoid the "max lenght exceeded" problem.

I also reviewed the "Windows-DOS Commands Help" menu to fix some small details and include almost all of the modern and frequently used commands that was missing.

The new AutoMenu.bat version 1.2 is in the first post of this topic as usual.

Antonio

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#6 Post by miskox » 12 Feb 2022 14:57

Thanks Aacini!

Great. Why I prefer 'M' over '>'? Because this is a prompt application and with a '>' somebody would want do tap/click on it... Let keep the app a console/character oriented. And this goes back to my DIGITIAL OpenVMS VT terminal era...

Thanks again. Works great.

Saso

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#7 Post by miskox » 13 Feb 2022 14:54

Maybe an idea for another version: without CHOICE but with SET /P.

Why?

Maybe I want to select a .bat and to provide some paramaters. In this way SET /P would be better. With choice I can select the .bat and this .bat checks for %1 and if it is missing then it asks for the params...

Maybe just an idea.

Another question: could .cmd be added to the list? Or maybe we can replace .bat with .cmd ?

I prefer .cmd over .bat.

Saso

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#8 Post by Aacini » 17 Feb 2022 22:50

I have developed a couple programs that aids in creating and maintaining AutoMenu.bat menu folders.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem EditMenu.bat: Insert/Extract options into/from a menu folder
rem Antonio Perez Ayala

if "%~1" neq "" if "%~1" neq "/?" goto begin
echo Insert/Extract options into/from a menu folder
echo/
echo    EditMenu.bat menuFolder [k [newOption]]
echo/
echo K is the character Key for the old/new option
echo NewOption is the name of a subfolder or .BAT/.TXT file
echo/
echo If both K and newOption are given, the option is inserted at K position.
echo/
echo If just K is given, such an existent option is extracted from the menu
echo and placed alone. If you want to remove it, delete such a folder or file.
echo/
echo In both cases, the rest of options are reordered in the menu.
echo/
echo If K is not given either, the program navigate the menu folder and check
echo that all subfolders and files have the format required for AutoMenu.bat
goto :EOF

:begin

cd %1 || ( echo Menu folder not exist: %1 & goto :EOF )

if "%~2" neq "" goto editMenu

cls
echo/
:checkMenu
setlocal EnableDelayedExpansion
echo %~1
for /F "delims=" %%f in ('dir /B') do for /F "tokens=1,2* delims=-" %%a in ("%%f") do (
   set "key=%%a"
   if "%%b" equ "" (
      echo === Option and description missing ===
      echo %%f
      echo ======================================
   ) else if "%%c" equ "" (
      echo === Description missing ===
      echo %%f
      echo ===========================
   ) else if "!key:~1!" neq "" (
      echo === Selection key must be a single char ===
      echo %%f
      echo ===========================================
   )
   set "name=%%f"
   if "!name:~-4,1!" neq "." (
      cd "%%f"
      call :checkMenu "%%f"
      cd ..
   )
)
goto :EOF


:editMenu
echo/
echo Edit menu %cd%
dir /B
echo/
set "options=123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

if "%~3" neq "" goto insertOption

:deleteOption
set "newKey="
for /F "tokens=1* delims=-" %%a in ('dir /B') do (
   if not defined newKey (
      if "%%a" equ "%~2" (
         ren "%%a-%%b" "%%b"
         echo Option %%a extracted as "%%b"
         set "newKey=%%a!options:*%%a=!"
      )
   ) else (
      ren "%%a-%%b" "!newKey:~0,1!-%%b"
      set "newKey=!newKey:~1!"
   )
)
echo/
dir /B
goto :EOF

:insertOption
if not exist "%~3" echo New option not exists: %3 & goto :EOF
set "newKey="
for /F "tokens=1* delims=-" %%a in ('dir /B') do (
   if not defined newKey (
      if "%%a" equ "%~2" (
         ren "%~3" "%%a-%~3"
         echo Option "%~3" inserted at position %%a
         set "newKey=!options:*%%a=!"
         ren "%%a-%%b" "!newKey:~0,1!-%%b" 2> NUL
         set "newKey=!newKey:~1!"
      )
   ) else (
      ren "%%a-%%b" "!newKey:~0,1!-%%b"
      set "newKey=!newKey:~1!"
   )
)
echo/
dir /B
goto :EOF
EditMenu.bat is an auxiliary program useful to insert a new option in the menu folder, or to delete an option from the menu folder. Use it this way:

Code: Select all

EditMenu.bat menuFolder [K [NewOption]]
K is the character Key for the new option and NewOption is the name of a subfolder or .BAT/.TXT file that will be inserted in the menu. The NewOption must be in the same menuFolder and must have the same name format of the other options, excepting for the Key part. For example, lets assume that in "A Menu Example" folder there are these options:

Code: Select all

1-FIRST-This is the first option
2-SECOND-The second one
3-THIRD-The third option
4-FOURTH-And the fourth and last one
NEW-This is the new option
After execute this line:

Code: Select all

EditMenu.bat "A Menu Example" 3 "NEW-This is the new option"
... the contents of "A Menu Example" folder will be this one:

Code: Select all

1-FIRST-This is the first option
2-SECOND-The second one
3-NEW-This is the new option
4-THIRD-The third option
5-FOURTH-And the fourth and last one
If just K is given, such an existent option is extracted from the menu. If after previous example you execute this line:

Code: Select all

EditMenu.bat "A Menu Example" 2
... then the folder contents would be this:

Code: Select all

1-FIRST-This is the first option
2-NEW-This is the new option
3-THIRD-The third option
4-FOURTH-And the fourth and last one
SECOND-The second one
If you want to delete the original option 2, just delete the "SECOND-The second one" folder/file. If you want to move such an option to other place, insert it now in its new place.

As you can see, this program makes it very easy to create and maintain large menu folders. I wish I had it when I created the "Windows-DOS Command Help" large menu! :(

If K key is not given either, the program navigate the menu folder and check that all subfolders and files have the format required for AutoMenu.bat. Any option with a bad format will makes AutoMenu.bat fail.


===========================================================================================

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem MakeAlpha.bat: Collect all *.bat files from an AutoMenu.bat menu folder
rem                and create an Alpha folder with letter subfolders
rem Antonio Perez Ayala

if "%~1" equ "" echo Usage: %~NX0 menuFolder & goto :EOF
if not exist %1 echo Menu folder not exist: %1 & goto :EOF
for %%d in (%1) do set "dest=%%~DPdAlpha"
if exist "%dest%" (
   set /P "=Delete " < NUL
   rd /S "%dest%" 2>NUL
)
cls
md "%dest%"
rem Step 1: Collect *.bat files in corresponding letter subfolders
set "level=-1"
call :nextLevel %1
rem Step 2: Adjust names of letter folders
echo/
echo -----------------------------
cd "%dest%"
for /F %%d in ('dir /B') do (
   echo/
   echo Letter: "%%d"
   cd %%d
   set "name="
   set "option=123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   for /F "delims=" %%f in ('dir /B') do for /F "delims=-" %%a in ("%%f") do (
      echo    %%a
      ren "%%f" "!option:~0,1!-%%f"
      set "option=!option:~1!"
      if "!name:~-3!" neq "etc" (
         set "newName=!name! %%a"
         if "!newName:~62!" equ "" (
            set "name=!newName!"
         ) else (
            set "name=!name! etc"
         )
      )
   )
   cd ..
   ren %%d "%%d-%%d-!name!"
)
goto :EOF


:nextLevel folder

setlocal EnableDelayedExpansion
cd %1
echo/
echo Folder: %~1
set /A level+=1
if %level% leq 1 (
   for /F "tokens=1,2 delims=-" %%a in ("%~N1") do set "parent=%%a-%%b"
) else (
   set /P "parent=Enter "parent" reference for nested subfolder: "
)
for %%f in (*.bat) do for /F "tokens=1,2 delims=-" %%a in ("%%f") do (
   echo    %%a-%%b
   set "letter=%%b" & set "letter=!letter:~0,1!"
   if not exist "%dest%\!letter!" md "%dest%\!letter!"
   REM Change "COPY" by "MKLINK" to create symbolic links instead:
   copy "%%f" "%dest%\!letter!\%%b-%parent%.bat" > NUL
   REM mklink "%dest%\!letter!\%%b-%parent%.bat" "%%~Ff" > NUL
)
for /D %%d in (*) do call :nextLevel "%%d"
exit /B

The other auxiliary program is MakeAlpha.bat. This program navigate for all options of the menu folder given in the parameter, order they in alphabetical order, and copy/accumulate they in letter subfolders that are created under "Alpha" folder. Each new option include as description a backwards reference to the original option in the base menu. After that, the program process the new Alpha menu folder options and insert in their descriptions a list of the original options included in each letter. The result is an alphabetical index of the options in the original menu.

After the Alpha menu folder was created, you must insert it as a new option in the original menu. For example:

Code: Select all

rem Create the Alpha menu folder of "Windows-DOS Commands Help" menu
MakeAlpha.bat "Windows-DOS Commands Help"

rem Insert it as the last option in the original menu
move "Alpha" "Windows-DOS Commands Help\A-ALPHA-Commands in Alphabetical order"
The result is pretty good! 8)

Image


An interesting aspect of MakeAlpha.bat program is that the new options inserted in the Alpha menu could be symbolic links to the original files, instead of physical copies of the files. To do that, change the specified line in the MakeAlpha.bat program in order to use MKLINK command instead of COPY, but remember that you must have admin privileges in order to use MKLINK. This could be very useful if the option files are large.

For example, suppose you organize your music .MP3 files collection in folders distributed in several sublevels, like AUTHOR>ALBUM>TRACK. If you want to create an Alpha list of all songs in your collection, the new menu must have a copy of each music file, but if such a "copy" is a symbolic link, then the data space occupied by each .mp3 file is not duplicated. You may use the same method to create "sub-collections" of songs in any other order, like by type of music, or individual play lists, etc. BTW I am currently working in a method to play music files from an AutoMenu menu.

Antonio

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#9 Post by miskox » 15 Jun 2024 14:03

Looks like I will put this menu system into a good use (I have some .cmd files to run so I will need a menu system).

So I was making some more tests with real .cmd files...

I had to add one line and change one line to support .cmd extension too:

Added line 33:

Code: Select all

set "action[.cmd]=call"
Changed line 49 (in original .bat, line 50 in updated .bat):

From:

Code: Select all

for /F "tokens=1,2* delims=-" %%a in ('dir /B *. *.txt *.bat') do (
to

Code: Select all

for /F "tokens=1,2* delims=-" %%a in ('dir /B *. *.txt *.bat .cmd') do (
Antonio: thank you again for this great and short menu system.

Saso

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#10 Post by miskox » 18 Jun 2024 04:31

I added

Code: Select all

@echo off
after this line:

Code: Select all

   !action[%descrip:~-4%]! "%choice%-%option%-%descrip%"
So if the called .cmd/.bat has ECHO ON it is turned off.

Aacini: how could I translate it? I have problems with

Code: Select all

set "textChoice=go back|exit"
My translated text has different lengths.

Code: Select all

set "textChoice=nazaj|izhod"
Saso

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#11 Post by miskox » 26 Jun 2024 22:49

2Aacini: here is version 1.3 if you want to added it to your first post.

Changes:

- added an easy way to translate three messages (everything else remains in English): 'Select the desired option', 'menu folder does not exist' and 'go back/exit'
- added .cmd as supported file type
- changed action from 'type' to 'more' for .txt files

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem ==================================================================
rem Automatic multi-level multi-option menu system
rem Antonio Perez Ayala    - 2022/02/09
rem            version 1.2 - 2022/02/12
rem Saso Tomat version 1.3 - 2024/06/26
rem  - added option for translation
rem  - added .cmd as supported file type
rem  - added @echo off if called .bat has echo set to ON
rem  - changed action from 'type' to 'more' for .txt files
rem ==================================================================
rem https://www.dostips.com/forum/viewtopic.php?f=3&t=10377

rem ==================================================================
rem translation of necessary text (everything else remains in English)
rem ==================================================================
REM Second SET could be used for translation
set "ChoiceExeText=Select the desired option (0 to"
set "ChoiceExeText=Select the desired option (0 to"

REM Second SET could be used for translation
set "notexist=Menu folder %1 does not exist."
set "notexist=Menu folder %1 does not exist."

REM Second SET could be used for translation
REM 'exit' text should not exceed the length of the 'go back' text
set "textChoice=go back|exit"
set "textChoice=go back|exit"
rem ==================================================================

rem Get text lengths of both 'go back' and 'exit' options.
for /f "tokens=1,2 delims=|" %%f in ("%textChoice%") do (
	>len1.tmp (echo %%f)
	>len2.tmp (echo %%g)
)
for %%f in (len1.tmp) do set /a len1=%%~zf - 1
for %%f in (len2.tmp) do set /a len2=%%~zf - 1
if exist len1.tmp del len1.tmp
if exist len2.tmp del len2.tmp

REM line below checks if the 'exit' option text is longer than the 'go back' option text
REM to prevent unwanted displaying of text.
if %len2% GTR %len1% echo Second 'TextChoice' string ('exit' string) should be shorter.&pause&goto :EOF

if "%~1" neq "" if "%~1" neq "/?" goto begin
echo Activate a multi-level multi-option menu system
echo/
echo    %~NX0 menuFolder
echo/
echo The menu is defined into menuFolder via subfolders, .txt and .bat files.
echo The names of these elements must have this format:
echo    K-NAME-Description of this option
echo where "K" is a character used in CHOICE.EXE to select this option.
echo/
echo Review the extensive example at "Windows-DOS Commands Help" folder.
goto :EOF

:begin
rem Select menu folder and get its name for title and header
if not exist "%~1\" echo %notexist%& goto :EOF
set "title=%~N1"
set "header[0]="
for /L %%i in (0,1,80) do if "!title:~%%i,1!" neq "" set "header[0]=!header[0]! !title:~%%i,1!"
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set "header[0]=!header[0]:%%a=%%a!"
set "spaces=         "
set "action[.txt]=more"
set "action[.bat]=call"
set "action[.cmd]=call"
color 1F
set "level=0"
call :nextLevel %1
color
cls
goto :EOF


:nextLevel subFolder
rem Enter next subFolder level and get directories, .txt, .cmd and .bat files
setlocal EnableDelayedExpansion
cd %1
for /F "delims==" %%a in ('set option[ 2^>NUL') do set "%%a="
set "choices= 0"
set "maxLen=0"
set "spc= "
for /F "tokens=1,2* delims=-" %%a in ('dir /B *. *.txt *.bat *.cmd') do (
   set "choices=!choices!%%a"
   set "option[%%a]=%%b"
   for /L %%i in (!maxLen!,1,40) do if "!option[%%a]:~%%i,1!" neq "" set "maxLen=%%i" & set "spc=!spc! "
   set "descrip[%%a]=%%c"
   if "!descrip[%%a]:~-4,1!" equ "." (set "type[%%a]= ") else set "type[%%a]=>"
)
set /A maxLen+=2
for /F "tokens=2 delims=[]" %%a in ('set option[') do (
   set "show[%%a]=!option[%%a]!%spc%"
   set "show[%%a]= !show[%%a]:~0,%maxLen%!"
)

:thisLevel
rem Show menu options at this level
title !title!
cls
echo/
for /L %%i in (0,1,%level%) do (
   set /A "spc=%%i*3"
   for %%n in ("!spc!") do echo    !spaces:~%%~n!!header[%%i]!& echo/
)
for /F "tokens=2 delims=[]" %%a in ('set option[') do (
   for %%b in ("!descrip[%%a]!") do echo !type[%%a]!  %%a-!show[%%a]! %%~Nb
)
echo/

rem Select option and activate it: open subfolder or: show .txt file / run .bat or .cmd file
set /A "cho=^!level * len1"
call set textChoice0=!textChoice:~%cho%,%len1%!
choice.exe /N /C %choices% /M "!ChoiceExeText! !textChoice0!): "
set "choice=!choices:~%errorlevel%,1!"
if %choice% == 0 exit /B
set "option=!option[%choice%]!"
set "lastTitle=%title%"
set "title=%title%  >  %choice%-%option%"
title !title!
set "descrip=!descrip[%choice%]!"
set /A "level+=1"
for %%a in ("%descrip%") do set "header[%level%]=%choice%- %option%  %%~Na"
if "%descrip:~-4,1%" neq "." (
   call :nextLevel "%choice%-%option%-%descrip%"
) else (

   rem If you want to preserve full menu on screen while a .bat or .txt run, cancel next IF:
   if CLEAR == CLEAR (
      cls
      for /L %%i in (0,1,%level%) do (
         set /A "spc=%%i*3"
         for %%n in ("!spc!") do echo/& echo    !spaces:~%%~n!!header[%%i]!
      )
   )

   echo/
   !action[%descrip:~-4%]! "%choice%-%option%-%descrip%"
   @echo off
   echo/
   pause
)
set /A "level-=1"
set "title=%lastTitle%"
goto thisLevel

Saso

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#12 Post by miskox » 14 Aug 2024 03:28

Version 1.4:

To exit main menu key 0 was replaced by key (letter) X (could be changed to Q (for Quit) or whatever you want). If you have lots of submenus and keep pressing on key 0 to return to previous menu you could exit main menu even if you don't want to.

Of course submenu should not have this letter as a choice.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem ==================================================================
rem Automatic multi-level multi-option menu system
rem Antonio Perez Ayala    - 2022/02/09
rem            version 1.2 - 2022/02/12
rem
rem Saso Tomat version 1.3 - 2024/06/26
rem  - added option for translation
rem  - added .cmd as supported file type
rem  - added @echo off if called .bat has echo set to ON
rem  - changed action from 'type' to 'more' for .txt files
rem
rem Saso Tomat version 1.4 - 2024/08/14
rem  - to exit main menu key 0 was replaced by X
rem    (prevents exit from the main menu when
rem     pressing on 0 to exit submenus)
rem ==================================================================
rem https://www.dostips.com/forum/viewtopic.php?f=3&t=10377

rem ==================================================================
rem translation of necessary text (everything else remains in English)
rem ==================================================================

REM Letter to exit main menu
set "LetterToExitMainMenu=X"

REM Second SET could be used for translation
set "ChoiceExeText=Select the desired option ("
set "ChoiceExeText=Select the desired option ("

REM Second SET could be used for translation
set "notexist=Menu folder %1 does not exist."
set "notexist=Menu folder %1 does not exist."

REM Second SET could be used for translation
REM 'exit' text should not exceed the length of the 'go back' text
set "textChoice=0 to go back|%LetterToExitMainMenu% to exit"
set "textChoice=0 to go back|%LetterToExitMainMenu% to exit"


rem ==================================================================

rem Get text lengths of both 'go back' and 'exit' options.
for /f "tokens=1,2 delims=|" %%f in ("%textChoice%") do (
	>len1.tmp (echo %%f)
	>len2.tmp (echo %%g)
)
for %%f in (len1.tmp) do set /a len1=%%~zf - 1
for %%f in (len2.tmp) do set /a len2=%%~zf - 1
if exist len1.tmp del len1.tmp
if exist len2.tmp del len2.tmp

REM line below checks if the 'exit' option text is longer than the 'go back' option text
REM to prevent unwanted displaying of text.
if %len2% GTR %len1% echo Second 'TextChoice' string ('exit' string) should be shorter.&pause&goto :EOF

if "%~1" neq "" if "%~1" neq "/?" goto begin
echo Activate a multi-level multi-option menu system
echo/
echo    %~NX0 menuFolder
echo/
echo The menu is defined into menuFolder via subfolders, .txt and .bat files.
echo The names of these elements must have this format:
echo    K-NAME-Description of this option
echo where "K" is a character used in CHOICE.EXE to select this option.
echo/
echo Review the extensive example at "Windows-DOS Commands Help" folder.
goto :EOF

:begin
rem Select menu folder and get its name for title and header
if not exist "%~1\" echo %notexist%& goto :EOF
set "title=%~N1"
set "header[0]="
for /L %%i in (0,1,80) do if "!title:~%%i,1!" neq "" set "header[0]=!header[0]! !title:~%%i,1!"
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set "header[0]=!header[0]:%%a=%%a!"
set "spaces=         "
set "action[.txt]=more"
set "action[.bat]=call"
set "action[.cmd]=call"
color 1F
set "level=0"
call :nextLevel %1
color
cls
goto :EOF


:nextLevel subFolder
rem Enter next subFolder level and get directories, .txt, .cmd and .bat files
setlocal EnableDelayedExpansion
cd %1
for /F "delims==" %%a in ('set option[ 2^>NUL') do set "%%a="
set "choices= 0"
if "%level%"=="0" set "choices= %LetterToExitMainMenu%"
set "maxLen=0"
set "spc= "
for /F "tokens=1,2* delims=-" %%a in ('dir /B *. *.txt *.bat *.cmd') do (
   set "choices=!choices!%%a"
   set "option[%%a]=%%b"
   for /L %%i in (!maxLen!,1,40) do if "!option[%%a]:~%%i,1!" neq "" set "maxLen=%%i" & set "spc=!spc! "
   set "descrip[%%a]=%%c"
   if "!descrip[%%a]:~-4,1!" equ "." (set "type[%%a]= ") else set "type[%%a]=>"
)
set /A maxLen+=2
for /F "tokens=2 delims=[]" %%a in ('set option[') do (
   set "show[%%a]=!option[%%a]!%spc%"
   set "show[%%a]= !show[%%a]:~0,%maxLen%!"
)

:thisLevel
rem Show menu options at this level
title !title!
cls
echo/
for /L %%i in (0,1,%level%) do (
   set /A "spc=%%i*3"
   for %%n in ("!spc!") do echo    !spaces:~%%~n!!header[%%i]!& echo/
)
for /F "tokens=2 delims=[]" %%a in ('set option[') do (
   for %%b in ("!descrip[%%a]!") do echo !type[%%a]!  %%a-!show[%%a]! %%~Nb
)
echo/

rem Select option and activate it: open subfolder or: show .txt file / run .bat or .cmd file
set /A "cho=^!level * len1"
call set textChoice0=!textChoice:~%cho%,%len1%!
choice.exe /N /C %choices% /M "!ChoiceExeText!!textChoice0!): "
set "choice=!choices:~%errorlevel%,1!"
if not "%level%"=="0" if "%choice%"=="0" exit /B
if     "%level%"=="0" if "%choice%"=="%LetterToExitMainMenu%" exit /B
set "option=!option[%choice%]!"
set "lastTitle=%title%"
set "title=%title%  >  %choice%-%option%"
title !title!
set "descrip=!descrip[%choice%]!"
set /A "level+=1"
for %%a in ("%descrip%") do set "header[%level%]=%choice%- %option%  %%~Na"
if "%descrip:~-4,1%" neq "." (
   call :nextLevel "%choice%-%option%-%descrip%"
) else (

   rem If you want to preserve full menu on screen while a .bat or .txt run, cancel next IF:
   if CLEAR == CLEAR (
      cls
      for /L %%i in (0,1,%level%) do (
         set /A "spc=%%i*3"
         for %%n in ("!spc!") do echo/& echo    !spaces:~%%~n!!header[%%i]!
      )
   )

   echo/
   !action[%descrip:~-4%]! "%choice%-%option%-%descrip%"
   @echo off
   echo/
   echo Press any key to return to main menu.
   pause
)
set /A "level-=1"
set "title=%lastTitle%"
goto thisLevel
Aacini: thank you again for this menu system. Very useful and easy to maintain.

Update 22-oct-2024:

Line

Code: Select all

if     "%level%"=="0" if "%choice%"=="X" exit /B
was replaced by

Code: Select all

if     "%level%"=="0" if "%choice%"=="%LetterToExitMainMenu%" exit /B
Saso
Last edited by miskox on 22 Oct 2024 03:27, edited 1 time in total.

bitwise
Posts: 2
Joined: 20 Oct 2024 12:20

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#13 Post by bitwise » 20 Oct 2024 13:41

I have been looking for an easier to use batch menu for work to replace the one I wrote and found AutoMenu.bat!
I was able to get all my "tools" from my menu converted to AutoMenu format pretty quickly.

I would really like to force the enter key be used after a menu option is typed in. I attempted to make the update; I think I have it in the correct spot.
This update allows for changing selection before running (some of my "tools" can do things that I do not want to run accidently).
I would like to hear others take on this as I might not have it exactly right.

Adding the below code below line 131 (version 1.4) seems to work

Code: Select all

set /p "choice=!ChoiceExeText!!textChoice0!): "
I also upated line 134 (old line 133) to handle X or x (added switch /I after if) I think that is necessary because of using set /p

Code: Select all

if     "%level%"=="0" if /I "%choice%"=="X" exit /B
Starting at line 130

Code: Select all

::choice.exe /N /C %choices% /M "!ChoiceExeText!!textChoice0!): "
set "choice=!choices:~%errorlevel%,1!"
set /p "choice=!ChoiceExeText!!textChoice0!): "
if not "%level%"=="0" if "%choice%"=="0" exit /B
if     "%level%"=="0" if /I "%choice%"=="X" exit /B
I also upated line 134 (old line 133) to

Code: Select all

if     "%level%"=="0" if /I "%choice%"=="X" exit /B

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#14 Post by miskox » 21 Oct 2024 02:45

Thanks!

Quickly I would say that this line

Code: Select all

set "choice=!choices:~%errorlevel%,1!"
should be

Code: Select all

set "choice=!choices:~1,1!"
I will check everything else later today.

Saso

miskox
Posts: 631
Joined: 28 Jun 2010 03:46

Re: AutoMenu.bat: simple multi-level menu system (with a coherent help on Windows-DOS commands)

#15 Post by miskox » 21 Oct 2024 09:43

Version 1.5:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem ==================================================================
rem Automatic multi-level multi-option menu system
rem Antonio Perez Ayala    - 2022/02/09
rem            version 1.2 - 2022/02/12
rem ------------------------------------------------------------------
rem Saso Tomat version 1.3 - 2024/06/26
rem  - added option for translation
rem  - added .cmd as supported file type
rem  - added @echo off if called .bat has echo set to ON
rem  - changed action from 'type' to 'more' for .txt files
rem ------------------------------------------------------------------
rem Saso Tomat version 1.4 - 2024/08/14
rem  - to exit main menu key 0 was replaced by X
rem    (prevents exit from the main menu when
rem     pressing on 0 to exit submenus)
rem ------------------------------------------------------------------
rem Saso Tomat version 1.5 - 2024/10/21
rem  - added an option to choose CHOICE.EXE or SET /P
rem ==================================================================
rem https://www.dostips.com/forum/viewtopic.php?f=3&t=10377

rem ==================================================================
rem below you can choose to use CHOICE.EXE or SET /P
rem valid options are 0 and 1
set use_choiceexe=0
rem ==================================================================

rem set use_choiceexe to 1 if wrong value has been set above
if not "%use_choiceexe%"=="1" if not "%use_choiceexe%"=="0" set use_choiceexe=1
 
rem ==================================================================
rem translation of necessary text (everything else remains in English)
rem ==================================================================

REM Letter to exit main menu
set "LetterToExitMainMenu=X"

REM Second SET could be used for translation
set "ChoiceExeText=Select the desired option ("
set "ChoiceExeText=Select the desired option ("

REM Second SET could be used for translation
set "notexist=Menu folder %1 does not exist."
set "notexist=Menu folder %1 does not exist."

REM Second SET could be used for translation
REM 'exit' text should not exceed the length of the 'go back' text
set "textChoice=0 to go back|%LetterToExitMainMenu% to exit"
set "textChoice=0 to go back|%LetterToExitMainMenu% to exit"


rem ==================================================================

rem Get text lengths of both 'go back' and 'exit' options.
for /f "tokens=1,2 delims=|" %%f in ("%textChoice%") do (
	>len1.tmp (echo %%f)
	>len2.tmp (echo %%g)
)
for %%f in (len1.tmp) do set /a len1=%%~zf - 1
for %%f in (len2.tmp) do set /a len2=%%~zf - 1
if exist len1.tmp del len1.tmp
if exist len2.tmp del len2.tmp

REM line below checks if the 'exit' option text is longer than the 'go back' option text
REM to prevent unwanted displaying of text.
if %len2% GTR %len1% echo Second 'TextChoice' string ('exit' string) should be shorter.&pause&goto :EOF

if "%~1" neq "" if "%~1" neq "/?" goto begin
echo Activate a multi-level multi-option menu system
echo/
echo    %~NX0 menuFolder
echo/
echo The menu is defined into menuFolder via subfolders, .txt and .bat files.
echo The names of these elements must have this format:
echo    K-NAME-Description of this option
echo where "K" is a character used in CHOICE.EXE to select this option.
echo/
echo Review the extensive example at "Windows-DOS Commands Help" folder.
goto :EOF

:begin
rem Select menu folder and get its name for title and header
if not exist "%~1\" echo %notexist%& goto :EOF
set "title=%~N1"
set "header[0]="
for /L %%i in (0,1,80) do if "!title:~%%i,1!" neq "" set "header[0]=!header[0]! !title:~%%i,1!"
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set "header[0]=!header[0]:%%a=%%a!"
set "spaces=         "
set "action[.txt]=more"
set "action[.bat]=call"
set "action[.cmd]=call"
color 1F
set "level=0"
call :nextLevel %1
color
cls
goto :EOF


:nextLevel subFolder
rem Enter next subFolder level and get directories, .txt, .cmd and .bat files
setlocal EnableDelayedExpansion
cd %1
for /F "delims==" %%a in ('set option[ 2^>NUL') do set "%%a="
set "choices= 0"
if "%level%"=="0" set "choices= %LetterToExitMainMenu%"
set "maxLen=0"
set "spc= "
for /F "tokens=1,2* delims=-" %%a in ('dir /B *. *.txt *.bat *.cmd') do (
   set "choices=!choices!%%a"
   set "option[%%a]=%%b"
   for /L %%i in (!maxLen!,1,40) do if "!option[%%a]:~%%i,1!" neq "" set "maxLen=%%i" & set "spc=!spc! "
   set "descrip[%%a]=%%c"
   if "!descrip[%%a]:~-4,1!" equ "." (set "type[%%a]= ") else set "type[%%a]=>"
)
set /A maxLen+=2
for /F "tokens=2 delims=[]" %%a in ('set option[') do (
   set "show[%%a]=!option[%%a]!%spc%"
   set "show[%%a]= !show[%%a]:~0,%maxLen%!"
)

:thisLevel
rem Show menu options at this level
title !title!
cls
echo/
for /L %%i in (0,1,%level%) do (
   set /A "spc=%%i*3"
   for %%n in ("!spc!") do echo    !spaces:~%%~n!!header[%%i]!& echo/
)
for /F "tokens=2 delims=[]" %%a in ('set option[') do (
   for %%b in ("!descrip[%%a]!") do echo !type[%%a]!  %%a-!show[%%a]! %%~Nb
)
echo/

rem Select option and activate it: open subfolder or: show .txt file / run .bat or .cmd file
set /A "cho=^!level * len1"
call set textChoice0=!textChoice:~%cho%,%len1%!
if "%use_choiceexe%"=="0" (
REM set default selection as $ - so just pressing ENTER does nothing
	set "choice=$"
REM 	set "choice=!choices:~1,1!"
REM if you want default selection to be 'LetterToExit' or 0 uncomment the SET line above
	set /p "choice=!ChoiceExeText!!textChoice0!): "
	set "choice=!choice: =!"
	if not "!choice:~1,1!"=="" goto :thislevel
	set "choice=!choice:~0,1!"
	for %%w in ("a=A" "b=B" "c=C" "d=D" "e=E" "f=F" "g=G" "h=H" "i=I" "j=J" "k=K" "l=L" "m=M" "n=N" "o=O" "p=P" "q=Q" "r=R" "s=S" "t=T" "u=U" "v=V" "w=W" "x=X" "y=Y" "z=Z") do call set choice=%%choice:%%~w%%%
	call set choicetmp=%%choices:!choice!=%%%
	if "!choicetmp!"=="!choices!" goto :thislevel
) else (
	choice.exe /N /C %choices% /M "!ChoiceExeText!!textChoice0!): "
	call set "choice=%%choices:~!errorlevel!,1%%%"
)

if not "%level%"=="0" if    "%choice%"=="0"                      exit /B
if     "%level%"=="0" if /I "%choice%"=="%LetterToExitMainMenu%" exit /B

set "option=!option[%choice%]!"
set "lastTitle=%title%"
set "title=%title%  >  %choice%-%option%"
title !title!
set "descrip=!descrip[%choice%]!"
set /A "level+=1"
for %%a in ("%descrip%") do set "header[%level%]=%choice%- %option%  %%~Na"
if "%descrip:~-4,1%" neq "." (
   call :nextLevel "%choice%-%option%-%descrip%"
) else (

   rem If you want to preserve full menu on screen while a .bat or .txt run, cancel next IF:
   if CLEAR == CLEAR (
      cls
      for /L %%i in (0,1,%level%) do (
         set /A "spc=%%i*3"
         for %%n in ("!spc!") do echo/& echo    !spaces:~%%~n!!header[%%i]!
      )
   )

   echo/
   !action[%descrip:~-4%]! "%choice%-%option%-%descrip%"
   @echo off
   echo/
   echo Press any key to return to main menu.
   pause
)
set /A "level-=1"
set "title=%lastTitle%"
goto thisLevel
You can choose to use CHOICE.EXE of SET /P -see comments. If using SET /P default selection is $ so just pressing ENTER will do nothing. If you want X or 0 to be default selection just uncomment an appropriate SET line.

Another option would be to use a second CHOICE.EXE instead of SET /P (for conirmation only).

Saso

Post Reply