How To Detect Program Exited In Python On Windows And Do Something On Exit
Solution 1:
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
.
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):
ifnot 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 = {}
defset_console_ctrl_handler(handler):
if handler notin _console_ctrl_handlers:
h = _HandlerRoutine(handler)
_kernel32.SetConsoleCtrlHandler(h, True)
_console_ctrl_handlers[handler] = h
You'd also want an unset_console_ctrl_handler
function.
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.
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.
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.
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
.
Solution 2:
You should use the atexit
module, which allows you to register exit hooks without using os specific function calls.
Post a Comment for "How To Detect Program Exited In Python On Windows And Do Something On Exit"