Using windows command line from Pascal

Posted by Jordan on Stack Overflow See other posts from Stack Overflow or by Jordan
Published on 2010-05-04T00:36:36Z Indexed on 2010/05/04 0:38 UTC
Read the original article Hit count: 679

Filed under:

I'm trying to use some windows command line tools from within a short Pascal program. To make it easier, I'm writing a function called DoShell which takes a command line string as an argument and returns a record type called ShellResult, with one field for the process's exitcode and one field for the process's output text.

I'm having major problems with some standard library functions not working as expected. The DOS Exec() function is not actually carrying out the command i pass to it. The Reset() procedure gives me a runtime error RunError(2) unless i set the compiler mode {I-}. In that case i get no runtime error, but the Readln() functions that i use on that file afterwards don't actually read anything, and furthermore the Writeln() functions used after that point in the code execution do nothing as well.

Here's the source code of my program so far. I'm using Lazarus 0.9.28.2 beta, with Free Pascal Compiler 2.24


program project1;

{$mode objfpc}{$H+}

uses
  Classes, SysUtils, StrUtils, Dos
  { you can add units after this };

{$IFDEF WINDOWS}{$R project1.rc}{$ENDIF}

type
  ShellResult = record
    output    : AnsiString;
    exitcode  : Integer;
  end;

function DoShell(command: AnsiString): ShellResult;
    var
      exitcode: Integer;
      output: AnsiString;
      exepath: AnsiString;
      exeargs: AnsiString;
      splitat: Integer;
      F: Text;
      readbuffer: AnsiString;
    begin
      //Initialize variables
      exitcode   := 0;
      output     := '';
      exepath    := '';
      exeargs    := '';
      splitat    := 0;
      readbuffer := '';
      Result.exitcode := 0;
      Result.output   := '';

      //Split command for processing
      splitat := NPos(' ', command, 1);
      exepath := Copy(command, 1, Pred(splitat));
      exeargs := Copy(command, Succ(splitat), Length(command));

      //Run command and put output in temporary file
      Exec(FExpand(exepath), exeargs + ' >__output');
      exitcode := DosExitCode();

      //Get output from file
      Assign(F, '__output');
      Reset(F);
      Repeat
        Readln(F, readbuffer);
        output := output + readbuffer;
        readbuffer := '';
      Until Eof(F);

      //Set Result
      Result.exitcode := exitcode;
      Result.output   := output;

    end;

var
  I : AnsiString;
  R : ShellResult;
begin
  Writeln('Enter a command line to run.');
  Readln(I);
  R := DoShell(I);
  Writeln('Command Exit Code:');
  Writeln(R.exitcode);
  Writeln('Command Output:');
  Writeln(R.output);
end.

© Stack Overflow or respective owner

Related posts about pascal