How do I get the MAC address of a network card using Delphi?
Get the JEDI conversion of the Microsoft IP Helper Library from the Project JEDI API Header Library - the file is IPHlpAPI.zip. Unpack the files, you need IpTypes.pas and IpHlpApi.pas. Then you can use something like this:
procedure TForm1.Button1Click(Sender: TObject);
var
NumInterfaces: Cardinal;
AdapterInfo: array of TIpAdapterInfo;
OutBufLen: ULONG;
i: integer;
begin
GetNumberOfInterfaces(NumInterfaces);
SetLength(AdapterInfo, NumInterfaces);
OutBufLen := NumInterfaces * SizeOf(TIpAdapterInfo);
GetAdaptersInfo(@AdapterInfo[0], OutBufLen);
Memo1.Lines.Clear;
for i := 0 to NumInterfaces - 1 do begin
Memo1.Lines.Add(Format('%.2x:%.2x:%.2x:%.2x:%.2x:%.2x',
[AdapterInfo[i].Address[0], AdapterInfo[i].Address[1],
AdapterInfo[i].Address[2], AdapterInfo[i].Address[3],
AdapterInfo[i].Address[4], AdapterInfo[i].Address[5]]));
end;
end;
(All error handling omitted, you should add it of course.)
The GetAdaptersAddresses function is the preferred way to obtain adapters information since 2001 with Windows XP.
The adapter's information is returned in the IP_ADAPTER_ADDRESSES structure by the AdapterAddresses
parameter.
The
GetAdaptersAddresses
function can retrieve information for IPv4 and IPv6 addresses.The recommended method of calling the
GetAdaptersAddresses
function is to pre-allocate a 15KB working buffer pointed to by theAdapterAddresses
parameter. On typical computers, this dramatically reduces the chances that theGetAdaptersAddresses
function returnsERROR_BUFFER_OVERFLOW
, which would require callingGetAdaptersAddresses
function multiple times.
procedure TForm1.Button1Click(Sender: TObject);
const
AF_UNSPEC = 0;
GAA_FLAG_INCLUDE_ALL_INTERFACES = $100;
WORKING_BUFFER_SIZE = 15000;
MAX_TRIES = 3;
var
pAddresses,
pCurrAddresses: PIpAdapterAddresses;
dwRetVal,
outBufLen: Cardinal;
i: Integer;
macAddress: string;
begin
Memo1.Lines.Clear;
outBufLen := WORKING_BUFFER_SIZE;
pAddresses := nil;
i := 0;
repeat
if Assigned(pAddresses) then
FreeMem(pAddresses);
GetMem(pAddresses, outBufLen);
if not Assigned(pAddresses) then
raise Exception.Create('Memory allocation failed for IP_ADAPTER_ADDRESSES struct');
dwRetVal := GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_INTERFACES, nil, pAddresses, @outBufLen);
Inc(i);
until (dwRetVal <> ERROR_BUFFER_OVERFLOW) or (i = MAX_TRIES);
try
if NO_ERROR <> dwRetVal then begin
if ERROR_NO_DATA = dwRetVal then begin
MessageDlg('No addresses were found for the requested parameters', mtInformation, [mbOK], 0);
Exit;
end
else
raise Exception.Create(SysErrorMessage(dwRetVal));
end;
pCurrAddresses := pAddresses;
while Assigned(pCurrAddresses) do begin
if pCurrAddresses^.PhysicalAddressLength > 0 then begin
Memo1.Lines.Add(pCurrAddresses^.FriendlyName);
macAddress := '';
for i := 0 to pCurrAddresses^.PhysicalAddressLength - 1 do begin
if i > 0 then
macAddress := macAddress + ':';
macAddress := macAddress + Format('%.2X', [pCurrAddresses^.PhysicalAddress[i]]);
end;
Memo1.Lines.Add(macAddress);
Memo1.Lines.Add('');
end;
pCurrAddresses := pCurrAddresses^.Next;
end;
finally
if Assigned(pAddresses) then
FreeMem(pAddresses);
end;
end;