Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[13859] Re:RunDosCommand 인데 출력결과가 깨집니다.
오랑캐꽃 [oranke] 2744 읽음    2011-10-11 14:45
콘솔모드 입출력 함수들은 유니코드를 지원하지 않습니다.
여기서 오고가는 문자열은 모두 안시문자열입니다.
(커맨드 명령어 중 CHCP 가 존재하는 이유가 그것 때문입죠.)

김성동님의 팁에서 캡쳐된 문자열 또한 당연히 유니코드가 아닌 안시 바이트 배열입니다.
델 2010은 (써본적은 없지만) String 이 유니코드 문자열이므로 버퍼로 사용되는 변수를
안시 문자열을 변경해주어야 합니다.

김성동님의 코드를 약간 수정한 녀석이 있으니 한 번 써보세요.
http://oranke.tistory.com/133
특별히 델 2010용으로 만든 건 아니지만 AnsiString 을 의식적으로 사용했으니 무리없이 동작할 껍니다.

이렇게 얻어낸 AnsiString 을 델파이의 유니코드로 가져올 때는, 뭐 그냥 대입하면 됩니다만
콘솔 코드페이지를 시스템 기본값이 아닌 상태로 쓰는 사람도 분명히 있으니... (누굴까...)
기왕이면 GetConsoleOutputCP() 로 얻어낸 코드페이지를 써서 MultiByteToWideChar() 로
변환하면 어느나라 어떤 미친놈을 만나건 문제없는 코드가 되겠습니다.

MultiByteToWideChar(), WideCharToMultiByte() 사용법은 다음 글을 참고하시구요...
http://oranke.tistory.com/14

위 글 말미에도 적었지만, 델 2006 이상에서는 System.SetMultiByteConversionCodePage() 함수를 쓰면
안시 <-> 와이드 문자열 변환시 참조되는 코드페이지를 설정할 수 있습니다.
다만 UTF-8은 직접 만져주셔야 해요~ ^^;



이정우 님이 쓰신 글 :
: WinXP환경에서 델파이 2010을 사용하고 있습니다.
:
:
: http://www.acrosoft.pe.kr/board/?mid=cg_tips&search_target=title&document_srl=24088
: 위 링크에 있는 소스그대로 사용했는데요.
:
:
: 결과가
: 펼쿇솷븠맆₫냅ꪳ될뢩붣뷊뿃⃀‮‮‮਍਍㩅䍜䑟噒륜엙죁뢭峩�횼�僚쏇>
: 이렇게 깨져서 보입니다.
:
:
:
: 제가 뭘 잘못한건가요?
:
:
: procedure TForm1.RunDosCommand(Command : string; Output : TMemo);
: 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;
: UsingWinNT : boolean;
: begin { Dos Application }
:
: UsingWinNT := true;
:
: 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);
: // 원본에 버그 있음 버퍼 크기를 넘어가는 경우가 생김 : 수정
:      ReadFile(hReadPipe, Dest, sizeof(Dest) -1, BytesRead, nil);
:
:      TmpList.Text := StrPas(Dest);
:       Output.Lines.AddStrings(TmpList);
:      finally
:       TmpList.Free;
:      end;
:     end;
:    end; // end of peek
:
:    { WAIT_TIMEOUT이 아니면 루프를 마친다. }
:    if wrResult <> WAIT_TIMEOUT then
:    ExitCode := 1;
:   end; // while
:
:   { 실행이 끝났다.. }
:   GetExitCodeProcess(PI.hProcess, ExitCode);
:   CloseHandle(PI.hProcess);
:   CloseHandle(PI.hThread);
: end;  // if
: finally
: CloseHandle(hReadPipe);
: CloseHandle(hWritePipe);
: Screen.Cursor := crDefault;
: end;
: end;

+ -

관련 글 리스트
13849 RunDosCommand 인데 출력결과가 깨집니다. 이정우 1967 2011/10/04
13859     Re:RunDosCommand 인데 출력결과가 깨집니다. 오랑캐꽃 2744 2011/10/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.