// 읽고 쓰기 파이프 핸들
type
TPipeHandles=record
hRead, hWrite: DWORD;
end;
// 실행한 도스 명령어의 결과값을 반환
function GetDosOutput(cmd: String): String;
const BUFFER_SIZE=4096;
// 넘겨받은 핸들을 닫아줌 ____________________________________________________
procedure ClosePipe(var Pipe: TPipeHandles);
begin
with Pipe do begin
if hRead<>0 then CloseHandle(hRead);
if hWrite<>0 then CloseHandle(hWrite);
hRead:=0;
hWrite:=0;
end;
end;
// 파이프에서 읽어온 정보를 Result 에 저장 ___________________________________
procedure ReadPipe(var Pipe: TPipeHandles);
var
ReadBuf: array [0..BUFFER_SIZE] of Char;
BytesRead: DWORD;
begin
// 파이프에 읽을 데이터가 있는지 검사
if PeekNamedPipe(pipe.hRead, nil, 0, nil, @BytesRead, nil) and (BytesRead>0)
then begin
ReadFile(pipe.hRead, ReadBuf, BytesRead, BytesRead, nil);
if BytesRead>0 then 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 파이프 생성
with PipeStdOut do // 표준 출력(stdout) 파이프
if not CreatePipe(hRead, hWrite, @SecAttr, BUFFER_SIZE) then ShowMessage('STDOUT pipe 를 만들 수 없습니다.');
try
// STDERR 파이프 생성
with PipeStdErr do // 표준 에러(stderr) 파이프
if not CreatePipe(hRead, hWrite, @SecAttr, BUFFER_SIZE) then ShowMessage('STDERR pipe 를 만들 수 없습니다.');
except
ClosePipe(PipeStdOut);
raise;
Exit;
end;
try
FillChar(StartupInfo, SizeOf(StartupInfo), 0);
with StartupInfo do begin
cb:=SizeOf(StartupInfo);
dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
// 표준출력 and 표준에러 스트림에 생성한 파이프를 연결
hStdOutput:=PipeStdOut.hWrite;
hStdError:=PipeStdErr.hWrite;
wShowWindow:=SW_HIDE;
end;
// 도스 명령어 실행
if CreateProcess(
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);
until dwExitCode<>STILL_ACTIVE; // 아직 실행중이면 반복
if not GetExitCodeProcess(ProcessInfo.hProcess, dwExitCode) then ShowMessage('Exit Code 를 읽어올 수 없습니다.');
if dwExitCode<>0 then // 정상종료가 아니면
raise Exception.Create('Exit Code '+IntToStr(dwExitCode));
finally
Screen.Cursor:=crDefault;
if dwExitCode=STILL_ACTIVE then TerminateProcess(ProcessInfo.hProcess, 1);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
ProcessInfo.hProcess:=0;
end;
end
else ShowMessage(Cmd+' 명령어 실행을 위한 프로세스 생성 실패');
finally
ClosePipe(PipeStdOut);
ClosePipe(PipeStdErr);
end;
end;
//=========================================================================================
procedure TForm1.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;
for i:=0 to sList.Count - 1 do begin
// 맥어드레스는 Physical Address 라는 항목에 있음
if Pos('Physical Address', sList[i])>0 then begin
tList.Clear;
// ':' 로 나눈 뒤에 것이 MAC Address
ExtractStrings([':'], [], PChar(sList[i]), tList);
Memo1.Lines.Add(Trim(tList[1]));
end;
end;
FreeAndNil(tList);
FreeAndNil(sList);
end;
end;
출처 : http://bloodguy.tistory.com/entry/Delphi-MAC-Address-%ED%99%95%EC%9D%B8