如何检测Windows上python中退出的程序并在退出时执行某些操作 [英] how to detect program exited in python on windows and do something on exit
问题描述
在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屋!