You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AutoIt StdoutRead无法捕获Python logging模块输出的问题求助

解决AutoIt无法捕获Python logging模块输出的问题

问题根源

Python标准logging模块默认将日志信息输出到标准错误流(stderr),而你的AutoIt代码仅通过$STDOUT_CHILD参数捕获了标准输出流(stdout),因此print()函数的内容能被正常捕获,但日志内容会被忽略。

解决方案

方案1:修改Python脚本,将logging输出重定向到stdout

通过配置logging的输出流为sys.stdout,让日志和print内容走同一个流:

import logging
import sys

# 配置logging输出到标准输出
logging.basicConfig(stream=sys.stdout, level=logging.WARNING)
logging.warning("Warning this could HURT!")

print(f'Hello world!')

方案2:修改AutoIt代码,同时捕获stderr流

在启动子进程时添加$STDERR_CHILD参数,同时读取标准错误流的内容并合并到结果中:

#include "Constants.au3"
#pragma compile(Console, true)
#AutoIt3Wrapper_Change2CUI=Y

Func ExecTestScript($command, $useEnv="")
    Local $line
    ; 添加$STDERR_CHILD参数,同时捕获stdout和stderr
    Local $pid = Run("cmd.exe", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
    StdinWrite($pid, 'cd "' & @ScriptDir & '"' & @CRLF)
    If StringLen($useEnv) > 0 Then
        StdinWrite($pid, "conda activate " & $useEnv & @CRLF)
    EndIf
    Local $cmd = $command & @CRLF
    ConsoleWrite($cmd & @CRLF)
    StdinWrite($pid, $cmd)
    StdinWrite($pid, "exit" & @CRLF)
    Local $nChars, $errChars
    While 1
        ; 读取stdout内容
        $nChars = StdoutRead($pid)
        If @error Then ExitLoop
        If @extended > 0 Then
            ConsoleWrite("++ " & $nChars & @CRLF)
            $line &= $nChars
        EndIf
        ; 读取stderr内容并合并
        $errChars = StderrRead($pid)
        If @extended > 0 Then
            ConsoleWrite("-- " & $errChars & @CRLF)
            $line &= $errChars
        EndIf
    WEnd
    ProcessClose($pid)
    Return $line
EndFunc

Local $res = ExecTestScript('python myTestScript.py', 'py38')

方案3:直接运行Python程序,减少cmd中转

跳过cmd.exe,直接启动Python进程,避免中间层的输入输出干扰,同时捕获双流:

#include "Constants.au3"
#pragma compile(Console, true)
#AutoIt3Wrapper_Change2CUI=Y

Func ExecTestScript($scriptPath, $useEnv="")
    Local $line
    Local $pythonCmd
    ; 如果需要激活conda环境,直接调用环境内的Python路径
    If StringLen($useEnv) > 0 Then
        ; 替换为你的conda环境Python路径,示例路径仅供参考
        $pythonCmd = 'C:\Users\YourName\miniconda3\envs\' & $useEnv & '\python.exe'
    Else
        $pythonCmd = 'python.exe'
    EndIf
    ; 直接运行Python脚本,同时捕获stdout和stderr
    Local $pid = Run('"' & $pythonCmd & '" "' & $scriptPath & '"', "", @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD)
    
    Local $nChars, $errChars
    While 1
        $nChars = StdoutRead($pid)
        If @error Then ExitLoop
        If @extended > 0 Then
            ConsoleWrite("++ " & $nChars & @CRLF)
            $line &= $nChars
        EndIf
        $errChars = StderrRead($pid)
        If @extended > 0 Then
            ConsoleWrite("-- " & $errChars & @CRLF)
            $line &= $errChars
        EndIf
    WEnd
    ProcessClose($pid)
    Return $line
EndFunc

Local $res = ExecTestScript(@ScriptDir & '\myTestScript.py', 'py38')

问题分析思路

  • 确认输出流归属:在命令行执行python myTestScript.py 2>&1,如果日志内容和print内容同时显示,说明日志确实输出到stderr。
  • 检查AutoIt捕获参数:确保Run函数的参数包含$STDERR_CHILD,否则无法捕获错误流内容。
  • 简化执行流程:避免通过cmd.exe中转执行脚本,减少环境变量、命令解析等环节可能带来的干扰。

内容的提问来源于stack exchange,提问作者mhanuel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:52:26