2009-06-01 11 views
6

Ho un file di finestre batch, con un paio di sub-routine in esso qualcosa di simile:Come terminare un file batch di Windows da una routine chiamata?

call :a 
goto :eof 

:a 
call :b 
goto :eof 

:b 
:: How do I directly exit here from here? 
goto :eof 

Io corro questo in una finestra cmd su Vista.
Se rilevo un errore da qualche parte nel file batch, voglio che esca con un errore di errore diverso da zero. C'è qualcosa che posso scrivere nella routine: b che farà terminare il file batch in questo modo.

  • Ho provato "exit", che chiude l'intera finestra cmd. Non è quello che voglio.
  • Ho provato "exit/B 1". Questo ritorna alla routine precedente. Per utilizzare questo schema dopo ogni 'chiamata' dovrei scrivere attentamente 'se errorlevel 1 exit/B 1' dopo ogni singola 'call' per passare l'errore di backup dello stack di chiamate. Preferirei non dover scrivere questa riga dopo ogni chiamata.

Questo articolo è stato interessante, ma non delle alternative si comportano nel modo che voglio. http://www.computerhope.com/exithlp.htm

C'è un altro modo?

Grazie.

risposta

14

È possibile chiamare i tuoi subroutine questo modo:

call :b||exit /b 1 

che equivale a

call :b 
if errorlevel 1 exit /b 1 

E 'un po' più corta e consente di risparmiare una linea, ma non è ancora ideale, sono d'accordo.

Diverso da quello che non vedo un modo.

MODIFICA: Ok, ho un modo, ma è Pure Evil ™.

uso scorretto la dimensione dello stack massima, e quindi limitare la ricorsione, creiamo un'altra subroutine che esaurisce semplicemente lo stack chiamando ricorsivamente sé:

@echo off 
echo Calling a 
call :a 
echo Called a 
goto :eof 
:a 
echo Calling b 
call :b 
echo Called b 
goto :eof 
:b 
echo Trying to exit 
call :exit 
goto :eof 
:exit 
call :exit 

Questo, tuttavia, si tradurrà nel messaggio di errore brutto

 
****** B A T C H R E C U R S I O N exceeds STACK limits ****** 
Recursion Count=704, Stack Usage=90 percent 
******  B A T C H PROCESSING IS A B O R T E D  ****** 

Inoltre, ci vorranno circa 2 secondi sulla mia macchina.

È possibile sopprimere il messaggio di errore, modificando la dichiarazione call come segue:

call :exit >nul 2>&1 

che reindirizzare tutto ciò che vuole output in un grande vuoto.

Ma considerando il tempo necessario per riempire lo stack, penso che la prima variante sarebbe più semplice.

Stavo anche pensando di utilizzare un secondo file batch, che, quando eseguito senza call, avrebbe essenzialmente interrotto il primo. Ma in qualche modo non funziona bene con le subroutine. Apparentemente, lo srotolamento dello stack delle chiamate avviene ancora.

+4

Cool, grazie. Questo è il migliore finora. Da questo ho trovato se uso "call: a || goto: eof", quindi il errorlevel verrà propagato di nuovo. Utile se lo specifico errorlevel ha un significato utilizzabile. –

+0

Sì, sembra davvero meglio. Non ci ho pensato. Inoltre, l'aborto ricorsivo che ho delineato non è un'opzione reale, suppongo :) – Joey

+0

Sì, l'interruzione ricorsiva era nuova, ma solo un po 'troppo lontana! :) –

0

È possibile creare un file exit.bat che uccida il file bat in alto in base al nome del titolo.

Esempio:

a.bat

@echo off 
title A.bat 
echo A.bat 
call B.bat 
echo A.bat 

B.bat

@echo off 
echo B.bat 
exit.bat A.bat 
echo B.bat 

Exit.bat

@echo off 
echo exit.bat 
kill %1 
+1

mentre decisamente cool e decisamente malvagio, questo approccio eliminerà il processo completo di cmd. Qual è esattamente ciò che l'uscita farebbe e che l'OP non considera accettabile. Inoltre, kill dovrebbe essere sostituito da taskkill/fi "windowtitle -eq% 1" poiché non esiste alcun comando kill su Windows. – Joey

+0

Ah Ho dimenticato di aver installato "Debugging Tools per Windows" (WinDbg) e include una copia di kill.exe. Grazie per il comando taskkill non mi ero reso conto che era lì. –

+0

Per rendere meno doloroso l 'abbattimento dell'intera finestra, puoi sempre usare il comando start cmd a.bat per sparare la parte che vuoi uccidere. –

Problemi correlati