Pythonsubprocess无法捕获Windows程序的输出

使用stdout=subprocess.PIPE停止输出到控制台,但是不会捕获任何内容。

 >>> import subprocess >>> proc = subprocess.Popen(['C:\\Users\\me\\program.exe']) >>> ERROR: please provide an argument // TRUNCATED USAGE OUTPUT proc.wait() 0 >>> proc = subprocess.Popen([''C:\\Users\\me\\program.exe''], stdout=subprocess.PIPE) >>> proc.communicate() ('', None) 

我已经尝试了每个组合可用在stackoverflow。 shell=True没有工作。 产生一个子cmd没有奏效。 subprocess.check_output捕获任何东西。 我很高兴在评论中重试这些命令。

我猜这与程序附加到shell有关。

这是程序用来输出的程序集( mcall只是一个将内存alignment到16位的macros)。 我包含这个的原因是GetStdHandle正在影响事情。

 console_write PROC ; rcx MSG ; rdx LEN prologue push rcx push rdx xor rcx, rcx mov ecx, [stdout] mcall GetStdHandle mov rcx, rax xor rdx, rdx pop r8 ; len pop rdx ; msg push 0 mov r9, rsp push 0 mcall WriteConsoleA pop rcx pop rcx epilogue console_write ENDP 

我被困在这一个。 我在Linux上做了这么多次。 我只是对Windows内部知识不够了解。 谢谢!


编辑:我试过的其他东西:

pipe理员(也用STDERR捕获)

 C:\Windows\system32>C:\Python27\python.exe Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import subprocess >>> proc = subprocess.Popen(['C:\\Users\\me\\program.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) >>> proc.communicate() ('', '') 

STDOUT文件redirect

 >>> import os >>> os.system('C:\\Users\\me\\program.exe > out.txt') 0 >>> f = open('out.txt', 'r') >>> f.read() '' 

STDERR文件redirect

 >>> import os >>> os.system('C:\\Users\\me\\program.exe 2>out.txt') ERROR: please provide an argument // TRUNCATED USAGE OUTPUT 0 >>> open('out.txt', 'r').read() '' 

命令行捕获失败(禁止输出到cmd,但没有捕获)

 program.exe > out.txt 

Solutions Collecting From Web of "Pythonsubprocess无法捕获Windows程序的输出"

你是否也试图赶上stderr?

 proc = subprocess.Popen([''C:\\Users\\me\\program.exe''], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

UPDATE

您可以尝试在进程运行时逐行读取输出,例如:

 p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: retcode = p.poll() print p.stdout.readline() if retcode is not None: break 

一位同事指出了这个问题。 事实证明, WriteConsole不能被重定向到一个文件,它只能用于控制台句柄。 [1] [2]

这个StackOverflow答案给出了如何解决它的大纲。 我已经用Python实现了,如果其他人有这个问题。

 import win32console import subprocess import msvcrt import os ccsb = win32console.CreateConsoleScreenBuffer() fd = msvcrt.open_osfhandle(ccsb, os.O_APPEND) proc = subprocess.Popen(['C:\\Users\\me\\program.exe'], stdout=fd) proc.wait() ccsb.ReadConsoleOutputCharacter(100, win32console.PyCOORDType(0,0)) # reads 100 characters from the first line 

对我来说更好的解决方案是使用相同的StdHandleWriteConsoleA更改为WriteFile

 console_write PROC ; rcx MSG ; rdx LEN prologue push rcx push rdx xor rcx, rcx mov ecx, [stdout] mcall GetStdHandle mov rcx, rax ; Write File pop r8 ; len pop rdx ; msg ; unalign for odd number of pushed args mov rbx, rsp sub rbx, 8 and rbx, 0Fh sub rsp, rbx ; args mov rcx, rax ; handle xor r9, r9 push 0 ; 1 arg (ununaligns) sub rsp, 20h ; shadow call WriteFile add rsp, 28h ; shadow + arg add rsp, rbx ; realign epilogue console_write ENDP