cx_freeze后subprocess.Popen的行为
我有一些Python代码,使用了subprocess.Popen
来打开一个控制台应用程序,并获取它的标准输出和错误输出。
在解释器中启动这个程序一切正常,效果也如我所期待的那样。
但是,当我使用cx_freeze并加上--base-name Win32GUI
这个选项后,Popen就会在一个控制台窗口中弹出来,这样我就无法捕获标准输出和错误输出了。如果我去掉--base-name Win32GUI
,它又能正常工作,但这时我的界面后面会有一个控制台窗口。
这是我的代码(我试过不使用startupinfo
和不设置shell=False
):
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
subprocess.Popen(['exe', 'arg1', 'arg2'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, startupinfo=startupinfo)
我使用out, err = p.communicate()
来获取标准输出和错误输出。
1 个回答
4
好的,我找到了解决办法。看起来因为这是一个Windows的图形界面应用,所以标准输出的句柄不存在,而子进程似乎也继承了这个特性。所以,有一个简单的解决方法和一个稍微复杂一点的方法,后者涉及到win32api和创建一个管道(我没有尝试这个方法)。
以下是最终有效的代码:
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
stdout_file = tempfile.NamedTemporaryFile(mode='r+', delete=False)
process = subprocess.Popen(['exe', 'arg1', 'arg2'], stdin=subprocess.PIPE, stdout=stdout_file, stderr=subprocess.PIPE, shell=False, startupinfo=startupinfo)
return_code = process.wait()
stdout_file.flush()
stdout_file.seek(0) # This is required to reset position to the start of the file
out = stdout_file.read()
stdout_file.close()