Redirection Issues on Windows MS-DOS Applications

'

Spawn Console Processes with Redirected Standard Handles

Due to implementation differences on the Microsoft Windows 95, Windows 98, and Microsoft Windows NT platforms, programs need an intermediate Win32 Console Application to successfully redirect the output of 16-bit console based applications (MS-DOS applications and batch files) on Windows 95 and Windows 98.

On Windows 95 and Windows 98 programs can exhibit blocking when using the ReadFile() API to read from the redirected handles of 16-bit console based applications (including console based MS-DOS applications and batch files.) In this situation ReadFile() remains blocked even after the redirected 16-bit console based application has terminated.

Programs can avoid this blocking situation by launching an intermediate Win32 Console application as a stub process between the Win32 parent and the 16-bit console based child. The creation of the stub application results in a Win32 console. The stub application then spawns the 16-bit console based application in the same console, forwarding it's redirected standard handles. As a result, the 16-bit console based application inherits the hidden console and the redirected standard handles.

{$APPTYPE CONSOLE}
{*++
         Description:

            Serves as an intermediate stub Win32 console application to
            avoid a hanging pipe when redirecting 16-bit console based
            programs (including MS-DOS console based programs and batch
            files) on Window 95 and Windows 98.
            This program is to be launched with redirected standard
            handles. It will launch the command line specified 16-bit
            console based application in the same console, forwarding
            it's own redirected standard handles to the 16-bit child.

--*}    

uses
 Windows;

var
   bRet : boolean;
   si : STARTUPINFO;
   pi : PROCESS_INFORMATION;

begin

   // Make child process use this app's standard files.
   si.cb := sizeof(si);
   si.dwFlags    := STARTF_USESTDHANDLES;
   si.hStdInput  := GetStdHandle (STD_INPUT_HANDLE);
   si.hStdOutput := GetStdHandle (STD_OUTPUT_HANDLE);
   si.hStdError  := GetStdHandle (STD_ERROR_HANDLE);

   bRet := CreateProcess (nil, PChar(paramstr(1)),
                         nil, nil,
                         TRUE, 0,
                         nil, nil,
                         si, pi
                         );
   if (bRet) then
   begin
      WaitForSingleObject (pi.hProcess, INFINITE);
      CloseHandle (pi.hProcess);
      CloseHandle (pi.hThread);
   end;
end. 

This tutorial was kindly provided by Serge Perevoznyk


Google
Web www.Delphi-Central.com
Delphi Central - Delphi Programming Tutorials, Hints and Tips