使用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
只是一个将内存对齐到16位的宏)。我包含这个的原因是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内部的了解不够充分。谢谢!
编辑:我尝试过的其他内容:
管理员(也使用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文件重定向
>>> import os
>>> os.system('C:\\Users\\me\\program.exe > out.txt')
0
>>> f = open('out.txt', 'r')
>>> f.read()
''
STDERR文件重定向
>>> 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
答案 0 :(得分:1)
你是否也试图抓住stderr?
proc = subprocess.Popen([''C:\\Users\\me\\program.exe''], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
<强>更新强>
您可以尝试在进程运行时逐行读取输出,例如:
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
答案 1 :(得分:1)
一位同事指出了这个问题。事实证明WriteConsole
无法重定向到文件,它只能用于控制台句柄。 [1] [2]
这个StackOverflow answer给出了如何解决它的大纲。如果其他人有这个问题,我已经用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
对我来说,更好的解决方案是使用相同的WriteConsoleA
将WriteFile
更改为StdHandle
。
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
答案 2 :(得分:1)
我认为我没有足够的代表来建议一个问题可能是重复的,也没有评论,所以我将此作为答案发布,因为尽管 douggard 的回答使我在思考上走上了正轨,但它没有t 实际上在我的情况下有效,而且我很难找到可行的解决方案。
这里有一个捕获 CONOUT 并为我工作的答案:https://stackoverflow.com/a/38749458/1675668