Lucas Tesch
Lucas Tesch

Reputation: 157

Automatically restart a python if it closes or crashes

I have 3 python files, 1.py, 2.py, 3.py and I'm trying to make a bat batch file that restarts my python files in case they break or close for some reason. I'm trying with the following code, but it is not working very well:

@echo off
:Restart
start "1" /wait "C:\Users\PC\Desktop\test\1.py"
start "2" /wait "C:\Users\PC\Desktop\test\2.py"
start "3" /wait "C:\Users\PC\Desktop\test\3.py"
goto Restart

my goal is, with just a bat file, to automatically restart any of my 3 files in case any of them close or crash. if only one of them has closed, restart only it, or if two of them close, restart both, so on

Upvotes: 1

Views: 4936

Answers (1)

double-beep
double-beep

Reputation: 5504

I am just copying-pasting my answer from your another dublicate question (Batch that monitors and restarts a python):

A combination of an "infinite loop" which is needed in your case and python files will overload your CPU a lot I think. Have a revised piece of code (working only in single file extensions (*.bat, *.txt)). See below for something more general.

@echo off
setlocal EnableExtensions

:start_python_files
start "1st" "test1.py"
start "2nd" "test2.py"
start "3rd" "test3.py"

:check_python_files
call:infinite 1st test1.py
call:infinite 2nd test2.py
call:infinite 3rd test3.py
goto:check_python_files

:infinite
tasklist /FI "WINDOWTITLE eq %1 - %2" | findstr /c:PID > nul
rem findstr /c:PID command added above to confirm that tasklist has found the process (errorlevel = 0). If not (errorlevel = 1).
if %errorlevel% EQU 1 (start "%1" "%2")

Well, this way may last some time, so if a file is closed (~2-3 secs depending on your CPU overload).

Please notify me if it is not working for you. I haven't python installed and I don't know how they are named when they are opened :).

So, now as you have (kindly???) requested complete answers let me explain my code:

  • I enable extensions (setlocal EnableExtensions) to change call command as follows:

CALL command now accepts labels as the target of the CALL. The syntax is:

CALL :label arguments

From call /? command. You should type it in a fresh cmd for more information

  • I specify the window title with the start command, so my code will work. Type start /? in a fresh cmd window.

  • I call the infinite subroutine sending to it arguments (window title and filename). These can be accessed with %1 (first argument) and %2 (second argument).

  • In the infinite subroutine, I search for window title (WINDOWTITLE) EQUAL (eq) to format window title - filename. Even if it doesn't exist tasklist will return errorlevel value 0 with the message:

INFO: No tasks are running which match the specified criteria.

As here PID string doesn't exist (if it is found it will exist), we put findstr to search for it. If found, errorlevel will be 0. Else, it would be 1.

  • If the errorlevel is 1, that means that process not found, which means that the file is closed. So, we reopen it with the arguments sent (start "window title (%1)" "filename (%2)").

  • As we have called the infinite subroutine, after its end, we will return to check_python_files subroutine doing all of these above infinitely, until user termination or computer shutdown.

As later discussed in chat, when we run python files standardly (with start "window title") window title will be the full path to python.exe file. I found a way to fix it: start the cmd /c command. A revised piece of code:

@echo off
setlocal EnableExtensions

:start_python_files
start "1st" "cmd /c test1.py"
start "2nd" "cmd /c test2.py"
start "3rd" "cmd /c test3.py"

:check_python_files
call:infinite 1st test1.py
call:infinite 2nd test2.py
call:infinite 3rd test3.py
goto:check_python_files

:infinite
tasklist /FI "WINDOWTITLE eq %1" | findstr /c:PID > nul
rem findstr /c:PID command added above to confirm that tasklist has found the process (errorlevel = 0). If not (errorlevel = 1).
if %errorlevel% EQU 1 (start "%1" "cmd /c %2")

I have just added only a cmd /c extra (and remove %2) from window title as it was not needed.

cmd /c tells system to run a new cmd which will carry out the command specified by string and then it will terminate.

Synopsis:

  1. Commands should be run to get more information about how they work:

    • call /?
    • start /?
    • goto /?
    • tasklist /?
    • findstr /?
    • cmd /?

I suggest to run the above in a fresh new cmd window.

  1. Some interesting references:

I am really sorry for putting you into this mess. In anyway, thank you for providing such good information for me to understand where I was wrong.

Upvotes: 2

Related Questions