2015-12-16 3 views
0

Я читал как avoid spaghetti code in batch files.Избегая кода спагетти

В примере того, что такое код спагетти, я понял, что пакетный файл, который я использую при входе в систему, почти соответствует этому примеру. Может кто-нибудь, пожалуйста, помогите мне сделать мой пакетный файл без кода спагетти?

@ECHO OFF 
CLS 


:MENU 
echo Welcome %USERNAME% 

echo 1 - Start KeePass 
echo 2 - Backup 
echo 3 - FireFox 
echo 4 - Exit 

SET /P M=Please Enter Selection, then Press Enter: 

IF %M%==1 GOTO StarKeePass 
IF %M%==2 GOTO Backup 
IF %M%==3 GOTO FireFox 
IF %M%==4 GOTO :EOF 
GOTO MENU 


:StarKeePass 
SET keePass="%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe" 
SET kdb="%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx" 

echo I'll start KeePass for You 
START "" %keePass% %kdb% 

GOTO MENU 

:Backup 
SET backup="%USERPROFILE%\backup.bat" 
call %backup% 

GOTO MENU 

:FireFox 
cd "C:\Program Files (x86)\Mozilla Firefox\" 
start firefox.exe 

GOTO MENU 
+2

Это окончательно не спагетти-код. Он называется SC, например, когда вызовы функций синтаксически вложены слишком глубоко или другие конструкции, которые должны быть логически сгруппированы и разбиты на несколько строк. – Ctx

+0

@Ctx - Спасибо за разъяснение. Итак, с точки зрения вещей, все в порядке, правильно? У меня есть еще одна статья о том, как сделать ее более надежной, но это другой вопрос. –

+1

Выглядит хорошо, да – Ctx

ответ

2

В этом случае, если вы хотите использовать подпрограммы, вы должны сделать это:

@ECHO OFF 
CLS 


:MENU 
echo Welcome %USERNAME% 

echo 1 - Start KeePass 
echo 2 - Backup 
echo 3 - FireFox 
echo 4 - Exit 

SET /P M=Please Enter Selection, then Press Enter: 

IF %M%==1 CALL :StartKeePass 
IF %M%==2 CALL :Backup 
IF %M%==3 CALL :FireFox 
IF %M%==4 GOTO :EOF 
GOTO MENU 


:StartKeePass 
SET "keePass=%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe" 
SET "kdb=%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx" 

echo I'll start KeePass for You 
START "" %keePass% %kdb% 

GOTO :EOF 

:Backup 
SET "backup=%USERPROFILE%\backup.bat" 
call %backup% 

GOTO :EOF 

:FireFox 
cd "C:\Program Files (x86)\Mozilla Firefox\" 
start firefox.exe 

GOTO :EOF 

Обратите внимание, что я изменил несколько вещей. Вместо goo ... goto меню, вы должны использовать call :labelgoto :eof/exit /b. Кроме того, у вас была орфографическая ошибка Star t KeePass, а вместо set variable="value" лучше использовать set "variable=value". Это также будет принимать пробелы в стоимости, но это не добавит кавычки в переменную

В следующий раз, вы, вероятно, должны опубликовать это code review, потому что эти вещи не являются на самом деле ошибки

+0

быстрый вопрос, почему лучше сказать goto: eof than goto: menu? –

+0

, чтобы объяснить это, вызов временно дает создает новый пакетный файл внутри этого, начиная с данной метки. Когда этот пакетный файл завершен, он возвращается к вызывающему, в строке под вызывающей линией. –

+0

goto: eof на самом деле не лучше, но это выбор для работы с подпрограммами или просто для перестановки позиций в пакетном файле. Я предлагаю посмотреть [здесь] (http://ss64.com/nt/call.html) для лучшего объяснения –

0

Если вы хотите удалить goto s, вы можете просто вызвать сценарий еще раз, чтобы продолжать использовать его. Кроме того, посмотрите на команду choice, если вы используете версию Windows позже XP, так как она устранит необходимость проверки, введен ли пользователь неправильный ввод.

@echo off 

cls 
echo Welcome %USERNAME% 

echo 1 - Start KeePass 
echo 2 - Backup 
echo 3 - FireFox 
echo 4 - Exit 

choice /C:1234 /M "Please enter your selection: " /N 

:: The first option listed by choice's /C option will return an errorlevel value of 1, the second 2, and so on 
if %errorlevel% equ 1 (
    SET keePass="%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe" 
    SET kdb="%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx" 

    echo I'll start KeePass for You 
    START "" %keePass% %kdb% 
) 

:: I've converted these to one-liners simply for personal preference. 
:: You can keep these the way you had them if you put them inside of parentheses like with option 1. 
if %errorlevel% equ 2 call "%USERPROFILE%\backup.bat" 
if %errorlevel% equ 3 start "" "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" 
if %errorlevel% equ 4 exit /b 

:: Calls this script again, simulating a goto :MENU 
:: Personally, I'd stick with a label and a goto in this instance, 
:: but this is how you could do it if you don't want to use goto at all 
call %0 

Если каждый выбор пользователь может сделать это довольно просто (то есть он может быть упрощен до одного или двух команд), вы можете закодировать таким образом; в противном случае, определенно используйте подпрограммы, как предложил Деннис.

0

Мое предложение об организации этого, добавлено сбрасывание в m переменной, позволило случайный ввод, который необходимо обработать, и сделал все это в одном блоке кода.

Ничего плохого в ответе «Деннис ван Гилс», подумал, что я покажу вам другой подход.

@echo off 
setlocal enableDelayedExpansion 

:menu 
set "m=" 
cls 
echo/Welcome !username! 
echo/ 
echo/1 - Start keepass 
echo/2 - Backup 
echo/3 - Firefox 
echo/4 - Exit 
echo/ 
set /p "m=Please enter selection, then press enter:" 
if not defined m (
    cls 
    echo/Error: Empty input. 
    pause 
) else (
    if "!m!" equ "1" (
     set "keepass=!userprofile!\keepass\keepass-2.30\keepass.exe" 
     set "kdb=!userprofile!\keepass\passworddatabase\passworddatabase.kdbx" 
     echo/I'll start keepass for you 
     start "" !keepass! !kdb! 
    ) else (
     if "!m!" equ "2" (
      set "backup=!userprofile!\backup.bat" 
      call !backup! 
     ) else (
      if "!m!" equ "3" (
       cd "c:\program files (x86)\mozilla firefox\" 
       start firefox.exe 
      ) else (
       if "!m!" equ "4" (
        goto :eof 
       ) else (
        cls 
        echo/Error: ["!m!"] not recognized. 
        pause 
       ) 
      ) 
     ) 
    ) 
) 
goto :menu 

Примечание: echo/ используются как привычка, так как echo: и echo\ я спутать части файла путь/URL и echo. так кропотливо отметил его длительное время команды.

Кроме того, я предпочитаю использовать ! по телефону % вместе с setlocal enableDelayedExpansion по чистому предпочтению и простоту блочного кодирования.

Смежные вопросы