아래 소스 코드 보신 분들 많으실겁니다.
도스 프로그램을 실행시키고, 그 출력 결과를 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;