Pregunta

Tengo un script .bat que inicia un programa java . El programa java elimina la carpeta donde se encuentra .bat . No tengo forma de tocar el programa java . Solo puedo modificar el archivo .bat .

El problema es que el archivo .bat , una vez eliminado, detiene su ejecución de inmediato sin finalizar. Pero hay algunas tareas de limpieza que deben realizarse después de que el programa java salga.

Traté de copiar el archivo .bat en otro lugar y ejecutarlo en una ubicación donde no se eliminaría. Por desgracia, una vez que se elimina el .bat original, porque todavía está en ejecución, ocurre el mismo bloqueo y no termina.

Aquí hay dos archivos de muestra (para el propósito del ejemplo, supongamos que se encuentran en D: \ tmp ):

delete.bat

echo "delete start"

pause

del launch.bat

pause

echo "delete end"

launch.bat

echo "launch start"

setlocal enabledelayedexpansion enableextensions 

if "%CD%"=="C:\tmp" (

    echo "in temp"
    d:
    cd \tmp
    delete.bat

)

if "%CD%" NEQ "C:\tmp" (

    echo "not in temp"
    mkdir C:\tmp
    copy launch.bat C:\tmp\launch.bat
    echo "launch copied"
    C:
    cd \tmp
    cmd /c launch.bat

)

echo "launch end"

El lanzamiento de launch.bat funcionaría si la ejecución del launch.bat copiado se separara del inicial.

¿Alguien sabe una manera de hacer que un .bat termine su ejecución incluso si se elimina mientras se ejecuta?

¿Fue útil?

Solución 4

Parece que tengo un mejor resultado al hacerlo así (llamando a launch.bat con cmd / k ):

launch.bat

echo "launch start"

setlocal enabledelayedexpansion enableextensions 

if "%CD%"=="C:\tmp" (

        echo "in temp"
        d:
        cd \tmp
        delete.bat
        echo "after delete"
)

if "%CD%" NEQ "C:\tmp" (

        echo "not in temp"
        mkdir C:\tmp
        copy launch.bat C:\tmp\launch.bat
        echo "launch copied"
        C:
        cd \tmp
        cmd /k launch.bat

)

echo "launch end"

Ahora puedo alcanzar el echo " después de eliminar " , pero termino de alguna manera en un bucle infinito. Al menos mi limpieza se puede ejecutar en este punto. Sin embargo, no sé por qué no puedo llegar a echo " end end " .

Otros consejos

Esto ordenará que el script se elimine a sí mismo y luego salga. El intérprete de comandos lee toda la línea antes de que se ejecute la línea, por lo que el comando de salida se ejecutará después del comando de eliminación aunque el archivo ya no exista.

del /f/q "%~0" | exit

Alternativamente, puede usar paréntesis si desea ejecutar muchos comandos después de que el archivo se haya eliminado ya que el intérprete de comandos leerá todo lo que está dentro de los paréntesis antes de ejecutarlo.

(del /f/q "%~0"
if exist "%~0" (echo.How did that happen?) else (echo.I've deleted myself.)
pause
exit)   
  

¿Alguien sabe una manera de hacer que un .bat termine su ejecución incluso si se elimina mientras se ejecuta?

No creo que sea posible. Ejecución por lotes leída directamente del archivo. Si modifica el archivo, cambiará la ejecución (¡los programas por lotes auto modificables son maravillosamente difíciles de depurar!)

¿Por qué no comienzas tu archivo por lotes desde una ubicación diferente?

Incluso si no puede hacer eso, lo que puede hacer es tener un archivo que consta de una sola línea, llamando a otro archivo por lotes que no se elimina. Este archivo hace todo: inicia el programa Java, realiza toda la limpieza e incluso incluye la restauración del archivo por lotes original para que pueda ejecutarlo varias veces.

En lugar de ejecutar launch.bat a través de un cmd / c launch.bat , que intentará transferir el control al archivo por lotes de llamada cuando esté listo, ejecútelo simplemente haciendo: launch.bat Esto transferirá el control (piénselo como un goto en lugar de una llamada) al archivo por lotes, por lo que no intentará devolver el control a un archivo que ya no existe.

Es posible ejecutar líneas desde un archivo eliminado, pero las líneas deben residir en un bloque de paréntesis, ya que los bloques siempre se almacenan en caché completamente en la memoria antes de ejecutarse.

Obviamente no puede llamar a funciones en el lote, pero es posible llamar a otros archivos por lotes y recuperar el control (en el bloque).

@echo off
(
  echo Delete myself
  del %~f0
  call ..\second.bat 
  echo do some other stuff after second.bat
)
echo This line can't be reached anymore
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top