매일 손으로 도스 명령을 치고 헥사값을 받아와
표를 보고 결과를 확인하는 일에 회의를 느끼고
프로그램을 한 번 만들어보고자 작심하여 Delphi를
잡은 지 어언 2개월... ㅠ.,ㅠ
고수님들. 한 수 지도 부탁드립니다.
도저히 모르겠네요.
제가 원하는 프로그램은
도스 상에 cr infpfail 이란 명령어를 입력하여
RS232 포트를 통해 기계에 신호를 보내고
이에 되돌아 오는 FF FE FF FF 와 같은 신호를
받아 그 값에 맞는 상태를 한글로 표시해 주는
프로그램을 만들어 보고자 합니다.
몇일 고생해서 RS232를 이용할 수 있는 컴포넌트를
찾아서 해보는데 잘 모르겠습니다.
고수님들의 힌트나 지도 편달 부탁드리겠습니다.
첨부된 파일은 RS232를 이용할 수 있는 컴포넌트로
Delphi 5,6 에 설치가 됩니다.
아래 소스예제는 도스명령을 보낸후 리턴값을 Memo1 에 출력해 줍니다. 그런데, OS 의 종류에 따라서 실행방법이 다른가 봅니다.
Uses Windows,classes;
...
// 도스 명령 실행 함수/프로시져
function MyF_UsingWinNT: Boolean;
var
OS: TOSVersionInfo;
begin
OS.dwOSVersionInfoSize := Sizeof(OS);
GetVersionEx(OS);
if OS.dwPlatformId = VER_PLATFORM_WIN32_NT then Result:= True
else Result:= False;
end;
// 도스 명령 실행 프로시져
procedure My_RunDosCommand(Command : string; Output : TStringList ; nShow : Boolean = False);
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
if My_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 begin
CreatePipe(hReadPipe, hWritePipe, nil, 1024);
end;
try
Screen.Cursor := crHourglass;
FillChar(SI, SizeOf(SI), 0);
SI.cb := SizeOf(TStartUpInfo);
if nShow then begin
SI.wShowWindow := SW_SHOWNORMAL
end else begin
SI.wShowWindow := SW_HIDE;
end;
SI.dwFlags := STARTF_USESHOWWINDOW;
SI.dwFlags := SI.dwFlags or STARTF_USESTDHANDLES;
SI.hStdOutput := hWritePipe;
SI.hStdError := hWritePipe;
StrPCopy(CmdLine, Command);
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);
if PeekNamedPipe(hReadPipe, nil, 0, nil, @Avail, nil) then begin
if Avail > 0 then begin
TmpList := TStringList.Create;
try
FillChar(Dest, SizeOf(Dest), 0);
ReadFile(hReadPipe, Dest, Avail, BytesRead, nil);
// Memo1.Lines.Add(Dest);
Output.Add(Dest);
finally
TmpList.Free;
end;
end;
end;
if wrResult <> WAIT_TIMEOUT then begin
ExitCode := 1;
end;
end;
GetExitCodeProcess(PI.hProcess, ExitCode);
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
end;
finally
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
Screen.Cursor := crDefault;
end;
end;
// 아래와 같이 버튼이벤트에 넣어서 사용하실수 있습니다.
// 예제는 ipconfig 란 명령을 보내서 ip 정보를 리턴받는 예제입니다.
procedure TMyForm.Button1Click(Sender: TObject);
var
S1 : TStringList;
begin
//Current PC의 현재 네트웍 상태가 Memo1에 나타나게 하는 테스트 코드입니다.
//그리고, ipconfig 명령뿐 아니라
//Command 에 사용할수 있는 모든 명령어는 다 사용할수 있습니다.
try
S1 := TStringList.Create;
My_RunDosCommand('ping '+'127.0.0.1', S1);
Memo1.Lines.AddStrings(S1);
finally
S1.Free ;
end;
end;