getting text from WinXP console

C

Chris Maloof

Hello,

Does anyone know how I can read the ASCII text from a console window
(from another application) in WinXP? It doesn't sound like a major
operation, but although I can find the window via pywin32, I haven't
been able to do anything with it. I'd really just like to get the
window text into a string.

By "console window", I mean the sort of thing that comes up when you
run "command" (although this particular one is for the game NetHack).

Thanks,
Chris
 
C

Chris Rebert (cybercobra)

You want the function raw_input().
Have you read the tutorial? I should have been covered there.
 
P

Peter Hansen

Chris said:
You want the function raw_input().
Have you read the tutorial? I should have been covered there.

I'm pretty sure he's looking for a means of capturing
the entire contents of a console window, not just
letting the user enter some textual input.

To the OP: this is an OS-specific question, not a
Python question, and although you have a good chance
of getting an answer from someone here, your
chances are even higher if you ask in some Windows
newsgroup or mailing list. (But let us know when you
find the answer, in any case, for the archives.)

-Peter
 
D

Dennis Lee Bieber

I'm pretty sure he's looking for a means of capturing
the entire contents of a console window, not just
letting the user enter some textual input.
Even worse -- He wants, as I read it, application-x to capture
the contents of a console window running application-y.

--
 
L

Lucas Raab

Chris said:
Hello,

Does anyone know how I can read the ASCII text from a console window
(from another application) in WinXP? It doesn't sound like a major
operation, but although I can find the window via pywin32, I haven't
been able to do anything with it. I'd really just like to get the
window text into a string.

By "console window", I mean the sort of thing that comes up when you
run "command" (although this particular one is for the game NetHack).

Thanks,
Chris

If you're looking to do this from Python then do "python <appname.py> >
output.txt" only without the quotes. AFAIK, this only works on Windows.
Correct me if it works from Linux or another OS.

--
--------------------------
Lucas Raab
lvraab located at earthlink.net
dotpyFE located at gmail.com
AIM: Phoenix11890
MSN: (e-mail address removed)
IRC: lvraab
ICQ: 324767918
Yahoo: Phoenix11890
 
J

Jeff Schwab

Lucas said:
If you're looking to do this from Python then do "python <appname.py> >
output.txt" only without the quotes. AFAIK, this only works on Windows.
Correct me if it works from Linux or another OS.

It works on Unix. :)
 
L

Lucas Raab

Jeff said:
It works on Unix. :)
Alright. Thanks, I wasn't sure.

--
--------------------------
Lucas Raab
lvraab located at earthlink.net
dotpyFE located at gmail.com
AIM: Phoenix11890
MSN: (e-mail address removed)
IRC: lvraab
ICQ: 324767918
Yahoo: Phoenix11890
 
C

Cappy2112

If you re-direct the output to a file, then you won't see it on the
console at all, unless the program writes to stderr separately.
 
C

Cappy2112

Are you the one who is launching the Nethack program, or is it already
running, and you ar e trying to capture the text after Nethack is
launched ?

If you are launching it you can try using one of the python popen()
calls to redirect the screen output to your python program.

I havne't doen this myself, but I've seen this suggested to many people
who have asked a similar question.

Also- you can try posting a message to the Python Tutor- as well as
googling for python popen, to look for examples.


Another alternative, is to use the tee.exe unix util (ported to wn32)
which will duplicate screen I/O to a file, or some other place.

Try googling for "unix utilities win32" -or similar combinations of
these words.
 
J

Jeff Shannon

Lucas said:
If you're looking to do this from Python then do "python <appname.py> >
output.txt" only without the quotes. AFAIK, this only works on Windows.
Correct me if it works from Linux or another OS.

It works in *nix (and probably other OSes as well) to the same extent
that it works in Windows. However, it does *not* do what the OP was
asking for -- it captures the (console-mode) output of appname.py into
a file, but the OP (as I understand it) wanted to have appname.py
capture the already-displayed console output of someotherapp.exe.

Unless I'm seriously mistaken, the only way that this will be possible
is if there's a Win32 API call that will give the correct information.
This might be possible to find in the MSDN documentation, if it
exists, but I suspect that it probably doesn't.

Actually, there's probably a second way -- capture the window image as
a bitmap, and then run OCR software on it. I'm not sure how well most
OCR software will deal with ASCII graphics, though -- they tend to be
optimized for reading "real" text (i.e. words in an actual language).

If it's permissible for the capturing program to start the application
whose output is to be captured, then it may be possible to work as a
proxy -- the capture app would pass (almost) all input to the child
app and then retrieve the child app's output (and probably perform the
actual display on-screen). This won't let you capture the text of an
arbitrary window, though, and would probably be pretty fragile.

Jeff Shannon
 
P

Peter Hansen

Jeff said:
Unless I'm seriously mistaken, the only way that this will be possible
is if there's a Win32 API call that will give the correct information.
This might be possible to find in the MSDN documentation, if it exists,
but I suspect that it probably doesn't.

Just thinking: in NT, XP, and friends, the "DOS" console has
a scrollback buffer. In addition, even in 98 you can cut and
paste text in a console window. Both of these are clear
evidence that the data is available. Whether the API to get
to it is well-documented and available remains to be
answered... I'm guessing it is, somewhere...
 
R

Ron

Actually, there's probably a second way -- capture the window image as
a bitmap, and then run OCR software on it.

There's also OCR aware clipboard software that can cut a selected area
from the screen, convert the graphic image to text and put it on the
clipboard. They work fairly well.

Most of them aren't free. But a shareware version with a limited
trial period might work just fine for this one purpose.

Ron
 
J

Jeff Shannon

Peter said:
Just thinking: in NT, XP, and friends, the "DOS" console has
a scrollback buffer. In addition, even in 98 you can cut and
paste text in a console window. Both of these are clear
evidence that the data is available. Whether the API to get
to it is well-documented and available remains to be
answered... I'm guessing it is, somewhere...

Hm, that's a good point. It may even be possible to simulate
selecting the entire console window and copying the text to the
clipboard, and from there into the capturing application. It might be
worth exploring win32ui & friends...

Jeff Shannon
 
C

Chris Maloof

Thanks for the interesting suggestions!

If you are launching it you can try using one of the python popen()
calls to redirect the screen output to your python program.

Aha. This sounds perfect, and I don't know why it doesn't work even
with a basic command window:
s = subprocess.Popen(args='c:\\WINDOWS\\system32\\command.com', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) [[[completely blank command window appears]]]
s.pid 372
s.stdin.write('hi there')

Traceback (most recent call last):
File "<pyshell#41>", line 1, in -toplevel-
s.stdin.write('hi there')
IOError: [Errno 22] Invalid argument''

I'm guessing it's not the right kind of screen output, somehow? I
should try this with Unix.


Jeff Shannon said:
Unless I'm seriously mistaken, the only way that this will be possible
is if there's a Win32 API call that will give the correct information.
This might be possible to find in the MSDN documentation, if it
exists, but I suspect that it probably doesn't.

I think you're right. I did consider the select-and-copy idea, which
sounds vaguely silly but acceptable if there's a way to do it without
getting the selection area highlighted. At this point I wouldn't be
terribly stunned if it's the best alternative, actually, though an API
call would seem nicer. I'll see if I can turn anything up in the MSDN
library. Peter's advice to ask about this on a Windows list is
probably wisest; I'll post again if I figure it out.

I refuse on principle to do a text -> image -> text conversion, clever
though it is. :)

Lucas Raab said:
If you're looking to do this from Python then do "python <appname.py> >
output.txt" only without the quotes. AFAIK, this only works on Windows.
Correct me if it works from Linux or another OS.

I do this all the time in Unix and had no idea it worked in Windows;
it's not quite what I need but still good to know!

Thanks to everybody for all the help.

Chris
 
C

Cappy2112

Popen(args='c:\\WINDOWS\\system32\\command.com'

Don't launch command.com, try running the actual program you are
interested in in capturing the text for. Although you should be able to
run the command interpreter too- I don't know why that didn't work.

There are several variations of popen, so you may want to explore them
all to see which suits your needs.
 
M

Mark T.

Chris Maloof said:
Hello,

Does anyone know how I can read the ASCII text from a console window
(from another application) in WinXP? It doesn't sound like a major
operation, but although I can find the window via pywin32, I haven't
been able to do anything with it. I'd really just like to get the
window text into a string.

By "console window", I mean the sort of thing that comes up when you
run "command" (although this particular one is for the game NetHack).

Thanks,
Chris

Check out the Win32 Console functions on MSDN, such as AlocConsole(),
ReadConsoleOutput(), GetStdHandle(). I don't see an easy way to get the
screen buffer handle unless you are the process that owns the console,
however.

Mark
 
C

Chris Maloof

Check out the Win32 Console functions on MSDN, such as AlocConsole(),
ReadConsoleOutput(), GetStdHandle(). I don't see an easy way to get the
screen buffer handle unless you are the process that owns the console,
however.

Mark
Yup, this is pretty much closest to what ended up working, after some
more research. There might have been an easier way, but for the
archives, here's the meat of what I did (as seen also in the
python-win32 mailing list):

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top