关闭运行Python脚本的Windows CMD时Python的行为及数据保存问题
解决Windows CMD关闭时Python程序保存数据的问题
当你点击CMD窗口右上角的红叉关闭时,Windows会向Python进程发送CTRL_CLOSE_EVENT系统信号,这和PyCharm停止按钮触发的KeyboardInterrupt异常完全不同——后者是Python层面捕获的CTRL_C_EVENT(对应Ctrl+C操作),而系统级的关闭信号不会触发普通的Python异常,所以你之前的try-except代码无法捕获这个事件。
要实现关闭CMD时自动保存数据,需要注册Windows控制台的信号处理函数,以下是两种可行方案:
方案1:使用pywin32库(第三方库)
先安装依赖:
pip install pywin32
示例代码:
import win32api import win32con def save(): # 替换为你的数据保存逻辑 print("数据已保存") def console_close_handler(event): if event == win32con.CTRL_CLOSE_EVENT: save() # 必须主动退出,否则系统会强制终止进程 win32api.ExitProcess(0) return True # 注册控制台关闭事件处理函数 win32api.SetConsoleCtrlHandler(console_close_handler, True) # 你的主程序逻辑 try: while True: # 模拟持续运行的程序 pass except KeyboardInterrupt: # 兼容Ctrl+C和PyCharm停止按钮的情况 save()
方案2:使用ctypes(无需第三方库)
如果不想安装额外库,可以用Python内置的ctypes调用Windows API:
import ctypes import sys def save(): # 替换为你的数据保存逻辑 print("数据已保存") # 定义Windows控制台处理函数的类型 console_handler_type = ctypes.WINFUNCTYPE(ctypes.BOOL, ctypes.DWORD) def console_close_handler(event): # CTRL_CLOSE_EVENT的事件码是2 if event == 2: save() sys.exit(0) return True # 注册处理函数 handler = console_handler_type(console_close_handler) ctypes.windll.kernel32.SetConsoleCtrlHandler(handler, True) # 你的主程序逻辑 try: while True: # 模拟持续运行的程序 pass except KeyboardInterrupt: save()
注意事项
- 处理函数中必须主动退出进程(
win32api.ExitProcess或sys.exit),否则系统会在短暂延迟后强制终止程序,可能导致保存操作未完成。 - 上述代码同时兼容
KeyboardInterrupt,可以处理Ctrl+C和PyCharm停止按钮的场景。
内容的提问来源于stack exchange,提问作者Phenixis22
相关产品推荐
相关产品推荐

