I am using Pycharm. When I click the "stop" button, the subprocess.Popen deletes the left over .bat files. But after putting the subprocess.Popen inside a threading.Thread function, the .bat files are no longer deleted.
Here is some example code:
def threads_(title, index):
#Create and process .Bat
with open('test'+str(index)+'.bat', "w", encoding='utf-8') as a: a.write('executable_program.py -start_test "'+title+'"')
p1 = subprocess.Popen('test'+str(index)+'.bat', stdout=subprocess.PIPE, text=True)
try:
while p1.poll() is None:
time.sleep(0.5)
_output = p1.stdout.readline()
except KeyboardInterrupt as e:
#Cleanup on Exit
print('Closing ...')
for c in psutil.Process(p1.pid).children(recursive=True): c.kill()
psutil.Process(p1.pid).kill()
print('Cleanup Done')
os.remove('test'+str(index)+'.bat')
quit()
def start_threads():
remaining = ['thread_test1', 'thread_test2', 'thread_test3']
Globals.thread1 = [Globals.thread1.append(None) for index in range(0, 3)]
for index in range(0, 3):
Globals.thread1[index] = threading.Thread(name='thread' + str(index), target=threads_, args=(remaining[index], index))
Globals.thread1[index].start()
start_threads()
How can I make the threading.Thread function delete files when I push PyCharm's "stop" button?
I also cannot use the join() function when starting the threads.
The following code works with a tkinter root.mainloop(), but it only works like 40% of the time. It doesn't always trigger the handler_stop_signals on exit.
def handler_stop_signals(signum, frame):
print("Hello world")
def main_thread():
Globals.root = tk.Tk()
Globals.root.geometry("+{}+{}".format(650, 50))
Globals.root.geometry("{}x{}".format(200, 200))
Globals.root.mainloop()
signal.signal(signal.SIGINT, handler_stop_signals)
signal.signal(signal.SIGTERM, handler_stop_signals)
main_thread()
I have put together a global solution that appears to work for all cases (without any occasional fails) ... threading.Threads , subprocess.Popen, including in combination with tkinters root.mainloop() which occasionally overrides any on-exit termination catch.
main.py
#main.py
import os
import threading
import tkinter as tk
def listen_Exit():
os.system("at_exit.py")
def main_thread():
root = tk.Tk()
root.title("Main_GUI")
root.geometry("+{}+{}".format(650, 50))
root.geometry("{}x{}".format(200, 200))
threading.Thread(name='process1', target=listen_Exit).start()
try: root.mainloop()
except: print('manually terminated')
main_thread()
at_exit.py
#at_exit.py
import win32gui
import time
import os
def termination_code():
print('terminated')
if os.path.isfile('D:\\GOOD\\Coding\\.Coding_Projects\\test\\thread_0.bat'):
os.remove('D:\\GOOD\\Coding\\.Coding_Projects\\test\\thread_0.bat')
while True:
try:
hwnd = win32gui.FindWindow(None, "Main_GUI")
print('connected')
break
except: time.sleep(1)
try:
print('maintaining connection')
while True:
if win32gui.IsWindow(hwnd): pass
else: print("Connection terminated"); break
time.sleep(1)
termination_code()
except:
termination_code()
This appears to have the capability of running at_exit.py in the background, until the main program (in any way) is terminated ... and then at_exit.py will clean up any leftover files.