delphi
type PIN_ADDR = ^in_addr; function GetCurrentIP: String; var Wsa: WSADATA; Name: array[0..255] of char; hostinfo: PHOSTENT; begin Result:= ''; FillChar(Wsa, SizeOf(WSAData), 0); if WSAStartup(MAKEWORD(2, 2), Wsa) = 0 then begin if gethostname(Name, SizeOf(Name)) = 0 then begin hostinfo:= gethostbyname(Name); if hostinfo <> nil then Result:= inet_ntoa(PIN_ADDR(hostinfo^.h_addr_list^)^); WSACleanup; end; end; end;
El problema aparece si tenemos más de una tarjeta de red física o virtual, como es el caso de tener instaladas máquinas virtuales en nuestro PC. Para solucionar este caso propongo esta función:
delphi
uses SysUtils, Windows, WinSock; type PIP_ADDR_STRING = ^IP_ADDR_STRING; IP_ADDR_STRING = record Next: PIP_ADDR_STRING; IpAddress: array [0..15] of Char; IpMask: array [0..15] of Char; Context: DWORD; end; PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO; IP_ADAPTER_INFO = record Next: PIP_ADAPTER_INFO; ComboIndex: DWORD; AdapterName: array [0..259] of Char; Description: array [0..131] of Char; AddressLength: UINT; Address: array [0..7] of BYTE; Index: DWORD; Type_: UINT; DhcpEnabled: UINT; CurrentIpAddress: PIP_ADDR_STRING; IpAddressList: IP_ADDR_STRING; GatewayList: IP_ADDR_STRING; DhcpServer: IP_ADDR_STRING; HaveWins: BOOL; PrimaryWinsServer: IP_ADDR_STRING; SecondaryWinsServer: IP_ADDR_STRING; LeaseObtained: Longint; LeaseExpires: Longint; end; function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; external 'iphlpapi.dll'; function GetCurrentIP: String; var pAI: PIP_ADAPTER_INFO; AILen: DWORD; begin // Encuentro la IP GetAdaptersInfo(nil, AILen); GetMem(pAI, AILen); if GetAdaptersInfo(pAI, AILen) = 0 then Result:= pAI.IpAddressList.IpAddress; FreeMem(pAI); end;
La potente API GetAdaptersInfo es un verdadero "ipconfig" de la que podemos extraer muchos más datos. Os propongo esta pequeña aplicación que muestra el nombre del equipo, la IP y la MAC:
delphi
program GeCurrent_IP_MAC; uses SysUtils, Windows, WinSock; type PIP_ADDR_STRING = ^IP_ADDR_STRING; IP_ADDR_STRING = record Next: PIP_ADDR_STRING; IpAddress: array [0..15] of Char; IpMask: array [0..15] of Char; Context: DWORD; end; PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO; IP_ADAPTER_INFO = record Next: PIP_ADAPTER_INFO; ComboIndex: DWORD; AdapterName: array [0..259] of Char; Description: array [0..131] of Char; AddressLength: UINT; Address: array [0..7] of BYTE; Index: DWORD; Type_: UINT; DhcpEnabled: UINT; CurrentIpAddress: PIP_ADDR_STRING; IpAddressList: IP_ADDR_STRING; GatewayList: IP_ADDR_STRING; DhcpServer: IP_ADDR_STRING; HaveWins: BOOL; PrimaryWinsServer: IP_ADDR_STRING; SecondaryWinsServer: IP_ADDR_STRING; LeaseObtained: Longint; LeaseExpires: Longint; end; function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; external 'iphlpapi.dll'; function wsprintf(lpOut, lpFmt: PChar): Integer; cdecl; varargs; external 'User32.dll' name 'wsprintfA'; function GetCurrentIP_MAC(var Name: String; var IP: String; var MAC: String): boolean; var Wsa: WSADATA; pAI: PIP_ADAPTER_INFO; AILen: DWORD; Buff: array [0..255] of char; begin Result:= true; // Encuentro el nombre del equipo if WSAStartup(MAKEWORD(2,2), Wsa) = 0 then begin gethostname(Buff, sizeof(Buff)); Name:= Buff; WSACleanup; end else Result:= Result and false; // Encuentro la IP y la MAC GetAdaptersInfo(nil, AILen); GetMem(pAI, AILen); if GetAdaptersInfo(pAI, AILen) = 0 then begin wsprintf(Buff, '%.2X-%.2X-%.2X-%.2X-%.2X-%.2X', pAI.Address[0], pAI.Address[1], pAI.Address[2], pAI.Address[3], pAI.Address[4], pAI.Address[5]); MAC:= Buff; IP:= pAI.IpAddressList.IpAddress; end else Result:= Result and false; FreeMem(pAI); end; var Name, IP, MAC: String; begin GetCurrentIP_MAC(Name, IP, MAC); MessageBox(0, PCHAR(Name + #10 + #10 + 'IP: ' + IP + #10 + 'MAC: ' + MAC + #10), 'Current IP', MB_OK or MB_ICONINFORMATION); end.
Saludos.