gpt4 book ai didi

Python 子进程无法捕获 Windows 程序的输出

转载 作者:可可西里 更新时间:2023-11-01 10:14:07 30 4
gpt4 key购买 nike

使用 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 不捕获任何内容。我很乐意在评论中重试这些命令中的任何一个。

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

这是程序用来输出的程序集(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

最佳答案

一位同事指出了这个问题。原来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

关于Python 子进程无法捕获 Windows 程序的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47038990/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com