お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"Delphi用popen/pclose"



 Win32APIのマニュアルを参考に、名前なしパイプを使って、UNIXでいうところのpope
n/pcloseを作ってみました。
 試作なのでオブジェクト化とかはしていないのですが、外部プログラムの出力を読み
取るプログラムの作成にどうぞ。

,

unit pipe;

interface

uses Windows,Classes, TestUnit;

type
  TPipe = record
    stdin: THandleStream;   // 子プロセスのstdin(これに書きこむ)
    stdout: THandleStream;  // 子プロセスのstdout(これを読みこむ)
  end;
  TPipeAccess = set of (read, write);

function popen( command: String; access: TPipeAccess): TPipe;
procedure pclose( pipeHandle: TPipe);

var
  saAttr: TSecurityAttributes;
  hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
  hChildStdoutRd, hChildStdoutWr,
  hSaveStdin, hSaveStdout: THandle;

implementation

function popen( command: String; access: TPipeAccess): TPipe;
var
  piProcInfo: TProcessInformation;
  siStartInfo: TStartupInfo;
begin

  saAttr.nLength := sizeof( TSecurityAttributes);
  saAttr.bInheritHandle := True;
  saAttr.lpSecurityDescriptor := nil;

  if read in access then
  begin
    hSaveStdout := GetStdHandle(STD_OUTPUT_HANDLE);
    if not CreatePipe( hChildStdoutRd, hChildStdoutWr, @saAttr, 4) then
      {Error};
    if not SetStdHandle( STD_OUTPUT_HANDLE, hChildStdoutWr) then
      {Error};
    result.stdout:=THandleStream.Create(hChildStdoutRd)
  end;

  if write in access then
  begin
    hSaveStdin := GetStdHandle( STD_INPUT_HANDLE );

    if not CreatePipe( hChildStdinRd, hChildStdinWr, @saAttr, 4) then
      {Error};

    if not SetStdHandle( STD_INPUT_HANDLE, hChildStdinRd) then
      {Error};

    if not DuplicateHandle( GetCurrentProcess, hChildStdinWr,
        GetCurrentProcess, @hChildStdinWrDup, 0,
        False, {/* not inherited */}
        DUPLICATE_SAME_ACCESS) then
      {Error};

    CloseHandle(hChildStdinWr);
    result.stdin := THandleStream.Create(hChildStdinWrDup);
  end;


  with siStartInfo do
  begin
    cb := sizeof(TStartupInfo);
    lpReserved := nil;
    lpReserved2 := nil;
    cbReserved2 := 0;
    lpDesktop := nil;
    dwFlags := 0;
  end;

  if not CreateProcess( nil, PChar(command), nil, nil, TRUE, 0, nil, nil,
      siStartInfo, piProcInfo) then
    {Error};

  if write in access then
    if not SetStdHandle( STD_INPUT_HANDLE, hSaveStdin) then
      {Error};

  if read in access then
  if not SetStdHandle( STD_OUTPUT_HANDLE, hSaveStdout) then
    {Error};
  CloseHandle( hChildStdoutWr);
end;

procedure pclose( pipeHandle: TPipe);
var
  hIn, hOut: THandle;
begin
  with pipeHandle do
  begin
    hIn:=stdin.Handle;
    hOut:=stdout.Handle;
    if stdin<>nil then
      stdin.Free;
    if stdout<>nil then
      stdout.Free;
    if hIn<>0 then
      CloseHandle(hIn);
    if hOut<>0 then
      CloseHandle(hOut);
  end;
end;

end.


    Black-HIRAKU(PEA01550)

Original document by Black-HIRAKU    氏 ID:(PEA01550)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum