Safely killing a python script on Windows

混江龙づ霸主 提交于 2021-02-08 08:01:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!