如何检测Windows上python中退出的程序并在退出时执行某些操作 [英] how to detect program exited in python on windows and do something on exit

查看:538
本文介绍了如何检测Windows上python中退出的程序并在退出时执行某些操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Windows上终止python脚本时我想做点什么。

I want to do something when terminate the python script on windows.

# coding:utf-8
import ctypes
import os

def set_exit_handler():
    def on_exit(event):
        print '=====exit====='

    _BOOL = ctypes.c_long
    _DWORD = ctypes.c_ulong
    _kernel32 = ctypes.windll.kernel32
    _SIGNAL_HANDLER = ctypes.WINFUNCTYPE(_BOOL, _DWORD)
    _kernel32.SetConsoleCtrlHandler.argtypes = [_SIGNAL_HANDLER, _BOOL]
    _kernel32.SetConsoleCtrlHandler.restype = _BOOL

    h = _SIGNAL_HANDLER(on_exit)
    if not _kernel32.SetConsoleCtrlHandler(h, True):
        raise ctypes.WinError()

    print 'register success'

if __name__ == '__main__':
    set_exit_handler()
    while(1):
        pass

请检查我的示例代码。有问题。当我按CTRL + C或关闭cmd window.on_exit()将不会执行。并且Windows弹出窗口 python.exe已停止工作,Windows正在检查问题的解决方案

Please check my sample code. It has a problem. when I press CTRL+C or Close the cmd window.on_exit() will not be executed.and windows popup "python.exe has stopped working, windows is checking the solution to the problem "

请在 http://msdn.microsoft.com/en-us/library/windows/desktop/ms685049%28v=vs.85%29.aspx

在此先感谢您,英语不好。

Thanks in advance and sorry for poor english.

推荐答案

@ mata建议,则应使用 atexit模块以注册正常退出脚本时要调用的函数,即不是通过未处理的Windows异常, ExitProcess TerminateProcess

As @mata suggests, you should use the atexit module to register a function to be called when the script exits normally, i.e. not via an unhandled Windows exception, ExitProcess, or TerminateProcess.

如果出于其他原因需要使用 SetConsoleCtrlHandler ,请保留对回调的引用以防止被回调垃圾收集。否则,该过程将崩溃(充其量)。

If you need to use SetConsoleCtrlHandler for some other reason, keep a reference to the callback to prevent it from being garbage collected. Otherwise the process will crash (at best).

import ctypes
from ctypes import wintypes

_kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

def _check_bool(result, func, args):
    if not result:
        raise ctypes.WinError(ctypes.get_last_error())
    # else build final result from result, args, outmask, and 
    # inoutmask. Typically it's just result, unless you specify 
    # out/inout parameters in the prototype.
    return args

_HandlerRoutine = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.DWORD)

_kernel32.SetConsoleCtrlHandler.errcheck = _check_bool
_kernel32.SetConsoleCtrlHandler.argtypes = (_HandlerRoutine, 
                                            wintypes.BOOL)

_console_ctrl_handlers = {}

def set_console_ctrl_handler(handler):
    if handler not in _console_ctrl_handlers:
        h = _HandlerRoutine(handler)
        _kernel32.SetConsoleCtrlHandler(h, True)
        _console_ctrl_handlers[handler] = h

您还需要一个 unset_console_ctrl_handler 函数。

仅供参考,控制台不是 cmd窗口。 cmd.exe是一个控制台用户界面(CUI)程序,通常是%COMSPEC%命令解释程序。在这方面,它与powershell.exe或python.exe或任何其他控制台应用程序没有什么不同。

FYI, the console isn't a "cmd" window. cmd.exe is a console user interface (CUI) program that's typically the %COMSPEC% command interpreter. In this respect it's no different from powershell.exe or python.exe, or any other console application.

控制台窗口使用 StandardInput ,<$ c $实现与传统标准I / O兼容的字符界面c> StandardOutput 和 StandardError 。还有一个功能性API(与终端控制序列相对)可创建更精致的文本界面。控制台缓冲区中的每个UCS-2字符都具有颜色和强度等属性。

A console window implements a character interface that's compatible with traditional standard I/O using StandardInput, StandardOutput, and StandardError. There's also a functional API (as opposed to terminal control sequences) to create more elaborate text interfaces. Each UCS-2 character in the console buffer has attributes such as color and intensity.

在NT 6.1之前,每个控制台都由系统服务器进程csrss.exe中的一个线程托管。在NT 6.1+中,每个控制台窗口都托管在conhost.exe实例中,该实例更加安全,因为它不是系统进程,并且为每个控制台窗口提供了单独的进程和安全上下文。在NT 6.3之前,进程通过Windows本地过程调用(LPC)与它的(一个和唯一一个)连接的控制台进行通信。在NT 6.3+中,它改为使用ConDrv设备驱动程序。多个进程可以共享同一控制台窗口。

Prior to NT 6.1, each console is hosted by a thread in the system server process, csrss.exe. In NT 6.1+, each console window is instead hosted in an instance of conhost.exe, which is more secure since it's not a system process and it gives each console window a separate process and security context. Prior to NT 6.3, a process communicates with its (one and only one) attached console via Windows local procedure call (LPC). In NT 6.3+ it instead uses the ConDrv device driver. Multiple processes can share the same console window.

扩展名为.pyw的脚本与pythonw.exe相关联,后者是作为不继承或创建控制台窗口的窗口化应用程序而构建的。如果在这种情况下需要控制台,则可以使用ctypes调用 AllocConsole AttachConsole

Scripts with the extension .pyw are associated with pythonw.exe, which is built as a windowed application that doesn't inherit or create a console window. If you need a console in this case, you can allocate a new one or attach to an existing one by using ctypes to call AllocConsole or AttachConsole.

这篇关于如何检测Windows上python中退出的程序并在退出时执行某些操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆