2017-01-12 2 views
1

Ich habe ein kleines Programm und wenn ich "wenn es existiert" es schließt, kann mir jemand sagen warum? Ich habe nach Syntaxfehlern gesucht und keine (glaube ich), ich werde meinen Code hier einfügen und sehen, was Sie tun können.Mein Stapelverarbeitungsfenster wird geschlossen, wenn es existiert

Direkt nachdem Sie das Laufwerk eingeben, schließt es, irgendwelche Hilfe?

+0

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). –

+0

in Ordnung, aber ich habe einiges von dieser Art der Sache schon ausprobiert – HungryBoy02

+0

ich heven hatte Echo auf, und immer noch nichts: | – HungryBoy02

Antwort

2

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.

0
  1. Ich bin mir nicht sicher, ob die Änderung APPDATA variable eine gute Idee ist.
  2. Fehlende :menu Label in Ihrem Code.
  3. Wichtig: lesen und anwenden http://ss64.com/nt/delayedexpansion.html.
  4. Never use :label nor :: label-like comment inside a command block enclosed in () parentheses

SETLOCAL EnableExtensions EnableDelayedExpansion 
     ::: 
:menu 
     ::: 
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? 
    set /p YesNoIn="[y/n]: " 
    if /I "!YesNoIn!"=="y" (
     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^! 
     set /p yesnol="Would you like to launch MCEdit now? [y/n]: " 
     if /I "!yesnol!"="y" (
      set APPDATA=%DRIVE%:\MC\DATA 
      start %DRIVE%:\MC\DATA\mcedit\mcedit.exe 
     ) 
    ) else goto:menu 
) 
1

Sie haben einfache Tippfehler im Vergleichsoperator in der zweiten if. if "%yesnol%"=="y"

Verwandte Themen