{ From: Matthew.Mastracci@matrix.cpubbs.cuug.ab.ca (Matthew Mastracci) tf> A simple example: tf> SwapVectors; tf> Exec (GetEnv('comspec'), '/c dir *.* > FileName'); tf> SwapVectors; This is a good way to do redirection for directory listings and the like, but a better way is to use this unit: (I wrote it from an idea given to me by someone else posting the same sort of this, except this one includes error checking and containm much more useful procedures) From this, you can go: SwapVectors; RedirectOutput('\DIRLIST.TXT'); Exec(GetEnv('COMSPEC'), '/C DIR *.*'); StdOutput; SwapVectors; Same thing, but more control... Here's my REDIR.PAS unit: Redirection unit - Original author unknown, rewritten by Matthew Mastracci - Added a bit of asm, pipe support, some better file handling ability, more flexibility - If you'd like some information on this program, E-Mail me at: madhacker@matrix.cpubbs.cuug.ab.ca - Feel free to distribute this source anywhere! (Public Domain) } unit Redir; interface { Redirects standard input from a textfile/device ie: command < filename } procedure RedirectInput(TextFile : String); { Redirects standard output to a textfile/device ie: command > filename } procedure RedirectOutput(TextFile : String); { Redirects standard error to a textfile/device } procedure RedirectError(TextFile : String); { Redirects standard output and error to a textfile/device } procedure RedirectAllOutput(TextFile : String); { Redirects all I/O from a textfile ie: ctty device } procedure RedirectAll(TextFile : String); { Restores STDIN to CON } procedure StdInput; { Restores STDOUT to CON } procedure StdOutput; { Restores STDERR to CON } procedure StdError; { Creates a unique file and returns its name (used for piping) } function UniqueFile : String; implementation uses Dos; var InFile, OutFile, ErrFile : Text; const STDIN = 0; { Standard Input } STDOUT = 1; { Standard Output } STDERR = 2; { Standard Error } Redirected : array[0..2] of Boolean = (False, False, False); { Duplicates a file handle } procedure ForceDup (Existing, Second : Word); var f, Error : Word; begin asm mov ah, $46 mov bx, Existing mov cx, Second int $21 pushf pop bx mov f, bx mov Error, ax end; if (f and FCarry) <> 0 then Writeln ('Error ', Error, ' changing handle ', Second); end; { Redirects standard input from a textfile/device ie: command < filename } procedure RedirectInput(TextFile : String); begin if Redirected[STDIN] then StdInput; Redirected[STDIN] := True; Assign(InFile, TextFile); Reset(InFile); ForceDup(TextRec(InFile).Handle, STDIN); end; { Redirects standard output to a textfile/device ie: command > filename } procedure RedirectOutput(TextFile : String); begin if Redirected[STDOUT] then StdOutput; Redirected[STDOUT] := True; Assign(OutFile, TextFile); Rewrite(OutFile); ForceDup(TextRec(OutFile).Handle, STDOUT); end; { Redirects standard error to a textfile/device } procedure RedirectError(TextFile : String); begin if Redirected[STDERR] then StdError; Redirected[STDERR] := True; Assign(ErrFile, TextFile); Rewrite(ErrFile); ForceDup(TextRec(ErrFile).Handle, STDERR); end; { Redirects standard output and error to a textfile/device } procedure RedirectAllOutput(TextFile : String); begin RedirectOutput(TextFile); RedirectError(TextFile); end; { Redirects all I/O from a textfile ie: ctty device } procedure RedirectAll(TextFile : String); begin RedirectInput(TextFile); RedirectOutput(TextFile); RedirectError(TextFile); end; { Restores STDIN to CON } procedure StdInput; begin if Redirected[STDIN] then begin Redirected[STDIN] := False; RedirectInput('CON'); Close(InFile); end; end; { Restores STDOUT to CON } procedure StdOutput; begin if Redirected[STDOUT] then begin Redirected[STDOUT] := False; RedirectOutput('CON'); Close(OutFile); end; end; { Restores STDERR to CON } procedure StdError; begin if Redirected[STDERR] then begin Redirected[STDERR] := False; RedirectOutput('CON'); Close(OutFile); end; end; function UniqueFile : String; const FName : array[1..20] of Char = '\' + #0 + ' '; var FSeg, FOfs : Word; FileName : String; begin FSeg := Seg(FName); FOfs := Ofs(FName) + 1; asm push ds mov ax, FSeg mov ds, ax mov dx, FOfs mov ah, $5a mov cx, 0 int $21 pop ds end; Move(FName, FileName[1], 9); FileName[0] := #9; UniqueFile := FileName; end; end. { This is how you can do piping. It is equivilent to: } { type \autoexec.bat | find "ECHO" | sort /R } {$M $1000,0,0} program PipeDemo; uses Redir, Dos; var FName : String; begin FName := UniqueFile; WriteLn('Temporary file: ', FName); WriteLn('Output from pipe:'); RedirectInput('\AUTOEXEC.BAT'); RedirectOutput(FName); Exec('C:\DOS\FIND.EXE', '"ECHO"'); RedirectInput(FName); RedirectOutput('CON'); Exec('C:\DOS\SORT.EXE', '/R'); end.