|
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
|