【发布时间】:2019-08-05 21:54:27
【问题描述】:
背景
我有一个 Python 3.5 控制台程序通过 pyinstaller 编译成 Windows 可执行文件。
问题
- 当通过命令提示符执行时,我希望我的程序使用提供的任何参数(可能没有)运行。
- 当通过操作系统的 GUI 执行时(即通过在 Windows 上的 Windows 资源管理器中双击 .exe 等),我希望我的程序提示用户输入。我还需要在退出之前暂停我的程序,以便用户可以阅读输出。
如何检测这些不同的场景?
约束
- 可执行文件必须能够在准系统(即全新安装)Windows/RedHat 机器上运行。
- 编译后的可执行文件必须是单个文件,并且不能依赖未打包在已编译可执行文件内的其他文件(pyinstaller 允许将文件打包在已编译可执行文件内)。
- 该程序可能依赖于第 3 方 python 包。
我尝试过的事情
sys.stdin.isatty()
https://stackoverflow.com/a/3818551/3508142os.isatty(sys.stdout.fileno())
https://stackoverflow.com/a/6108504/3508142
这些在 Windows 上总是返回True。搜索 StackOverflow / 互联网:
How to determine if Python script was run via command line?
How can I check to see if a Python script was started interactively?
据我了解,如果用户启动一个程序,无论它是从命令提示符还是 GUI 启动的,它都会以交互方式运行。我还考虑检查父进程是
cmd.exe还是explorer.exe。但是,通过 Windows 运行命令启动程序将使explorer.exe成为父进程。通过任务管理器启动程序将使任务管理器成为父进程。这些是我可以忍受的极端情况,但显然我更喜欢更强大的解决方案。
【问题讨论】:
-
我假设你的可执行文件是一个控制台应用程序,因为
sys.stdin.isatty()是真的。默认情况下,如果父级有控制台,它将继承父级的控制台。如果没有命令行参数并且父级 not 连接到您的控制台,您可以提示用户。调用GetConsoleProcessList以获取附加到控制台的进程的 PID。我们可以使用 ctypes 或者 PyWin32 来调用这个函数。 -
@eryksun 感谢您的回复。是的,我的可执行文件是一个控制台应用程序。我不熟悉 Windows API 调用;也许您可以通过示例发布完整的答案?
标签: python python-3.x windows pyinstaller