Q&A

  • 도스출력 바로바로 잡아오기
c로짠 프로그램이 도스창에 출력할때 델파이프로그램이 캣치하는 소스를

델파이 팁/강좌에서 찾았습니다.

그런데 내용을 잘모르겠습니다.

밑에있는 소스는 델파이코든데 c에서는 어떻게 틀리는지

어디에다 코딩을 해야할지 모르겠네요.



>김성동님의 홈에서 퍼왔습니다~

>

>도스 프롬프트에서처럼 Redirect 명령을 이용해서 파일로 저장한 다음 그 파일을 읽어

>들이는 방법이 제일 쉽죠. 짐작하시겠지만 이 방법은 작업이 다 끝나야지만 출력을 볼 >수 있다는 문제가 있죠..

>또 다른 방법은 파이프를 이용하는겁니다.

>CreateProcess 함수의 인자 중 TStartUpInfo 구조체의 hStdOutput, hStdError 핸들에 >CreatePipe 함수로 생성된 WritePipe를 인자로 넣어주면 해당 명령의 출력이 이 Pipe

>로 Redirect됩니다. 그럼 ReadFile 함수의 파일 핸들을 ReadPipe로 해서 읽어들이면 읽>어 들이면 됩니다.

>자세한 건 아래 소스를 보시면 이해하실겁니다.





>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