Working With Console StdIn and StdOut Streams

Applies to TestComplete 14.10, last modified on June 5, 2019

TestComplete provides several approaches that you can use to interact with console windows’ output. For instance, you can use the wText property of the corresponding Window object (for more information on this approach, see Interacting With Console Windows). However, the wText property implements single access to a console window’s text. But when working with console applications, you may need to work with them in interactive mode, that is send commands to the console and receive responses from them. This implies working with standard input and output streams that are associated with the console window. Standard properties and methods of the console window do not provide you with these abilities.

You can work around this by using the Windows WshShell object. It provides scripting access to the native Windows shell. WshShell object’s Exec method runs an application in a child command-shell and returns the WshScriptExec object. Its StdIn, StdOut and StdErr properties provides scripting access to StdIn, StdOut, and StdErr streams of the tested application (in the example below, the tested application is cmd.exe).

Obtaining the Console’s Output Stream

The following example runs the system console, pings the Server_name server and then reads all the data from the console’s standard output stream:

JavaScript, JScript

function CheckServerStatus()
{
  // Ping the server
  var ExecOperation = WshShell.Exec("ping Server_name.com");

  // Check the operation's status
  while (ExecOperation.Status == 0)
    Delay(100);

  // Get the operation's exit code
  var ExCode = ExecOperation.ExitCode;

  // Get the application's StdOut stream
  var StdOut = ExecOperation.StdOut;

  if (ExCode == 0)
    Log.Message("Connection succeeded", StdOut.ReadAll())
  else
    Log.Error("Server is unavailable", StdOut.ReadAll())
}

Python

def CheckServerStatus():
  # Ping the server
  ExecOperation = WshShell.Exec("ping Server_name.com");

  # Check the operation's status
  while (ExecOperation.Status == 0):
    Delay(100);

  # Get the operation's exit code
  ExCode = ExecOperation.ExitCode;

  # Get the application's StdOut stream
  StdOut = ExecOperation.StdOut;

  if (ExCode == 0):
    Log.Message("Connection succeeded", StdOut.ReadAll());
  else:
    Log.Error("Server is unavailable", StdOut.ReadAll());

VBScript

Sub CheckServerStatus

  Dim ExecOperation, ExCode, StdOut
  ' Ping the server
            Set ExecOperation = WshShell.Exec("ping Server_name.com")

  ' Check the operation's status
  While (ExecOperation.Status = 0)
    Delay(100)
  WEnd

  ' Get the operation's exit code
  ExCode = ExecOperation.ExitCode

  ' Get the application's StdOut stream
  Set StdOut = ExecOperation.StdOut

  If ExCode = 0 Then
    Call Log.Message("Connection succeeded", StdOut.ReadAll)
  Else
    Call Log.Error("Server is unavailable", StdOut.ReadAll)
  End If

End Sub

DelphiScript

function CheckServerStatus;
var
  ExecOperation, ExCode, StdOut;
begin

  // Ping the server
  ExecOperation := WshShell.Exec('ping Server_name.com');

  // Check the operation's status
  while ExecOperation.Status = 0 do
    Delay(100);

  // Get the operation's exit code
  ExCode := ExecOperation.ExitCode;

  // Get the application's StdOut stream
  StdOut := ExecOperation.StdOut;

  if ExCode = 0 then
    Log.Message('Connection succeeded', StdOut.ReadAll)
  else
    Log.Error('Server is unavailable', StdOut.ReadAll);

end;

C++Script, C#Script

function CheckServerStatus()
{
  // Ping the server
  var ExecOperation = WshShell["Exec"]("ping Server_name.com");

  // Check the operation's status
  while (ExecOperation["Status"] == 0)
    Delay(100);

  // Get the operation's exit code
  var ExCode = ExecOperation["ExitCode"];

  // Get the application's StdOut stream
  var StdOut = ExecOperation["StdOut"];

  if (ExCode == 0)
    Log["Message"]("Connection succeeded", StdOut["ReadAll"]())
  else
    Log["Error"]("Server is unavailable", StdOut["ReadAll"]())
}

Writing Text to the Console’s Input Stream

The following code example runs the system console, writes the "ver" command to the console’s input stream and then reads all of the data from the standard output stream:

JavaScript, JScript

function Main()
{
   var WshShellExecObj = WshShell.Exec("cmd.exe");

   // Flush the stream
   var out = readTillChar(WshShellExecObj, ">");
   Log.Message(out);

   // Send the "ver" command and the new line character
   WshShellExecObj.StdIn.Write("ver\n");
   out = readTillChar(WshShellExecObj, ">");
   Log.Message(out);
}

function readTillChar(WshShellExecObj, endChar)
{
   var out = "";
   var curChar;
   while (!WshShellExecObj.StdOut.AtEndOfStream)
   {
     curChar = WshShellExecObj.StdOut.Read(1);
     out += curChar;
     if (curChar == endChar) break;
   }
   return out;
}

Python

def Main():
  WshShellExecObj = WshShell.Exec("cmd.exe");

  # Flush the stream 
  outs = readTillChar(WshShellExecObj, ">");
  Log.Message(outs);
  
  # send the "ver" command and the new line character
  WshShellExecObj.StdIn.Write("ver\n");
  outs = readTillChar(WshShellExecObj, ">"); 
  Log.Message(outs);

def readTillChar(WshShellExecObj, endChar):
  while not WshShellExecObj.StdOut.AtEndOfStream:
    curChar = WshShellExecObj.StdOut.Read(1);
    outs = outs + curChar;
    if (curChar == endChar):
      Result = outs;
   break;

VBScript

Sub Main
  Dim WshShellExecObj, out

  Set WshShellExecObj = WshShell.Exec("cmd.exe")

  ' Flush the stream
  out = readTillChar(WshShellExecObj, ">")
  Log.Message(out)
  
  ' Send the "ver" command and the new line character
  WshShellExecObj.StdIn.Write("ver" + VbCrLf)
  out = readTillChar(WshShellExecObj, ">")
  Log.Message(out)
End Sub

Function readTillChar(WshShellExecObj, endChar)
  Dim out, curChar
  
  Do While Not WshShellExecObj.StdOut.AtEndOfStream
    curChar = WshShellExecObj.StdOut.Read(1)
    out = out + curChar
    If curChar = endChar Then
      readTillChar = out
      Exit Function
    End If
  Loop
End Function

DelphiScript

function readTillChar(WshShellExecObj, endChar); forward;

procedure Main;
var WshShellExecObj, outs;
begin
  WshShellExecObj := WshShell.Exec('cmd.exe');

  // Flush the stream
  outs := readTillChar(WshShellExecObj, '>');
  Log.Message(outs);
  
  // send the "ver" command and the new line character
  WshShellExecObj.StdIn.Write('ver'+ #13#10);
  outs := readTillChar(WshShellExecObj, '>');
  Log.Message(outs);
end;

function readTillChar(WshShellExecObj, endChar);
var
  outs, curChar: OleVariant;
begin
  while not WshShellExecObj.StdOut.AtEndOfStream do
  begin
   curChar := WshShellExecObj.StdOut.Read(1);
   outs := outs + curChar;
   if curChar = endChar then
   begin
   Result := outs;
   break;
   end;
  end;
end;

C++Script, C#Script

function Main()
{
   var WshShellExecObj = WshShell["Exec"]("cmd.exe");

   // Flush the stream
   var out = readTillChar(WshShellExecObj, ">");
   Log.Message(out);

   // Send the "ver" command and the new line character
   WshShellExecObj["StdIn"]["Write"]("ver\n");
   out = readTillChar(WshShellExecObj, ">");
   Log.Message(out);
}

function readTillChar(WshShellExecObj, endChar)
{
   var out = "";
   var curChar;
   while (!WshShellExecObj["StdOut"]["AtEndOfStream"])
   {
     curChar = WshShellExecObj["StdOut"]["Read"](1);
     out += curChar;
     if (curChar == endChar) break;
   }
   return out;
}

See Also

Testing Console Applications - Overview
Interacting With Console Windows

Highlight search results