Das Problem, das bewirkt, dass das Skript vorzeitig beendet wird, ist ein Syntaxfehler in der letzten if-Anweisung Ihres Zweigs else
. Wenn Sie das Skript über die Befehlszeile ausführen (nicht durch einen Doppelklick darauf), erhalten Sie die folgende Fehlermeldung:
= "y" war zu dieser Zeit unerwartet.
die Tat der letzte if-Anweisung lautet:
if "%yesnol%"="y" (
aber der cmd-Parser erwartet ein doppeltes Zeichen "=" (==
) für Vergleiche, so dass Sie sollten:
if "%yesnol%"=="y" (
Der Grund, warum es es sehen wird, selbst wenn es den Else-Zweig nicht nimmt, ist, weil ein If-Block (eigentlich alle Blöcke von (...)
) geparst wird, als wäre es ein einzelner Befehl in einer Zeile geschrieben (mit jedem "Unterkom Mand "in Ihrem Block getrennt mit &&
). Da der Parser die gesamte "Zeile" auf einmal bearbeitet, erkennt er den Syntaxfehler, der im gesamten Block vorhanden ist.
Neben diesem Syntaxfehler gibt es ein paar kleine Fehler, die Sie in Ihrem Skript gemacht haben. Der erste ist, dass es eigentlich nicht gut ist, Labels innerhalb eines Codeblocks zu deklarieren. Sie haben das Label :yes
im if-Block im Zweig else
deklariert. Ein goto
innerhalb eines if-Blocks "zerstört" den if
-Kontext. Sie werden vielleicht nicht in Ihrem Code bemerken, aber dieses Beispiel betrachten:
@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
Sie eine Ausgabe wie
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
erwarten würde, aber der Ausgang
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"
Die goto
zerstört wird der if-Kontext. Wie bereits erwähnt, analysiert der CMD-Parser den gesamten if-Block als einen Befehl.Sehen Sie es so: Sie bitten den Parser, den Befehl, den er gerade bearbeitet hat (den ganzen Block if
mit der gerade geprüften Bedingung), zu verlassen und zu einem anderen Ort zu springen. Das woanders ist nach dem if
Zustand, so wird es das noch nicht einmal auswerten. Wenn Sie also innerhalb eines Blocks sind (insbesondere if-blocks und for-loops), verwenden Sie goto
nicht, um einen Teil des Codes in diesem Block zu ignorieren. Verwenden Sie if-Anweisungen, und setzen Sie den Code in den if-Block, um ihn zu ignorieren. Ein goto
Sprung nach außerhalb eines Codeblocks ist kein Problem, aber von dem Moment an, an dem sich das Etikett beispielsweise in einem if-Block befindet, kann es zu unerwarteten Ergebnissen kommen. Der zweite Fehler betrifft die Variablen YesNoIn
und yesnol
. Wie gesagt, der ganze if-Block wird in einem Durchgang als ein einziger Befehl geparst. Es ist nicht möglich, einer Variablen einen neuen Wert zu geben und diesen neuen Wert im selben Befehl mit der einfachen Variablenerweiterung %YesNoIn%
oder %yesnol%
zu lesen. Eine Lösung für dieses Problem ist delayed expansion (der Link hat auch ein Beispiel). Während ich diese Antwort schrieb, sah ich @Josefz bereits eine answer mit verzögerter Erweiterung gepostet, also werde ich es hier nicht wiederholen. Aber was ich empfehlen würde ist, dass Sie einen Blick auf den choice
Befehl werfen. Mit dem Befehl choice
benötigen Sie keine verzögerte Erweiterung. Er setzt nur den errorlevel und es gibt eine Möglichkeit, den errorlevel zu überprüfen, ohne sich um eine verzögerte Erweiterung kümmern zu müssen: IF ERRORLEVEL n
prüft , wenn der errorlevel größer oder gleich n ist. Darüber hinaus überprüft choice
automatisch, ob der Benutzer einen korrekten Wert eingegeben hat!
Ihr Skript mit choice
statt set /p
wird wie folgt aussehen:
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: Kein Schlüssel muss Enter gedrückt werden, wenn choice
verwendet wird.
EDIT: Ein dritte Fehler ist die Wahl der Variablen APPDATA
, wird bereits von Ihrem Windows-Betriebssystem in einem Benutzerkontext verwendet, wie Sie here sehen können.
Haben Sie versucht, selbst zu debuggen? Werfen Sie einige zusätzliche Echo-Anweisungen ein, die Ihnen helfen, genau herauszufinden, was tatsächlich ausgeführt wird (und was nicht). –
in Ordnung, aber ich habe einiges von dieser Art der Sache schon ausprobiert – HungryBoy02
ich heven hatte Echo auf, und immer noch nichts: | – HungryBoy02