在Windows上安全地杀死python脚本

时间:2017-04-25 08:04:40

标签: python windows daemon

我创建了一个python脚本来定期抓取网站并在工作时将结果存储在.json文件中。这个脚本被设置为在无限循环中没有命令行的情况下运行,所以我可以让它在早上开始,然后在一整天都不受阻碍地运行。

我的问题是,晚上我会想要杀死它以便我可以回家,但我不想在连接中间或中间写入时导致任何问题。我想知道在Windows 10上处理创建并随后销毁这样一个脚本来处理退出行为的正确方法是什么。

1 个答案:

答案 0 :(得分:0)

这是一个使用隐藏窗口监听taskkill.exe发送的WM_CLOSE消息的示例。

<强> 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%

<强>输出

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

Windows 8/10任务管理器不会将此隐藏窗口视为属于交互式应用程序,并且不会在其“应用程序”列表中列出该进程,因此与taskkill.exe不同,它强制终止进程而不是发布WM_CLOSE。可能还有其他方法可以强制任务管理器将流程归类为“应用”。