현재 LocalPC 에 존재하는 IP 목록을 구한후 차례로 MacAddress 를 구해내는 코드입니다.
즐거운 프로그래밍 하세요..^^
uses
WinSock;
{$R *.dfm}
function SendARP(DestIP:ULONG; SrcIP:DWORD; PMacAddr:PULONG; PhyAddrLen:PULONG): DWORD; StdCall;
external 'iphlpapi.dll' name 'SendARP';
function LocalIPList: TStringList;
type
TaPInAddr = array[0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe: PHostEnt;
pptr: PaPInAddr;
Buffer: array[0..63] of AnsiChar;
I: Integer;
WSAData: TWSAData;
begin
WSAStartup(MakeWord(2, 2), WSAData);
Result := TStringList.Create;
Result.Clear;
GetHostName(Buffer, SizeOf(Buffer));
phe := GetHostByName(buffer);
if phe = nil then Exit;
pPtr := PaPInAddr(phe^.h_addr_list);
I := 0;
while pPtr^[I] <> nil do
begin
Result.Add(string(inet_ntoa(pptr^[I]^)));
Inc(I);
end;
WSACleanUp;
end;
function GetMacAddress(IpAddress: string): string;
var
DestIP: ULONG;
MacAddr: Array [0..5] of Byte;
MacAddrLen: ULONG;
begin
DestIP := inet_addr(PAnsiChar(AnsiString(IPAddress)));
MacAddrLen := Length(MacAddr);
SendARP(DestIP, 0, @MacAddr, @MacAddrLen);
Result := Format('%s (MAC): %2.2X-%2.2X-%2.2X-%2.2X-%2.2X-%2.2X',
[IpAddress, MacAddr[0], MacAddr[1], MacAddr[2],
MacAddr[3], MacAddr[4], MacAddr[5]]);
end;
procedure TForm21.Button1Click(Sender: TObject);
var
i : integer;
IPAddressList: TStringList;
begin
IPAddressList := LocalIPList;
try
for i := 0 to IpAddressList.Count -1 do
ShowMessage(GetMacAddress(IpAddressList[i]));
except
on E:Exception do
ShowMessage(E.Message);
end;
end;
땅쿠님 .. 쪽지로 질의를 보내시면 대부분은 답변을 안주십니다...앞으론 쪽지로 주지 마시구요..
질답은 공유되어야 추후 검색자료로도 사용되구요...
문의 주신 질문에 부합되는 코드를 만들려면.. 아무래도 젤 손쉬운 방법은 도스출력을 리다이렉션 하는 방법이
젤 편할거 같습니다. 결과를 가공하셔서 쓰시구요..
아래 그 예제를 퍼다 드립니다.
아마 오래전에 영대님이 팁게에 올리셨던거 같네요..
// 읽고 쓰기 파이프 핸들
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;
// ___________________________________________________________________________
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;
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;
아침에 급조해서 만들어봤습니다.. Delphi2010 으로 구현했되었구요..
현재 LocalPC 에 존재하는 IP 목록을 구한후 차례로 MacAddress 를 구해내는 코드입니다.
즐거운 프로그래밍 하세요..^^
uses
WinSock;
{$R *.dfm}
function SendARP(DestIP:ULONG; SrcIP:DWORD; PMacAddr:PULONG; PhyAddrLen:PULONG): DWORD; StdCall;
external 'iphlpapi.dll' name 'SendARP';
function LocalIPList: TStringList;
type
TaPInAddr = array[0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe: PHostEnt;
pptr: PaPInAddr;
Buffer: array[0..63] of AnsiChar;
I: Integer;
WSAData: TWSAData;
begin
WSAStartup(MakeWord(2, 2), WSAData);
Result := TStringList.Create;
Result.Clear;
GetHostName(Buffer, SizeOf(Buffer));
phe := GetHostByName(buffer);
if phe = nil then Exit;
pPtr := PaPInAddr(phe^.h_addr_list);
I := 0;
while pPtr^[I] <> nil do
begin
Result.Add(string(inet_ntoa(pptr^[I]^)));
Inc(I);
end;
WSACleanUp;
end;
function GetMacAddress(IpAddress: string): string;
var
DestIP: ULONG;
MacAddr: Array [0..5] of Byte;
MacAddrLen: ULONG;
begin
DestIP := inet_addr(PAnsiChar(AnsiString(IPAddress)));
MacAddrLen := Length(MacAddr);
SendARP(DestIP, 0, @MacAddr, @MacAddrLen);
Result := Format('%s (MAC): %2.2X-%2.2X-%2.2X-%2.2X-%2.2X-%2.2X',
[IpAddress, MacAddr[0], MacAddr[1], MacAddr[2],
MacAddr[3], MacAddr[4], MacAddr[5]]);
end;
procedure TForm21.Button1Click(Sender: TObject);
var
i : integer;
IPAddressList: TStringList;
begin
IPAddressList := LocalIPList;
try
for i := 0 to IpAddressList.Count -1 do
ShowMessage(GetMacAddress(IpAddressList[i]));
except
on E:Exception do
ShowMessage(E.Message);
end;
end;