delphi通过IP或机器名获取局域网MAC地址

2018-10-30

通过IP获取局域网MAC地址
uses winsock;
function sendarp(ipaddr:ulong;temp:dword;ulmacaddr:pointer;ulmacaddrleng:pointer) : Dword; StdCall;
    External 'Iphlpapi.dll' Name 'SendARP';
function GetMACByIP(const Ip:string):string;
var
  MyIp:ulong;
  MyMac:array[0..5] of byte;
  MyMacLength:ulong;
  ErrCode:integer;
begin
  Myip:=inet_addr(PChar(Ip));
  MyMacLength:=Length(MyMac);
  ErrCode:=SendArp(MyIp,0,@MyMac,@MyMacLength);
  if ErrCode = 0 then
     Result := Format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',[MyMac[0],MyMac[1],MyMac[2],MyMac[3],MyMac[4],MyMac[5]])
  else
     Result := ''; //EorrCode: ErrCode
end;
又一函数:
下面的函数以'XX-XX-XX-XX-XX-XX' 的格式返回远程或本地机器的MAC地址。

Function to return the MAC address of a remote or local machine in the format 'XX-XX-XX-XX-XX-XX'

返回的MAC地址是一个能用在多个方面的唯一标识。使用方法:
ShowMessage(GetMacAddress('\\MHEYDON');
输出'00-02-08-E7-99-6B'
// ======================================================================
//返回值是主机AServerName的MAC地址
//AServerName参数的格式为'\\ServerName' 或者 'ServerName'
//参数ServerName为空时返回本机的MAC地址
//MAC地址以'XX-XX-XX-XX-XX-XX'的格式返回
// ======================================================================
function GetMacAddress(const AServerName: string): string;
type
    TNetTransportEnum = function (pszServer: PWideChar;
                                  Level: DWORD;
                                  var pbBuffer: pointer;
                                  PrefMaxLen: LongInt;
                                  var EntriesRead: DWORD;
                                  var TotalEntries: DWORD;
                                  var ResumeHandle: DWORD): DWORD; stdcall;
    TTransportInfo = record
                      quality_of_service: DWord;
                      number_of_vcs: DWORD;
                      transport_name: PWChar;
                      transport_address: PWChar;
                      wan_ish: boolean;
                    end;
    TNetApiBufferFree = function(Buffer: pointer): DWORD; stdcall;
    PTransportInfo = ^TTransportInfo;
var
    E,ResumeHandle,
    EntriesRead,
    TotalEntries: DWORD;
    FLibHandle: THandle;
    sMachineName,
    sMacAddr,
    Retvar: string;
    pBuffer: pointer;
    pInfo: PTransportInfo;
    FNetTransportEnum: TNetTransportEnum;
    FNetApiBufferFree: TNetApiBufferFree;
    pszServer: array[0..128] of WideChar;
    i,ii,iIdx: integer;
begin
  sMachineName := Trim(AServerName);
  Retvar := '00-00-00-00-00-00';
  //Add leading \\ if missing
  if (sMachineName <> '') and (length(sMachineName) >= 2) then  begin
    if copy(sMachineName,1,2) <> '\\' then
        sMachineName := '\\' + sMachineName;
  end;
  //Setup and load from DLL
  pBuffer := nil;
  ResumeHandle := 0;
  FLibHandle := LoadLibrary('NETAPI32.DLL');
  // Execute the external function
  if FLibHandle <> 0 then begin
      @FNetTransportEnum := GetProcAddress(FLibHandle,'NetWkstaTransportEnum');
      @FNetApiBufferFree := GetProcAddress(FLibHandle,'NetApiBufferFree');
      E := FNetTransportEnum(StringToWideChar(sMachineName,pszServer,129),0,
      pBuffer,-1,EntriesRead,TotalEntries,Resumehandle);
    if E = 0 then begin
      pInfo := pBuffer;
      // Enumerate all protocols - look for TCPIP
      for i := 1 to EntriesRead do begin
          if pos('TCPIP',UpperCase(pInfo^.transport_name)) <> 0 then begin
            // Got It - now format result 'xx-xx-xx-xx-xx-xx'
            iIdx := 1;
            sMacAddr := pInfo^.transport_address;
            for ii := 1 to 12 do begin
              Retvar[iIdx] := sMacAddr[ii];
              inc(iIdx);
              if iIdx in [3,6,9,12,15] then inc(iIdx);
            end;
        end;
        inc(pInfo);
      end;
      if pBuffer <> nil then FNetApiBufferFree(pBuffer);
    end;
    try
      FreeLibrary(FLibHandle);
    except
      // 错误处理
    end;
  end;
  result:=Retvar;
end;


阅读165