Read/Write from/to a process

Bengt Richter bokr at oz.net
Tue Oct 25 20:48:15 EDT 2005


On Tue, 25 Oct 2005 17:32:28 GMT, Dennis Lee Bieber <wlfraed at ix.netcom.com> wrote:

>On 25 Oct 2005 05:22:20 -0700, "jas" <codecraig at gmail.com> declaimed the
>following in comp.lang.python:
>
>> So it seems there is no good way to handle "interactive" processes on
>> windows using python.  By interactive I mean processes/commands that
>> require user interaction, such as telnet or del (to delete a file or
>> directory sometimes you need to confirm with a yes or no), date, etc.
>>
>	telnetlib includes an "expect" method... 
> 
>> os.system gives the exact behavior, but you can't redirec the output.
>> pexpect isn't supported on windows.  Even with subprocess you can't
>> handle all/most cases..since you have to do things like look for he
>> prompt.
>
>	That applies to any OS... If you have no IPC signalling mechanism
>that the other process has completed an output phase and is now waiting
>for input, you must scan for whatever is the "current" prompt. Even an
>"expect" module is "expecting" to find something you had to specify in
>advance.
>
>	Heck... How do YOU recognize that an application running in a
>command window is waiting for input?
>
>	I suspect you do it by reading the output text and recognizing that
>the cursor is on a line that looks like a prompt. The main difference is
>that you have cognitive understanding of what IS the prompt, and can
>recognize the differences between, say an [abort, retry, exit] prompt
>and c:\junk> prompt. To programmatically handle this situation, you have
>to code the logic to recognize the two possible prompts.
>
If I were going to do something on windows, I think I would look at
creating a cmd.exe process and see if I could get ahold of its console
by way of the windows console-related api, or I might try to write a limited
shell of my own, but I'm not going to do it just for fun ;-)

NT and descendants have all sorts of stuff for waiting for things
and communicating etc. if you want to get down to the raw stuff, e.g.,
----
    GetQueuedCompletionStatus QuickInfo Overview Group

    The GetQueuedCompletionStatus function attempts to dequeue
    an I/O completion packet from a specified input/output
    completion port. If there is no completion packet queued,
    the function waits for a pending input/output operation
    associated with the completion port to complete. The
    function returns when it can dequeue a completion packet, or
    optionally when the function times out. If the function
    returns because of an I/O operation completion, it sets
    several variables that provide information about the
    operation.

    BOOL GetQueuedCompletionStatus(

    HANDLE CompletionPort, // the I/O completion port of
    interest LPDWORD lpNumberOfBytesTransferred, // to receive
    number of bytes transferred during I/O LPDWORD
    lpCompletionKey, // to receive file's completion key
    LPOVERLAPPED * lpOverlapped, // to receive pointer to
    OVERLAPPED structure DWORD dwMilliseconds // optional
    timeout value );

    Parameters

    CompletionPort

    Handle to the input/output completion port of interest. Use
    the CreateIoCompletionPort function to create I/O completion
    ports.

    lpNumberOfBytesTransferred

    Points to a variable that the function sets to the number of
    bytes transferred during an I/O operation that has completed
    and is causing the function to return.

    lpCompletionKey

    Points to a variable that the function sets to the
    completion key value associated with the file handle whose
    I/O operation has completed and is causing the function to
    return. A completion key is a per-file key that is specified
    in a call to CreateIoCompletionPort.

    lpOverlapped

    Points to a variable that the function sets to the address
    of the OVERLAPPED structure that was specified when an
    input/output operation that has completed was started. The
    following functions can be used to start input/output
    operations that complete using I/O completion ports. You
    must pass the function an OVERLAPPED structure and a file
    handle associated (by a call to CreateIoCompletionPort) with
    an I/O completion port to invoke the I/O completion port
    mechanism:

    · ConnectNamedPipe · DeviceIoControl · LockFileEx · ReadFile
    · TransactNamedPipe · WaitCommEvent · WriteFile

    Even if both of the preceding conditions (passing the
    function a file handle associated with a completion port and
    a valid OVERLAPPED structure) are met, an application can
    prevent completion port notification. To do this, specify a
    valid event handle for the hEvent member of the OVERLAPPED
    structure, and set the low order bit of that event handle. A
    valid event handle whose low order bit is set keeps I/O
    completion from being queued to the completion port.

    dwMilliseconds

    Specifies the number of milliseconds that the caller is
    willing to wait for an input/output completion packet to
    appear at the I/O completion port. If a completion packet
    doesn't appear within the specified time, the function times
    out, returns FALSE, and sets *lpOverlapped to NULL. Timing
    out is optional. If dwMilliseconds is -1, the function will
    never time out. If dwMilliseconds is zero and there is no
    I/O operation to dequeue, the function will timeout
    immediately.

    Return Value

    The GetQueuedCompletionStatus function's return value is
    TRUE if the function dequeues an I/O completion packet for a
    successful I/O operation from the completion port. The
    function stores valid values into the variables pointed to
    by lpNumberOfBytesTransferred, lpCompletionKey, and
    lpOverlapped. The function's return value is FALSE, and
    *lpOverlapped is set to NULL, if the function does not
    dequeue an I/O completion packet from the completion port.
    The function does not store valid values into the variables
    pointed to by lpNumberOfBytesTransferred and
    lpCompletionKey. To get extended error information, call
    GetLastError.

    The function's return value is FALSE, and *lpOverlapped is
    not NULL, if the function dequeues an I/O completion packet
    for a failed I/O operation from the completion port. The
    function stores valid values into the variables pointed to
    by lpNumberOfBytesTransferred, lpCompletionKey, and
    lpOverlapped. To get extended error information, call
    GetLastError.

    Remarks

    The Win32 I/O system can be instructed to send I/O
    completion notification packets to input/output completion
    ports, where they are queued up. The CreateIoCompletionPort
    function provides a mechanism for this. When you perform an
    input/output operation with a file handle that has an
    associated input/output completion port, the I/O system
    sends a completion notification packet to the completion
    port when the I/O operation completes. The I/O completion
    port places the completion packet in a first-in-first-out
    queue. The GetQueuedCompletionStatus function retrieves
    these queued I/O completion packets.

    A server application may have several threads calling
    GetQueuedCompletionStatus for the same completion port. As
    input operations complete, the operating system queues
    completion packets to the completion port. If threads are
    actively waiting in a call to this function, queued requests
    complete their call. You can call the
    PostQueuedCompletionStatus function to post an I/O
    completion packet to an I/O completion port. The I/O
    completion packet will satisfy an outstanding call to the
    GetQueuedCompletionStatus function.

    See Also

    ConnectNamedPipe, CreateIoCompletionPort, DeviceIoControl,
    LockFileEx, OVERLAPPED, ReadFile,
    PostQueuedCompletionStatus, TransactNamedPipe,
    WaitCommEvent, WriteFile,
----

And then there is the console stuff,

----
Following are the functions used to access a console. 

AllocConsole
CreateConsoleScreenBuffer
FillConsoleOutputAttribute
FillConsoleOutputCharacter
FlushConsoleInputBuffer
FreeConsole
GenerateConsoleCtrlEvent
GetConsoleCP
GetConsoleCursorInfo
GetConsoleMode
GetConsoleOutputCP
GetConsoleScreenBufferInfo
GetConsoleTitle
GetLargestConsoleWindowSize
GetNumberOfConsoleInputEvents
GetNumberOfConsoleMouseButtons
GetStdHandle
HandlerRoutine
PeekConsoleInput
ReadConsole
ReadConsoleInput
ReadConsoleOutput
ReadConsoleOutputAttribute
ReadConsoleOutputCharacter
ScrollConsoleScreenBuffer
SetConsoleActiveScreenBuffer
SetConsoleCP
SetConsoleCtrlHandler
SetConsoleCursorInfo
SetConsoleCursorPosition
SetConsoleMode
SetConsoleOutputCP
SetConsoleScreenBufferSize
SetConsoleTextAttribute
SetConsoleTitle
SetConsoleWindowInfo
SetStdHandle
WriteConsole
WriteConsoleInput
WriteConsoleOutput
WriteConsoleOutputAttribute
WriteConsoleOutputCharacter 
----
And that is a miniscule piece of it all.
For sychronizing, there ought to be something in:
---
Following are the functions used in synchronization. 

CreateEvent
CreateMutex
CreateSemaphore
DeleteCriticalSection
EnterCriticalSection
GetOverlappedResult
InitializeCriticalSection
InterlockedDecrement
InterlockedExchange
InterlockedIncrement
LeaveCriticalSection
MsgWaitForMultipleObjects
OpenEvent
OpenMutex
OpenSemaphore
PulseEvent
ReleaseMutex
ReleaseSemaphore
ResetEvent
SetEvent
WaitForMultipleObjects
WaitForMultipleObjectsEx
WaitForSingleObject
WaitForSingleObjectEx 

BTW, 
"""
The CreateFile function creates, opens, or truncates a file, pipe,
communications resource, disk device, or console. It returns a handle
that can be used to access the object. It can also open and return
a handle to a directory.
"""
So it seems likely someone has put together most of the pieces already,
just maybe not wrapped in a python API ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list