Q&A

  • 2000에서 pipe가 왜 안먹힐까요..
아래 소스 코드 보신 분들 많으실겁니다.

도스 프로그램을 실행시키고, 그 출력 결과를 pipe를 통해 가져오는 프로그램입니다.

그런데 윈98 같은데서 실행시키면 잘 되는데, 2000에서 실행시키면 잘 동작 안합니다.

도스 프로그램도 문제없이 실행되고, 도스창 화면에도 출력 결과가 안찍히는데(pipe로 redirection되서요), pipe에 출력 결과가 들어가지를 않습니다.

결론적으로 2000에서 작동안합니다.-_-

왜 그런지 아시는 분 답변 부탁드립니다.



procedure RunDosCommand(Command : string; Output : TStrings);

var

hReadPipe : THandle;

hWritePipe : THandle;

SI : TStartUpInfo;

PI : TProcessInformation;

SA : TSecurityAttributes;

SD : TSecurityDescriptor;

BytesRead : DWORD;

Dest : array[0..1023] of char;

CmdLine : array[0..512] of char;

TmpList : TStringList;

S, Param : string;

Avail, ExitCode, wrResult : DWORD;



begin { Dos Application }

if UsingWinNT then

begin

InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION);

SetSecurityDescriptorDacl(@SD, True, nil, False);

SA.nLength := SizeOf(SA);

SA.lpSecurityDescriptor := @SD;

SA.bInheritHandle := True;

CreatePipe(hReadPipe, hWritePipe, @SA, 1024);

end else

CreatePipe(hReadPipe, hWritePipe, nil, 1024);

try

Screen.Cursor := crHourglass; { STARTUPINFO를 설정한다. }

FillChar(SI, SizeOf(SI), 0);

SI.cb := SizeOf(TStartUpInfo);

SI.wShowWindow := SW_HIDE;

SI.dwFlags := STARTF_USESHOWWINDOW; { STARTF_USESTDHANDLES 를 빼면 PIPE로 입출력이 Redirect 되지 않는다. }

SI.dwFlags := SI.dwFlags or STARTF_USESTDHANDLES;

SI.hStdOutput := hWritePipe;

SI.hStdError := hWritePipe;

StrPCopy(CmdLine, Command); { Process를 생성한다. }

if CreateProcess(nil, CmdLine, nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then

begin

ExitCode := 0;

while ExitCode = 0 do

begin

wrResult := WaitForSingleObject(PI.hProcess, 500);

{ Pipe에 출력된 내용이 있는 지 조사한다. }

if PeekNamedPipe(hReadPipe, nil, 0, nil, @Avail, nil) then

begin

if Avail > 0 then

begin

{ Redirect된 화면 내용을 출력 윈도에 내보낸다. }

TmpList := TStringList.Create;

try

FillChar(Dest, SizeOf(Dest), 0);

ReadFile(hReadPipe, Dest, Avail, BytesRead, nil);

TmpList.Text := StrPas(Dest);

Output.Lines.AddStrings(TmpList);

finally

TmpList.Free;

end;

end;

end;

{ WAIT_TIMEOUT이 아니면 루프를 마친다. }

if wrResult <> WAIT_TIMEOUT then

ExitCode := 1;

end;

{ 실행이 끝났다.. }

GetExitCodeProcess(PI.hProcess, ExitCode);

CloseHandle(PI.hProcess);

CloseHandle(PI.hThread);

end;

finally

CloseHandle(hReadPipe);

CloseHandle(hWritePipe);

Screen.Cursor := crDefault;

end;

end;



0  COMMENTS