Проблема, из-за которой сценарий выходит из системы, является синтаксической ошибкой в последнем операторе if вашего else
. Если вы запустите сценарий из командной строки (не дважды щелкнув по нему), вы получите сообщение об ошибке:
= "y" в это время было неожиданным.
Действительно ваш последний если-заявление:
if "%yesnol%"="y" (
но CMD анализатор ожидает двойной знак "=" (==
) для сравнения, так что вы должны иметь:
if "%yesnol%"=="y" (
Причина, по которой он увидит его, даже если он не примет ветку else, связан с тем, что if-блок (фактически, весь блок кодов, разделенных (...)
) анализируется так, как если бы это была одна команда, написанная на одной строке (с каждой «SUBCOM mand "в вашем блоке, разделенном &&
). Поскольку анализатор будет обрабатывать всю эту «линию» за один раз, он обнаружит любую синтаксическую ошибку, присутствующую во всем блоке.
Кроме ошибки синтаксиса в вашем скрипте есть некоторые небольшие ошибки. Первый заключается в том, что на самом деле нехорошо объявлять метки внутри блока кода. Вы объявили метку :yes
внутри if-блока в ветке else
. A goto
внутри if-блока «уничтожит» if
-контекст. Вы, возможно, не заметите в своем коде, но рассмотрите следующий пример:
@echo off
set var=Let's brake the if statement
IF DEFINED var (
echo The variable var exists
IF "%var%"=="Let's brake the if statement" goto :expected
echo The variable var is not what I would expect though.
echo You have to change it to something else...
goto :outside
:expected
echo I'm happy with its value. It is at least something I would expect
echo This is the end of the if-branch
) ELSE (
echo Strange ... the variable var is not defined.
echo Indeed: var="%var%"
)
:outside
rem just to get outside
Вы могли бы ожидать выход как
The variable var exists
I'm happy with its value. It is at least something I would expect
This is the end of the if-branch
, но выход будет
The variable var exists
I'm happy with its value. It is at least something I would expect
This is the end of the if-branch
Strange ... the variable var is not defined.
Indeed: var="Let's brake the if statement"
goto
уничтожен if-context. Как было сказано ранее, синтаксический анализатор cmd будет анализировать весь if-блок как одну команду.См. Так: вы просите парсер отказаться от команды, которую он обрабатывал (весь блок if
с условием, который он только что проверил) и перейдите в другое место. Это где-то еще после условия if
, поэтому он даже не оценит это снова. Поэтому, когда вы находитесь внутри блока (espacially if-blocks и for-loops), не используйте goto
, чтобы игнорировать часть кода внутри этого блока, использовать if-statements и поместить код в игнор внутри if-блока. A goto
для перехода за пределы кода кода не является проблемой, но с момента, когда метка находится внутри блока if, это может привести к неожиданным результатам.
Вторая ошибка касается переменных YesNoIn
и yesnol
. Как я уже сказал, весь блок if анализируется за одну единственную команду. Невозможно дать переменной новое значение и прочитать это новое значение в той же команде с простым расширением переменной %YesNoIn%
или %yesnol%
. Решение этой проблемы - delayed expansion (ссылка также имеет пример). Когда я писал этот ответ, я увидел, что @Josefz уже разместил answer с задержкой расширения, поэтому я не буду повторять его здесь. Но я бы рекомендовал, чтобы вы взглянули на команду choice
. Используя команду choice
, вам не потребуется замедленное расширение. Он просто устанавливает уровень ошибок и существует способ проверить уровень ошибок, не беспокоясь о задержке расширения: IF ERRORLEVEL n
проверит , если уровень ошибок больше или равен n. Кроме того, choice
автоматически проверяет, введен ли пользователь правильное значение!
Ваш скрипт с choice
вместо set /p
будет выглядеть следующим образом:
echo What drive would you like to launch MCEdit on?
set /p DRIVE="Drive: "
if exist "%DRIVE%:\MC\DATA\mcedit\mcedit.exe" (
set APPDATA=%DRIVE%:\MC\DATA
start %DRIVE%:\MC\DATA\mcedit\mcedit.exe
) else (
echo You do not have MCEdit installed on this drive, would you like to install it?
choice /c YN
REM Y ==> errorlevel = 1 ; N ==> errorlevel = 2
if ERRORLEVEL 2 goto:menu
echo Choose the "mcedit.exe" file from a current installation on your pc.
pause
call "%DRIVE%\MC\DATA\FileViewer.bat"
xcopy "%OutCD%" "%DRIVE%:\MC\DATA\mcedit" /E
echo Done!
choice /c YN /m "Would you like to launch MCEdit now? "
if NOT ERRORLEVEL 2 (
set APPDATA=%DRIVE%:\MC\DATA
start %DRIVE%:\MC\DATA\mcedit\mcedit.exe
)
)
PS: Нет Введите ключевые нужно нажать, когда choice
используется.
EDIT: Третья ошибка заключается в выборе переменной APPDATA
, уже используется в вашей ОС Windows в контексте пользователя, как вы можете видеть here.
Вы пытались выполнить любую отладку самостоятельно? Бросьте несколько дополнительных выражений эха, которые помогут вам отследить, что именно (и не реально) выполняет. –
хорошо, но я уже пробовал некоторые из таких вещей – HungryBoy02
У меня был эхо, и все еще ничего: | – HungryBoy02