停止键盘中断到达批处理文件处理器

问题描述 投票:0回答:2

我正在 Windows 上用 Python 3 编写一些代码,如下所示:

try:
    do something that takes a long time
    (training a neural network in TensorFlow, as it happens)
except KeyboardInterrupt:
    print('^C')
print a summary of results
still useful even if the training was cut short early

如果直接从控制台使用

python foo.py
运行,效果非常好。

但是,如果对 Python 的调用是在批处理文件中,它最终会执行上述所有操作,但仍然会向控制台发送“终止批处理作业”提示。

有办法阻止这种情况发生吗?通过在Python中完全吃掉^C,直接跳出批处理文件还是其他方式?

python windows batch-file windows-console
2个回答
2
投票

在批处理文件中使用

break
更多信息)命令,这将禁用 CTRL+C 停止文件

编辑:根据this site的break命令

较新版本的 Windows(Windows ME、Windows 2000、Windows XP 及更高版本)仅包含此命令以实现向后兼容性,关闭中断没有任何效果。

我亲自测试了这一点,并且可以确认,当我找到解决方法时我会进行编辑

编辑#2:如果您可以有第二个批处理脚本来运行

start "" /b /wait cmd /c "yourfile.bat"
,但是众所周知,这会导致其他嵌套批处理文件出现故障

禁用 Ctrl+C 的标志由子进程继承,因此 Python 将不再引发键盘中断。另外,如果从控制台的读取被 Ctrl+C 中断而没有从 CRT 获取 SIGINT,那么 Python 中仍然存在错误。 Python 脚本应通过 ctypes 手动启用 Ctrl+C。使用导入ctypes; kernel32 = ctypes.WinDLL('kernel32', use_last_error=True);成功= kernel32.SetConsoleCtrlHandler(无,假)

编辑#3正如Eryksyn(在评论中)所指出的,您可以使用cytpes启用它;

import ctypes; 
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True); success = kernel32.SetConsoleCtrlHandler(None, False)

编辑#4:我想我找到了它,试试这个(虽然它可能不起作用)你可以使用threading导入吗?

import time
from threading import Thread

def noInterrupt():
    for i in xrange(4):
        print i
        time.sleep(1)

a = Thread(target=noInterrupt)
a.start()
a.join()
print "done"

0
投票

Windows 允许您对当前进程关闭 Ctrl-C,这也会抑制操作系统中 Ctrl-C 已发送到当前进程的记录。

您可以使用上下文管理器完全忽略 Ctrl-C,如下所示:

class Ignore_Ctrl_C:
     
     def __enter__(self):
        ctypes.windll.kernel32.SetConsoleCtrlHandler(None, True)
        return self
     
     def __exit__(self, exc_type, exc_value, traceback):
        ctypes.windll.kernel32.SetConsoleCtrlHandler(None, False)


with Ignore_Ctrl_C():
    do_something_that_requires_Ctrl_C_off()

如果您有 main() 函数,您可以尝试使用多进程模块将其作为单独的进程运行,并让顶级进程在等待 main() 完成时使用 Ignore_Ctrl_C() 。 我希望任何进入子进程的 Ctrl-C 最终都不会与顶级进程相关联,并且您的批处理文件不应该要求终止。

或者,如果您不能或不想摆弄您的 python 程序,您可以在“运行程序”程序中使用 Ignore_Ctrl_C() 来启动您的程序并等待,而不是直接运行您的程序的批处理文件就完成了。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.