短い Pascal プログラム内からいくつかの Windows コマンド ライン ツールを使用しようとしています。簡単にするために、コマンド ライン文字列を引数として受け取り、プロセスの終了コード用の 1 つのフィールドとプロセスの出力テキスト用の 1 つのフィールドを持つ、ShellResult というレコード タイプを返す DoShell という関数を作成しています。
一部の標準ライブラリ関数が期待どおりに機能しないという大きな問題があります。DOS Exec() 関数は、私が渡したコマンドを実際には実行していません。コンパイラ モード {I-} を設定しない限り、Reset() プロシージャで実行時エラー RunError(2) が発生します。その場合、実行時エラーは発生しませんが、後でそのファイルで使用する Readln() 関数は実際には何も読み取らず、さらにコード実行のその時点以降に使用される Writeln() 関数も何もしません。
これまでの私のプログラムのソースコードです。私は Lazarus 0.9.28.2 beta と 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.