// 읽고 쓰기 파이프 핸들type
TPipeHandles=record
hRead, hWrite: DWORD;
end;
// 실행한 도스 명령어의 결과값을 반환
functionGetDosOutput(cmd:String): String;
constBUFFER_SIZE=4096;
// 넘겨받은 핸들을 닫아줌 ____________________________________________________
procedureClosePipe(var Pipe: TPipeHandles);
begin
withPipe do begin
ifhRead<>0thenCloseHandle(hRead);
ifhWrite<>0thenCloseHandle(hWrite);
hRead:=0;
hWrite:=0;
end;
end;
// 파이프에서 읽어온 정보를 Result 에 저장 ___________________________________ procedureReadPipe(varPipe: TPipeHandles);
var
ReadBuf: array[0..BUFFER_SIZE] ofChar;
BytesRead: DWORD;
begin
// 파이프에 읽을 데이터가 있는지 검사
ifPeekNamedPipe(pipe.hRead, nil, 0, nil, @BytesRead, nil) and(BytesRead>0)
then begin
ReadFile(pipe.hRead, ReadBuf, BytesRead, BytesRead, nil);
if BytesRead>0then begin
ReadBuf[BytesRead]:=#0;
Result:=ReadBuf;
end;
end;
end;
// ___________________________________________________________________________
var
ProcessInfo: TProcessInformation;
StartupInfo: TStartupInfo;
SecAttr: TSecurityAttributes;
PipeStdOut: TPipeHandles;
PipeStdErr: TPipeHandles;
dwExitCode: DWORD;
begin
SecAttr.nLength:=SizeOf(SecAttr);
SecAttr.lpSecurityDescriptor:=nil;
SecAttr.bInheritHandle:=True;
// STDOUT 파이프 생성
withPipeStdOutdo // 표준 출력(stdout) 파이프
if notCreatePipe(hRead, hWrite, @SecAttr, BUFFER_SIZE) then ShowMessage('STDOUT pipe 를 만들 수 없습니다.');
try
// STDERR 파이프 생성
withPipeStdErr do// 표준 에러(stderr) 파이프
if notCreatePipe(hRead, hWrite, @SecAttr, BUFFER_SIZE) thenShowMessage('STDERR pipe 를 만들 수 없습니다.');
except
ClosePipe(PipeStdOut);
raise;
Exit;
end;
try
FillChar(StartupInfo, SizeOf(StartupInfo),0);
withStartupInfo do begin
cb:=SizeOf(StartupInfo);
dwFlags:=STARTF_USESHOWWINDOW orSTARTF_USESTDHANDLES;
// 표준출력 and 표준에러 스트림에 생성한 파이프를 연결
hStdOutput:=PipeStdOut.hWrite;
hStdError:=PipeStdErr.hWrite;
wShowWindow:=SW_HIDE;
end;
// 도스 명령어 실행
ifCreateProcess(
nil, PChar(Cmd), @SecAttr, @SecAttr, True,
DETACHED_PROCESS or NORMAL_PRIORITY_CLASS,
nil, nil,
StartupInfo, ProcessInfo
)
then begin
dwExitCode:=STILL_ACTIVE;
Screen.Cursor:=crHourglass;
try
repeat
// 실행완료까지 기다림
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess, dwExitCode);
Application.ProcessMessages;
// 실행완료후 결과값을 파이프에서 읽어옴
ReadPipe(PipeStdOut);
ReadPipe(PipeStdErr);
untildwExitCode<>STILL_ACTIVE; // 아직 실행중이면 반복
if notGetExitCodeProcess(ProcessInfo.hProcess, dwExitCode) thenShowMessage('Exit Code 를 읽어올 수 없습니다.');
ifdwExitCode<>0then// 정상종료가 아니면 raiseException.Create('Exit Code '+IntToStr(dwExitCode));
finally Screen.Cursor:=crDefault;
if dwExitCode=STILL_ACTIVE thenTerminateProcess(ProcessInfo.hProcess,1);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
ProcessInfo.hProcess:=0;
end;
end
else ShowMessage(Cmd+' 명령어 실행을 위한 프로세스 생성 실패');
finally
ClosePipe(PipeStdOut);
ClosePipe(PipeStdErr);
end;
end;
procedureTForm1.Button1Click(Sender: TObject);
var s: String;
sList, tList: TStringList;
i: Integer;
begin sList:=TStringList.Create;
tList:=TStringList.Create;
try
s:=GetDosOutput('ipconfig /all');
ExtractStrings([#13],[],PChar(s),sList);
Memo1.Clear;
fori:=0tosList.Count - 1do begin
// 맥어드레스는 Physical Address 라는 항목에 있음
if Pos('Physical Address', sList[i])>0then begin
tList.Clear;
// ':' 로 나눈 뒤에 것이 MAC Address
ExtractStrings([':'], [], PChar(sList[i]), tList);
Memo1.Lines.Add(Trim(tList[1]));
end;
end;
finally
FreeAndNil(tList);
FreeAndNil(sList);
end;
end;
댓글 없음:
댓글 쓰기