AtEndOfStream Property (Windows Script Host)

Switch View :
ScriptFree
Windows Script Host
AtEndOfStream Property (Windows Script Host)

Returns a Boolean value indicating whether the end of an input stream has been reached.


                      object.AtEndOfStream 
Arguments

object

StdIn text stream object.

Remarks

The AtEndOfStream property contains a Boolean value indicating whether the end of an input stream has been reached. The AtEndOfStream property returns True if the stream pointer is at the end of an input stream, False if not. The StdIn, StdOut, and StdErr properties and methods work only when the script is run with CScript.exe. If the script is run with WScript.exe, an error occurs.

Example

The following code samples demonstrate the AtEndOfStream property by reading a standard directory listing from "dir", stripping the top and bottom lines that aren't actual entries, and double spacing the directory entries.

VBScript
Dim StdIn, StdOut, Str1, Str2

Set StdIn = WScript.StdIn
Set StdOut = WScript.StdOut

Str1 = ""
Str2 = ""For i = 0 to 4 
   StdIn.SkipLine
Next

i = 0
Do While Not StdIn.AtEndOfStream
     If i >= 2 Then
          StdOut.WriteLine Str1
     End If
     i = i + 1
     Str1 = Str2
     Str2 = StdIn.ReadLine
Loop
JScript
var stdin = WScript.StdIn;
var stdout = WScript.StdOut;
var str1, str2 = "";
var i;
for (i = 0; i < 5; i++)
     stdin.SkipLine();
i = 0;
while (!stdin.AtEndOfStream)
{
     if (i++ >= 2)
     {
          stdout.WriteLine(str1);
     }
     str1 = str2;
     str2 = stdin.ReadLine();
}

See Also

Reference

Other Resources

Community Content

Benhaha
BUG: AtEndOfStream blocks if nothing has been written

Ref http://www.codecomments.com/archive300-2004-10-298223.html helpful comments by Michael Harris
Microsoft.MVP.Scripting and kmashint of that forum.

WScriptExec.StdErr.AtEndOfStream (and I think also Read,ReadLine and ReadAll) will block if nothing has yet been written to the stream. If the called process then writes more than about 4KB to StdOut then the application will hang, because the called process will block waiting for the caller to read from StdOut, and the caller will block waiting for the Called process to write to StdErr.

The following workarounds are suggested there by kmashint of that forum (not tested by me - yet. I'll see if they work soon though.).

Workaround 1: Redirect StdErr to StdIn by appending " 2>&1" to the end of the command line. This will work provided you don't need them separate. Then you can ignore StdErr and read from StdOut instead.

If your command line is cmdLine, then (JScript):

var oExec = WScript.Exec("CMD /c " + cmdLine + " 2>&1");
// Might need this if program tries to read StdIn
// oExec.StdIn.Close();
var strStdOut = oExec.ReadAll();
var iExitCode = oExec.ExitCode();

Workaround 2: Redirect StdErr to a temporary file " 2>tmp12345_err.log" or similar. Remember to ensure a unique name and delete the file when finished. If you need to know what has been written part way through you can open it as a text file with OpenTextStream.
Once again it is

var oExec = WScript.Exec("CMD /c " + cmdLine + " 2>tmp12345_err.log");

If you do this with StdOut and StdErr both, you can keep checking the file size which may allow you to work interactively with the called program.

Fix: Create a new method ReadTimeout(int nCharsToRead, int nMillisecondsToWait) which returns after the number of bytes has been read or the timeout occurs, whichever is first. Could implement using overlapped ReadFile, WaitForSingleObject and CancelIO.


Benhaha
How is the behaviour defined?
Does AtEndOfStream tell you if there is anything to read right now, or does it just tell you when the stream is closed?

Does the behaviour differ on the WScriptExec StdOut/StdIn/StdErr objects? They are not mentioned in the documentation for AtEndOfStream.

There seems to be a problem when reading unpredictable amounts from a WScriptExec object's StdOut and StdErr because it only buffers a limited amount.

This makes it hard to tell how much you need to read from each of StdErr and StdOut to avoid the blocking whilst simultaneously avoiding the exec'd process blocking on writing to stderr and stdout.