[python-win32] reading from console child process

Chris Maloof cjmaloof at gmail.com
Tue Apr 5 05:52:11 CEST 2005


Niki Spahiev wrote:

> Chris Maloof wrote:
>> Hello,
>>
>> I'm trying to read the output from a WinXP console application using 
>> PythonWin -- that is, I start the application as a child process, and I 
>> want to be able to read the ASCII text in the application's screen.
>>
>> The child app uses MSDN functions WriteConsoleOutputChar() and 
>> WriteConsoleOutputAttributes() for output.  Thus I think I need to use 
>> ReadConsoleOutput() and WriteConsoleInput() to communicate with it, as 
>> described here: 
>> http://homepages.tesco.net/~J.deBoynePollard/FGA/capture-console-win32.html . 
>> Unfortunately these don't seem to be implemented in PyWin32.
>>
>
> Try console module from effbot or use ctypes.
>
> HTH
> Niki Spahiev

Thanks for the help!  ctypes ended up working for me, with help from 
win32process where possible.  I'm not sure why the solutions involving popen 
variants failed; I might have missed something easier.  Here's the meat of 
my solution for the archives anyway, though.

import win32process
from ctypes import *
import time

# Constants from winbase.h in .NET SDK
STD_INPUT_HANDLE = c_uint(-10) # (not used here)
STD_OUTPUT_HANDLE = c_uint(-11)
STD_ERROR_HANDLE = c_uint(-12) # (not used here)

startup = win32process.STARTUPINFO()
(hProcess, hThread, dwProcessId, dwThreadId) = \
 win32process.CreateProcess("C:\myConsoleApp.exe",
                           "-X",
                           None,
                           None,
                           0,
                           0,
                           None,
                           None,
                           startup)
time.sleep(1) #wait for console to initialize

# Use ctypes to simulate a struct from the Win32 API
class COORD(Structure):
    _fields_ = [("X", c_short),
                ("Y", c_short)]

topleft = COORD(0,0)

CHARS_TO_READ = 200
result = create_string_buffer(CHARS_TO_READ)
count = c_int()

windll.kernel32.AttachConsole(c_uint(dwProcessId))
inHandle = windll.kernel32.GetStdHandle(STD_INPUT_HANDLE)
outHandle = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
errHandle = windll.kernel32.GetStdHandle(STD_ERROR_HANDLE)

# See Win32 API for definition
windll.kernel32.ReadConsoleOutputCharacterA(outHandle,
                                            result,
                                            CHARS_TO_READ,
                                            topleft,
                                            byref(count))

print result.value



More information about the Python-win32 mailing list