子进程似乎在 pyinstaller exe 文件中不起作用

Posted

技术标签:

【中文标题】子进程似乎在 pyinstaller exe 文件中不起作用【英文标题】:subprocess seems not working in pyinstaller exe file 【发布时间】:2018-10-31 23:02:02 【问题描述】:

当我使用PyCharm 运行它时,我在tkinter 中的程序运行良好, 当我使用 pyinstaller 创建.exe 文件时,pyinstaller -i"icon.ico" -w -F script.py我没有错误。 我将script.exe 粘贴在与script.py 相同的文件夹中,运行它后,我认为在subprocess 所在的步骤中,它没有回答,因为我在子进程行及其工作之前有print

有人知道为什么吗?

这是带有子进程的行:

import subprocess
from subprocess import Popen, PIPE
 s = subprocess.Popen([EXE,files,'command'],shell=True, stdout=subprocess.PIPE)

编辑:

同样的问题:

s = subprocess.check_output([EXE,files,'command'],shell=True, stderr=subprocess.STDOUT)

【问题讨论】:

在 pyinstaller 生成的二进制文件中使用 subprocess.Popen() 需要进行一些修改。检查this recipe 作为示例和对正在发生的事情的解释。 @zwer 谢谢,但是当我使用close_fds=True 时,我收到此错误:raise ValueError("close_fds is not supported on Windows " ValueError: close_fds is not supported on Windows platforms if you redirect stdin/stdout/stderr 【参考方案1】:

您可以在 -w 模式或 --windowed 下编译您的代码,但是您还必须指定 stdin 和 stderr。

所以改变:

s = subprocess.Popen([EXE,files,'command'],shell=True, stdout=subprocess.PIPE)

到:

s = subprocess.Popen([EXE,files,'command'],shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

【讨论】:

@DaanWittenburg 我用“systeminfo”命令试过这个,按钮我的python程序会冻结。知道这是为什么吗?这只发生在我使用 --noconsole 命令时。没有它,它运行良好。我也看到了一个弹出窗口,但它并没有真正做任何事情。它会在一段时间后关闭,但没有任何内容写入我的文件。 这个答案对我有用,即使使用 -w--noconsole 选项。【参考方案2】:

通过不使用-w 命令从 .py 脚本生成 exe 文件解决了问题。

【讨论】:

【参考方案3】:

使用此函数来获取命令的输出。与 -F 和 -w 选项一起使用:

import subprocess
def popen(cmd: str) -> str:
    """For pyinstaller -w"""
    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    process = subprocess.Popen(cmd,startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
    return decode_utf8_fixed(process.stdout.read())

【讨论】:

我不知道 :o 在 Linux 上,必须使用等效的模块“fctnl”...我很确定它可以做 startupinfo 在 Windows 上可以做的事情。并且有很多关于带有 fctnl 的标志的模式线程 :)【参考方案4】:

我收到了错误 [WinError 6] The handle is invalid 跑线时

data = subprocess.check_output(['netsh', 'wlan', 'show', 'profiles']).decode('utf-8').split('\n')

这为我解决了这个问题: https://***.com/a/43606682/12668094

【讨论】:

以上是关于子进程似乎在 pyinstaller exe 文件中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

pyinstaller打包Windows的exe文件后,多进程导致程序反复重启,python

pyinstaller递归错误:超出最大递归深度

Pyinstaller (python打包为exe文件)

pyinstaller打包exe时subprocess无效的解决方法

导出单个 .exe 时,PyInstaller 卡在“正在构建 PKG ...”

使用Pyinstaller的Python子进程Popen