问题
I have created a python script to regularly scrape a website and store the results in a .json file while at work. This script is set to run without the command line on an infinite loop, so I can have it start in the morning and then just run unimpeded throughout the day.
My issue is that at night I'm going to want to kill it so that I can go home, but I don't want to cause any issues with killing it mid-connection or mid-write. I was wondering what was the correct way to handle creating, and subsequently destroying, such a script on Windows 10 to handle exit behaviours.
回答1:
Here's an example that uses a hidden window to listen for a WM_CLOSE
message sent by taskkill.exe.
demo.py
import win32con
import win32gui
def shutdown_monitor():
def wndproc(hwnd, msg, wparam, lparam):
if msg == win32con.WM_CLOSE:
win32gui.DestroyWindow(hwnd)
return 0
elif msg == win32con.WM_DESTROY:
win32gui.PostQuitMessage(0)
return 0
return win32gui.DefWindowProc(hwnd, msg, wparam, lparam)
wc = win32gui.WNDCLASS()
wc.lpszClassName = 'SpamMessages'
wc.lpfnWndProc = wndproc
win32gui.RegisterClass(wc)
hwnd = win32gui.CreateWindow('SpamMessages', 'Python Spam App',
0, 0, 0, 0, 0, 0, 0, 0, None)
win32gui.PumpMessages()
if __name__ == '__main__':
import sys
import time
import atexit
import threading
atexit.register(print, 'PYTHON SPAM APP: SHUTDOWN')
shutdown_thread = threading.Thread(target=shutdown_monitor)
shutdown_thread.start()
shutdown_thread.join()
time.sleep(1)
sys.exit(0x2A)
demo.bat
@echo off
setlocal
set killquit=taskkill /fi "windowtitle eq Python Spam App"
set killkill=taskkill /f /fi "windowtitle eq Python Spam App"
echo Quit Test
start /b cmd /c "(timeout 3 >nul) & %killquit%" & demo.py
echo ExitCode=%=ExitCode%
echo.
echo Kill Test
start /b cmd /c "(timeout 3 >nul) & %killkill%" & demo.py
echo ExitCode=%=ExitCode%
output
Quit Test
SUCCESS: Sent termination signal to the process with PID 5612.
PYTHON SPAM APP: SHUTDOWN
ExitCode=0000002A
Kill Test
SUCCESS: The process with PID 5432 has been terminated.
ExitCode=00000001
The Windows 8/10 Task Manager doesn't consider this hidden window as belonging to an interactive application and doesn't list the process in its "Apps" list, so unlike taskkill.exe it forcefully terminates the process instead of posting WM_CLOSE
. There may be some other way to force Task Manager to classify the process as an 'app'.
来源:https://stackoverflow.com/questions/43604939/safely-killing-a-python-script-on-windows