在 python 可执行文件中实现退出例程

Implement exit routine in python executable

提问人:kamaru510 提问时间:9/6/2023 最后编辑:kamaru510 更新时间:9/7/2023 访问量:69

问:

我使用该库创建了 python 应用程序的可执行文件。pyinstaller

当通过双击启动时,带有 python 控制台的窗口将启动,应用程序开始运行。 现在,当我使用每个窗口右上角的 X 关闭应用程序时,我想在应用程序最终停止之前执行一些代码。*.exe

这是我的代码片段,它给出了我尝试执行的操作的示例:

def exit_handler():
    # This code should get executed before the application finally terminates
    print("I want this to print")
    sys.exit()

def main(*args):
    atexit.register(exit_handler)
    signal.signal(signal.SIGTERM, exit_handler)
    signal.signal(signal.SIGINT, exit_handler)
    uvicorn.run(app, host="0.0.0.0", port=8000)

不幸的是,在使用 . 有谁知道这个问题的解决方案?signalatexitpyinstaller

更新:我正在使用 Windows 操作系统

python pyinstaller 可执行文件 退出

评论

0赞 Daraan 9/6/2023
您如何验证它们现在是否有效?我在那里没有专业知识,我只是想知道打印语句是否可能只是丢失并且没有正确记录,例如,其他一些方法(如创建文件)是否真的有效,以验证代码是否确实运行。
2赞 ShadowRanger 9/6/2023
强烈建议:1)传递给 ,将消息发送到而不是(因此默认情况下输出是无缓冲的),或者,如果消息在逻辑上不是日志/警告,则2)显式传递给(因此立即刷新缓冲区)。我还建议不要使用调用 ;如果稍后注册的任何其他退出处理程序引发异常,这将替换它,因此程序以退出代码 0(成功)而不是非零失败代码退出。file=sys.stderrprintstderrstdoutflush=Trueprintstdoutsys.exit()atexit.register
1赞 ShadowRanger 9/6/2023
对于后一个建议,您可以直接替换为 (假设实际上只是一个 和 调用)。atexit.register(exit_handler)atexit.register(print, "I want this to print", file=sys.stdout)exit_handlerprintsys.exit
0赞 kamaru510 9/6/2023
@Daraan我不在那里使用 print 语句,我使用一个 log 语句,它应该在日志文件中写入一些东西,但这不会发生。
1赞 kamaru510 9/6/2023
@ShadowRanger是的,这可能是 print 语句的解决方案,但实际上我想执行清理代码并将信息写入日志文件

答:

1赞 Codist 9/6/2023 #1

在 Unix 类型系统上尝试以下操作:

from atexit import register
from time import sleep
from signal import signal, SIGINT, SIGTERM

def end():
    print('Goodbye')

def handler(*_):
    print('Signalled')
    exit()

register(end)

signal(SIGINT, handler)
signal(SIGTERM, handler)

sleep(5)

请注意信号处理程序和 atexit 函数之间的区别。

运行此程序并等待至少 5 秒钟。输出将为:

Goodbye

运行此程序并在 5 秒之前中断它(例如,Ctrl-C)。输出将为:

^CSignalled
Goodbye

评论

1赞 kamaru510 9/6/2023
感谢您的回答,但我无法使用此应用程序迁移到 Unix 类型系统。它旨在在 Windows 主机上运行
1赞 Codist 9/7/2023
@kamaru510 在这种情况下,我建议您研究尝试在 Windows 上使用 SIGINT 和 SIGTERM 信号的可行性。如果你在 Windows 系统上尝试这个答案中的代码,并且它的行为方式与我描述的方式不同,那么你就会知道你的方法不是可移植的
0赞 kamaru510 9/7/2023
我上面发布的代码适用于我的 Windows 机器,但前提是我启动 main.py 脚本。当我启动从该应用程序制作的可执行文件时,它不起作用。在我看来,这个问题与.我需要研究当我通过 X 关闭打开的控制台时会发送什么样的信号pyinstaller
0赞 Codist 9/7/2023
@kamaru510 如评论中所述,您在问题中发布的代码存在缺陷
0赞 kamaru510 9/7/2023
当然,这可能是,我已经根据收到的建议对其进行了改进。但即使它奏效了。它在运行可执行文件时也有效,但前提是我使用 CTRL+C 终止应用程序。
0赞 kamaru510 9/7/2023 #2

我终于找到了解决我的问题的方法。与大多数情况一样,对文档的准确阅读会带来解决方案。感谢大家的努力。

https://pyinstaller.org/en/stable/feature-notes.html#signal-handling-in-console-windows-applications-and-onefile-application-cleanup