Re: Read/Write from/to a process
Thanks, that is certainly a start. As you mentioned, the "cd" could is an issue. Perhaps checking to see if the line ends with ">" is sufficient? Dennis Lee Bieber wrote: > On 24 Oct 2005 07:20:42 -0700, "jas" <[EMAIL PROTECTED]> declaimed the > following in comp.lang.python: > > > Hi, > > I would like to start a new process and be able to read/write from/to > > it. I have tried things like... > > > > import subprocess as sp > > p = sp.Popen("cmd.exe", stdout=sp.PIPE) > > p.stdin.write("hostname\n") > > > > however, it doesn't seem to work. I think the cmd.exe is catching it. > > One: you didn't read any of the "returned" output... > > Two: the output only seems to be available upon EOF, which means the > spawned command processor has to exit first... Though you CAN read one > character at a time, and then have to build lines and expected prompt > strings... > > > This seems to work: > -=-=-=-=-=-=-=-=- > import subprocess > import os > > PROMPT = os.getcwd() + ">" > > def getLine(proc): > ld = [] > while True: > c = proc.stdout.read(1) > if c == "\r": continue #skip Windows > if c != "\n": ld.append(c) #save all but > if c is None or c == "\n" or c == ">": break > ln = "".join(ld) > return ln > > p = subprocess.Popen("cmd.exe", stdout=subprocess.PIPE, stdin = > subprocess.PIPE) > > print " START of captured output" > while True: > ln = getLine(p) > print ln > if ln == PROMPT: break > print " END of captured output" > > p.stdin.write("ipconfig\n") > print " START of captured output" > while True: > ln = getLine(p) > print ln > if ln == PROMPT: break > print " END of captured output" > > p.stdin.write("dir\n") > print " START of captured output" > while True: > ln = getLine(p) > print ln > if ln == PROMPT: break > print " END of captured output" > > p.stdin.write("exit\n") > -=-=-=-=-=-=-=-=-=- > E:\UserData\Dennis Lee Bieber\My Documents>python script1.py > START of captured output > Microsoft Windows XP [Version 5.1.2600] > (C) Copyright 1985-2001 Microsoft Corp. > > E:\UserData\Dennis Lee Bieber\My Documents> > END of captured output > START of captured output > ipconfig > > Windows IP Configuration > > > Ethernet adapter Local Area Connection: > > Connection-specific DNS Suffix . : > IP Address. . . . . . . . . . . . : 192.168.1.100 > Subnet Mask . . . . . . . . . . . : 255.255.255.0 > IP Address. . . . . . . . . . . . : fe80::211:11ff:fee1:f303%4 > Default Gateway . . . . . . . . . : 192.168.1.1 > > Tunnel adapter Teredo Tunneling Pseudo-Interface: > > Connection-specific DNS Suffix . : > IP Address. . . . . . . . . . . . : > 3ffe:831f:4004:1956:0:fbde:bd0a:e50b > IP Address. . . . . . . . . . . . : fe80::5445:5245:444f%5 > Default Gateway . . . . . . . . . : :: > > Tunnel adapter Automatic Tunneling Pseudo-Interface: > > Connection-specific DNS Suffix . : > IP Address. . . . . . . . . . . . : fe80::5efe:192.168.1.100%2 > Default Gateway . . . . . . . . . : > > E:\UserData\Dennis Lee Bieber\My Documents> > END of captured output > START of captured output > dir > Volume in drive E is Data > Volume Serial Number is 2626-D991 > > Directory of E:\UserData\Dennis Lee Bieber\My Documents > > 10/24/2005 09:23 AM > . > 10/24/2005 09:23 AM > .. > 07/25/2005 10:39 PM > .metadata > 10/06/2005 09:54 AM > Ada Progs > 08/13/2005 02:01 PM > Agent Data > 10/21/2005 09:29 AM 421,820 apress_offer.pdf > 07/03/2005 11:36 AM 132 cp.py > 07/17/2005 12:25 PM > Cyberlink > 07/06/2005 09:32 AM 102,400 db1.mdb > 07/26/2005 12:20 AM26,614 eclipse_code.xml > 10/24/2005 01:08 AM > Eudora > 06/24/2005 08:50 PM 667 fake_oosums.ads > 06/24/2005 08:50 PM 695 fake_oosums.ali > 09/06/2005 09:01 PM > Genealogy > 07/13/2005 10:56 PM > HomeSite > 05/08/2005 01:05 PM > Investing > 10/21/2005 10:04 PM > Java Progs > 08/04/2005 10:13 PM 162 main.py > 10/11/2005 10:43 PM > My Downloads > 05/01/2005 10:31 AM > My eBooks > 04/22/2005 12:09 AM > My Music > 07/10/2005 11:43 AM > My Pictures > 06/29/2005 11:55 PM > My PSP Files > 05/23/2005 09:30 AM > My Videos > 05/01/2005 12:49 PM > Office Documents > 06/27/2005 03:19 PM 7,961,778 > org.eclipse.jdt.doc.user.I20050627-1435.pdf > 06/27/2005 03:19 PM 6,791,109 > org.eclipse.platform.doc.user.I20050627-1435.pdf > 10/11/2005 10:52 PM56 oth_tsr_rm_750.ram > 07/20/2005 09:32 AM 108,457 parkerred15yc.jpg > 09/03/2005 10:36 PM > Pytho
Re: Read/Write from/to a process
actually, i can't check for ">" only because if you a dir, a line can end with a > but is not the end of the output jas wrote: > Thanks, that is certainly a start. As you mentioned, the "cd" could is > an issue. > > Perhaps checking to see if the line ends with ">" is sufficient? > > Dennis Lee Bieber wrote: > > On 24 Oct 2005 07:20:42 -0700, "jas" <[EMAIL PROTECTED]> declaimed the > > following in comp.lang.python: > > > > > Hi, > > > I would like to start a new process and be able to read/write from/to > > > it. I have tried things like... > > > > > > import subprocess as sp > > > p = sp.Popen("cmd.exe", stdout=sp.PIPE) > > > p.stdin.write("hostname\n") > > > > > > however, it doesn't seem to work. I think the cmd.exe is catching it. > > > > One: you didn't read any of the "returned" output... > > > > Two: the output only seems to be available upon EOF, which means the > > spawned command processor has to exit first... Though you CAN read one > > character at a time, and then have to build lines and expected prompt > > strings... > > > > > > This seems to work: > > -=-=-=-=-=-=-=-=- > > import subprocess > > import os > > > > PROMPT = os.getcwd() + ">" > > > > def getLine(proc): > > ld = [] > > while True: > > c = proc.stdout.read(1) > > if c == "\r": continue #skip Windows > > if c != "\n": ld.append(c) #save all but > > if c is None or c == "\n" or c == ">": break > > ln = "".join(ld) > > return ln > > > > p = subprocess.Popen("cmd.exe", stdout=subprocess.PIPE, stdin = > > subprocess.PIPE) > > > > print " START of captured output" > > while True: > > ln = getLine(p) > > print ln > > if ln == PROMPT: break > > print " END of captured output" > > > > p.stdin.write("ipconfig\n") > > print " START of captured output" > > while True: > > ln = getLine(p) > > print ln > > if ln == PROMPT: break > > print " END of captured output" > > > > p.stdin.write("dir\n") > > print " START of captured output" > > while True: > > ln = getLine(p) > > print ln > > if ln == PROMPT: break > > print " END of captured output" > > > > p.stdin.write("exit\n") > > -=-=-=-=-=-=-=-=-=- > > E:\UserData\Dennis Lee Bieber\My Documents>python script1.py > > START of captured output > > Microsoft Windows XP [Version 5.1.2600] > > (C) Copyright 1985-2001 Microsoft Corp. > > > > E:\UserData\Dennis Lee Bieber\My Documents> > > END of captured output > > START of captured output > > ipconfig > > > > Windows IP Configuration > > > > > > Ethernet adapter Local Area Connection: > > > > Connection-specific DNS Suffix . : > > IP Address. . . . . . . . . . . . : 192.168.1.100 > > Subnet Mask . . . . . . . . . . . : 255.255.255.0 > > IP Address. . . . . . . . . . . . : fe80::211:11ff:fee1:f303%4 > > Default Gateway . . . . . . . . . : 192.168.1.1 > > > > Tunnel adapter Teredo Tunneling Pseudo-Interface: > > > > Connection-specific DNS Suffix . : > > IP Address. . . . . . . . . . . . : > > 3ffe:831f:4004:1956:0:fbde:bd0a:e50b > > IP Address. . . . . . . . . . . . : fe80::5445:5245:444f%5 > > Default Gateway . . . . . . . . . : :: > > > > Tunnel adapter Automatic Tunneling Pseudo-Interface: > > > > Connection-specific DNS Suffix . : > > IP Address. . . . . . . . . . . . : fe80::5efe:192.168.1.100%2 > > Default Gateway . . . . . . . . . : > > > > E:\UserData\Dennis Lee Bieber\My Documents> > > END of captured output > > START of captured output > > dir > > Volume in drive E is Data > > Volume Serial Number is 2626-D991 > > > > Directory of E:\UserData\Dennis Lee Bieber\My Documents > > > > 10/24/2005 09:23 AM > > . > > 10/24/2005 09:23 AM > > .. > > 07/25/2005 10:39 PM > > .metadata > > 10/06/2005 09:54 AM > > Ada Progs > > 08/13/2005 02:01 PM > > Agent Data > > 10/21/2005 09:29 AM 421,820 apress_offer.pdf > > 07/03/2005 11:36 AM 132 cp.py > > 07/17/2005 12:25 PM > > Cyberlink > > 07/06/2005 09:32 AM 102,400 db1.mdb > > 07/26/2005 12:20 AM26,614 eclipse_code.xml > > 10/24/2005 01:08 AM > > Eudora > > 06/24/2005 08:50 PM 667 fake_oosums.ads > > 06/24/2005 08:50 PM 695 fake_oosums.ali > > 09/06/2005 09:01 PM > > Genealogy > > 07/13/2005 10:56 PM > > HomeSite > > 05/08/2005 01:05 PM > > Investing > > 10/21/2005 10:04 PM > > Java Progs > > 08/04/2005 10:13 PM 162 main.py > > 10/11/2005 10:43 PM > > My Downloads > > 05/01/2005 10:31 AM > > My eBooks > > 04/22/2005 12:09 AM > > My Music > > 07/10/2005 11:43 AM > > My Pictures > > 06/29/2005 11:55 PM > > My PSP Files > > 05/23/2005
Re: Read/Write from/to a process
What about having a thread which reads from subprocess.Popen()'s stdout...instead of read/write, read/write. just always read, and write when needed? any comments on that idea? jas wrote: > actually, i can't check for ">" only because if you a dir, a line can > end with a > but is not the end of the output > > jas wrote: > > Thanks, that is certainly a start. As you mentioned, the "cd" could is > > an issue. > > > > Perhaps checking to see if the line ends with ">" is sufficient? > > > > Dennis Lee Bieber wrote: > > > On 24 Oct 2005 07:20:42 -0700, "jas" <[EMAIL PROTECTED]> declaimed the > > > following in comp.lang.python: > > > > > > > Hi, > > > > I would like to start a new process and be able to read/write from/to > > > > it. I have tried things like... > > > > > > > > import subprocess as sp > > > > p = sp.Popen("cmd.exe", stdout=sp.PIPE) > > > > p.stdin.write("hostname\n") > > > > > > > > however, it doesn't seem to work. I think the cmd.exe is catching it. > > > > > > One: you didn't read any of the "returned" output... > > > > > > Two: the output only seems to be available upon EOF, which means the > > > spawned command processor has to exit first... Though you CAN read one > > > character at a time, and then have to build lines and expected prompt > > > strings... > > > > > > > > > This seems to work: > > > -=-=-=-=-=-=-=-=- > > > import subprocess > > > import os > > > > > > PROMPT = os.getcwd() + ">" > > > > > > def getLine(proc): > > > ld = [] > > > while True: > > > c = proc.stdout.read(1) > > > if c == "\r": continue #skip Windows > > > if c != "\n": ld.append(c) #save all but > > > if c is None or c == "\n" or c == ">": break > > > ln = "".join(ld) > > > return ln > > > > > > p = subprocess.Popen("cmd.exe", stdout=subprocess.PIPE, stdin = > > > subprocess.PIPE) > > > > > > print " START of captured output" > > > while True: > > > ln = getLine(p) > > > print ln > > > if ln == PROMPT: break > > > print " END of captured output" > > > > > > p.stdin.write("ipconfig\n") > > > print " START of captured output" > > > while True: > > > ln = getLine(p) > > > print ln > > > if ln == PROMPT: break > > > print " END of captured output" > > > > > > p.stdin.write("dir\n") > > > print " START of captured output" > > > while True: > > > ln = getLine(p) > > > print ln > > > if ln == PROMPT: break > > > print " END of captured output" > > > > > > p.stdin.write("exit\n") > > > -=-=-=-=-=-=-=-=-=- > > > E:\UserData\Dennis Lee Bieber\My Documents>python script1.py > > > START of captured output > > > Microsoft Windows XP [Version 5.1.2600] > > > (C) Copyright 1985-2001 Microsoft Corp. > > > > > > E:\UserData\Dennis Lee Bieber\My Documents> > > > END of captured output > > > START of captured output > > > ipconfig > > > > > > Windows IP Configuration > > > > > > > > > Ethernet adapter Local Area Connection: > > > > > > Connection-specific DNS Suffix . : > > > IP Address. . . . . . . . . . . . : 192.168.1.100 > > > Subnet Mask . . . . . . . . . . . : 255.255.255.0 > > > IP Address. . . . . . . . . . . . : fe80::211:11ff:fee1:f303%4 > > > Default Gateway . . . . . . . . . : 192.168.1.1 > > > > > > Tunnel adapter Teredo Tunneling Pseudo-Interface: > > > > > > Connection-specific DNS Suffix . : > > > IP Address. . . . . . . . . . . . : > > > 3ffe:831f:4004:1956:0:fbde:bd0a:e50b > > > IP Address. . . . . . . . . . . . : fe80::5445:5245:444f%5 > > > Default Gateway . . . . . . . . . : :: > > > > > > Tunnel adapter Automatic Tunneling Pseudo-Interface: > > > > > > Connection-specific DNS Suffix . : > > > IP Address. . . . . . . . . . . . : fe80::5efe:192.168.1.100%2 > > > Default Gateway . . . . . . . . . : > > > > > > E:\UserData\Dennis Lee Bieber\My Documents> > > > END of captured output > > > START of captured output > > > dir > > > Volume in drive E is Data > > > Volume Serial Number is 2626-D991 > > > > > > Directory of E:\UserData\Dennis Lee Bieber\My Documents > > > > > > 10/24/2005 09:23 AM > > > . > > > 10/24/2005 09:23 AM > > > .. > > > 07/25/2005 10:39 PM > > > .metadata > > > 10/06/2005 09:54 AM > > > Ada Progs > > > 08/13/2005 02:01 PM > > > Agent Data > > > 10/21/2005 09:29 AM 421,820 apress_offer.pdf > > > 07/03/2005 11:36 AM 132 cp.py > > > 07/17/2005 12:25 PM > > > Cyberlink > > > 07/06/2005 09:32 AM 102,400 db1.mdb > > > 07/26/2005 12:20 AM26,614 eclipse_code.xml > > > 10/24/2005 01:08 AM > > > Eudora > > > 06/24/2005 08:50 PM 667 fake_oosums.ads > > > 06/24/2005 08:50 PM 695 fake_oosums.ali > > > 09/06/2005 09:01 PM > > > Genealogy > > > 07/13/2005 10:56 PM
Re: Read/Write from/to a process
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. 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. I modified the original suggestion so it would update the prompt, in case the user did a "cd.." ..which works fine now. However, if a user tries to do, "del tmp123" ...windows prompts for a "are you sure you want to delete... Y/N?" ...so the code hangs. I can't believe no one else has done this yet..or if they have, it hasn't been widely discussed. Any other suggestions? -- http://mail.python.org/mailman/listinfo/python-list
Re: Read/Write from/to a process
jas wrote: > 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. > > 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. > > I modified the original suggestion so it would update the prompt, in > case the user did a "cd.." ..which works fine now. However, if a user > tries to do, "del tmp123" ...windows prompts for a "are you sure you > want to delete... Y/N?" ...so the code hangs. > > I can't believe no one else has done this yet..or if they have, it > hasn't been widely discussed. > > Any other suggestions? > Look at how you might do it in other languages. Then you'll realise this isn't (just) a Python problem. regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC www.holdenweb.com PyCon TX 2006 www.python.org/pycon/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Read/Write from/to a process
Steve Holden wrote: > Look at how you might do it in other languages. Then you'll realise this > isn't (just) a Python problem. Yea your right. However, for example, in Java, one can use the Process class, and then read from the stream until its the end (i.e. -1 is returned). However, with Python when reading from subprocess.Popen.stdout ...I don't know when to stop (except for looking for a ">" or something). Is there a standard, like read until "-1" or something? As I mentioned, os.system("cmd") gives me exactly the output/interactivity I need...but I can't redirect the output. Thanks. -- http://mail.python.org/mailman/listinfo/python-list
Re: Read/Write from/to a process
Jas, I use a python called twisted to run processes as you describe. Twisted is an event-driven framework that brings a change in the way that you look at things. take a look at: http://twistedmatrix.com/projects/core/documentation/howto/process.html Good luck, hope this is useful, Mike jas wrote: > Hi, > I would like to start a new process and be able to read/write from/to > it. I have tried things like... > > import subprocess as sp > p = sp.Popen("cmd.exe", stdout=sp.PIPE) > p.stdin.write("hostname\n") > > however, it doesn't seem to work. I think the cmd.exe is catching it. > > I also tried > f = open("out.txt", "w") > sys.stdout = f > os.system("cmd.exe") > > ..but out.txt didn't contain any output from cmd.exe > > So, how can I create a process (in this case, cmd.exe) on Windows and > be able to read/write from/to it? > > Thanks > -- The greatest performance improvement occurs on the transition of from the non-working state to the working state. -- http://mail.python.org/mailman/listinfo/python-list
Re: Read/Write from/to a process
Quoth "jas" <[EMAIL PROTECTED]>: | Steve Holden wrote: |> Look at how you might do it in other languages. Then you'll realise this |> isn't (just) a Python problem. | | Yea your right. However, for example, in Java, one can use the Process | class, and then read from the stream until its the end (i.e. -1 is | returned). However, with Python when reading from | subprocess.Popen.stdout ...I don't know when to stop (except for | looking for a ">" or something). Is there a standard, like read until | "-1" or something? Sure, end of file is '', a string with 0 bytes. That means the other end of the pipe has closed, usually due to exit of the other process that was writing to it. Not much help for you there, nor would the Java equivalent be, I presume. Even on UNIX, where pipes are a mainstay of ordinary applications, this one would very likely need a pseudotty device instead, to prevent C library block buffering, and it would still be difficult and unreliable. Ironically the best support I've seen came from a platform that didn't use pipes much at all, VAX/VMS (I put that in the past tense because for all I know it may have evolved in this respect.) The pipe-like VMS device was called a "mailbox", and the interesting feature was that you could be notified when a read had been queued on the device. Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: Read/Write from/to a process
I have setup multiple threads and a queue...which is working pretty good. But I have one other issue...I have a new thread (since it is different issue) here: http://groups.google.com/group/comp.lang.python/browse_frm/thread/ec81d8982d1a0130 if you get chance, would you mind checking that out. Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: Read/Write from/to a process
I have setup multiple threads and a queue...which is working pretty good. But I have one other issue...I have a new thread (since it is different issue) here: http://groups.google.com/group/comp.lang.python/browse_frm/thread/ec81d8982d1a0130 if you get chance, would you mind checking that out. Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: Read/Write from/to a process
Dennis Lee Bieber <[EMAIL PROTECTED]> writes: > Followed by the Amiga... The Amiga IPC used "message ports" (linked > lists owned by the creating process to which, if "public" [named], other > processes could send message packets). The Amiga port of REXX made use > of message ports as its native IPC... > > address SOME_APPLICATION > > would redirect all "non-REXX" statements to the message port named > "SOME_APPLICATION"; the default being "address COMMAND" -- a shell > interpreter. Then, any non-REXX statement would be processed by the > shell interpreter -- and the easiest way to force a non-REXX statement > was to put a quote mark around it (or the first word of it) > > "delete" my_file_var > > would translate my_file_var to whatever had been assigned to it earlier, > and pass a delete command to the shell. > > address ED > > would now route such statements to the "ed" editor These things weren't unique to the Amiga port of Rexx. Rexx on VM/CMS did all these things. Tying them to the native IPC mechanism as a brilliant move. Add in the shared library for supporting Rexx so that adding Rexx support to an application (or to a language!) was trivial, and Rexx the end result was that Rexx was used far more heavily on the Amiga than on VM/CMS. The downside was that variables had a default value of their name in upper case, and any statement that wasn't recognized evaluated as a string expresion and then fed to the current command processor. So that the quote marks weren't needed - if you hadn't assigned a value to the variable delete, then you could just do delete my_file_var and it would do the right thing. Of course, almost anything you typed like that was valid, creating interesting bugs. I made it a habit to keep "0" and "1" commands around that just logged errors, as those would catch such things. http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: Read/Write from/to a process
On Tue, 25 Oct 2005 17:32:28 GMT, Dennis Lee Bieber <[EMAIL PROTECTED]> wrote: >On 25 Oct 2005 05:22:20 -0700, "jas" <[EMAIL PROTECTED]> 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 p