2008-11-28 19 views
10

He estado usando una tarjeta inalámbrica 3G por un tiempo y cada vez que me conecto, mi antivirus activa las actualizaciones.Detectar una activación de conexión a Internet con Delphi

Me pregunto cuál es el conjunto de funciones de la API de Win32 que puedo utilizar para recibir notificaciones o consultar sobre el evento de una conexión a Internet.

¿Y ya hay un conjunto de cabeceras portadas para Delphi?

+1

¿Definir la conexión a Internet? ¿Que es la Internet? –

+0

Creo que sería una interfaz de red, pero realmente no sé cómo lo hace Anti-Virus. –

Respuesta

19

Trabajé en un proyecto para ejecutar un script de inicio de sesión de un usuario cada vez que conectaban nuestra red a través de VPN. Para hacer esto, escribí una unidad auxiliar que recupera la información del adaptador y la almacena en un registro simple.

entonces la configuración de una notificación de registro, see here for how to do that in Delphi

La notificación de registro fue en HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces. Este evento de notificación se dispara cada vez que Windows obtiene una nueva dirección IP o realiza cualquier tipo de cambio en la información de conexión de un adaptador. Cuando se desencadenó este evento, llamé a la función (en el código siguiente) para recuperar información actualizada sobre el adaptador. Comparé esta nueva información con mi información previamente grabada ... lo que significa que tuve que guardar la consulta previa de información del adaptador para saber si algo había cambiado.

De todos modos, aquí está mi unidad ayudante:

unit uAdapterInfo; 

interface 

uses 
    Classes, 
    SysUtils; 

const 
    MAX_INTERFACE_NAME_LEN = $100; 
    ERROR_SUCCESS = 0; 
    MAXLEN_IFDESCR = $100; 
    MAXLEN_PHYSADDR = 8; 

    MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0; 
    MIB_IF_OPER_STATUS_UNREACHABLE = 1; 
    MIB_IF_OPER_STATUS_DISCONNECTED = 2; 
    MIB_IF_OPER_STATUS_CONNECTING = 3; 
    MIB_IF_OPER_STATUS_CONNECTED = 4; 
    MIB_IF_OPER_STATUS_OPERATIONAL = 5; 

    MIB_IF_TYPE_OTHER = 1; 
    MIB_IF_TYPE_ETHERNET = 6; 
    MIB_IF_TYPE_TOKENRING = 9; 
    MIB_IF_TYPE_FDDI  = 15; 
    MIB_IF_TYPE_PPP  = 23; 
    MIB_IF_TYPE_LOOPBACK = 24; 
    MIB_IF_TYPE_SLIP  = 28; 

    MIB_IF_ADMIN_STATUS_UP  = 1; 
    MIB_IF_ADMIN_STATUS_DOWN = 2; 
    MIB_IF_ADMIN_STATUS_TESTING = 3; 

    _MAX_ROWS_ = 20; 
    ANY_SIZE = 1; 


type 
    MIB_IFROW = record 
    wszName: array[0 .. (MAX_INTERFACE_NAME_LEN * 2 - 1)] of ansichar; 
    dwIndex: longint; 
    dwType:  longint; 
    dwMtu:  longint; 
    dwSpeed: longint; 
    dwPhysAddrLen: longint; 
    bPhysAddr: array[0 .. (MAXLEN_PHYSADDR - 1)] of byte; 
    dwAdminStatus: longint; 
    dwOperStatus: longint; 
    dwLastChange: longint; 
    dwInOctets: longint; 
    dwInUcastPkts: longint; 
    dwInNUcastPkts: longint; 
    dwInDiscards: longint; 
    dwInErrors: longint; 
    dwInUnknownProtos: longint; 
    dwOutOctets: longint; 
    dwOutUcastPkts: longint; 
    dwOutNUcastPkts: longint; 
    dwOutDiscards: longint; 
    dwOutErrors: longint; 
    dwOutQLen: longint; 
    dwDescrLen: longint; 
    bDescr:  array[0 .. (MAXLEN_IFDESCR - 1)] of ansichar; 
    end; 

type 
    MIB_IPADDRROW = record 
    dwAddr:  longint; 
    dwIndex:  longint; 
    dwMask:  longint; 
    dwBCastAddr: longint; 
    dwReasmSize: longint; 
    unused1:  word; 
    unused2:  word; 
    end; 

type 
    _IfTable = record 
    nRows: longint; 
    ifRow: array[1.._MAX_ROWS_] of MIB_IFROW; 
    end; 

type 
    _IpAddrTable = record 
    dwNumEntries: longint; 
    table: array[1..ANY_SIZE] of MIB_IPADDRROW; 
    end; 



function GetIfTable(pIfTable: Pointer; var pdwSize: longint; bOrder: longint): longint; 
    stdcall; 
function GetIpAddrTable(pIpAddrTable: Pointer; var pdwSize: longint; 
    bOrder: longint): longint; stdcall; 

function Get_if_type(iType: integer): string; 
function Get_if_admin_status(iStatus: integer): string; 
function Get_if_oper_status(iStatus: integer): string; 


implementation 

function GetIfTable; stdcall; external 'IPHLPAPI.DLL'; 
function GetIpAddrTable; stdcall; external 'IPHLPAPI.DLL'; 

function Get_if_type(iType: integer): string; 
var 
    sResult: string; 
begin 
    sResult := 'UNKNOWN'; 
    case iType of 
    1: sResult := 'Other'; 
    6: sResult := 'Ethernet'; 
    9: sResult := 'Tokenring'; 
    15: sResult := 'FDDI'; 
    23: sResult := 'PPP'; 
    24: sResult := 'Local loopback'; 
    28: sResult := 'SLIP'; 
    37: sResult := 'ATM'; 
    71: sResult := 'IEEE 802.11'; 
    131: sResult := 'Tunnel'; 
    144: sResult := 'IEEE 1394 (Firewire)'; 
    end; 

    Result := sResult; 
end; 

function Get_if_admin_status(iStatus: integer): string; 
var 
    sResult: string; 
begin 
    sResult := 'UNKNOWN'; 

    case iStatus of 
    1: sResult := 'UP'; 
    2: sResult := 'DOWN'; 
    3: sResult := 'TESTING'; 
    end; 

    Result := sResult; 
end; 

function Get_if_oper_status(iStatus: integer): string; 
var 
    sResult: string; 
begin 
    sResult := 'UNKNOWN'; 

    case iStatus of 
    0: sResult := 'NON_OPERATIONAL'; 
    1: sResult := 'UNREACHABLE'; 
    2: sResult := 'DISCONNECTED'; 
    3: sResult := 'CONNECTING'; 
    4: sResult := 'CONNECTED'; 
    5: sResult := 'OPERATIONAL'; 
    end; 

    Result := sResult; 
end; 

end. 

Para utilizar esta unidad desde otra unidad, creé la siguiente función, que rellena un tipo personalizado llamado TAdapterInfo (declarada en mi unidad principal):

type 
    TAdapterInfo = array of record 
    dwIndex: longint; 
    dwType:  longint; 
    dwMtu:  longint; 
    dwSpeed: extended; 
    dwPhysAddrLen: longint; 
    bPhysAddr: string; 
    dwAdminStatus: longint; 
    dwOperStatus: longint; 
    dwLastChange: longint; 
    dwInOctets: longint; 
    dwInUcastPkts: longint; 
    dwInNUcastPkts: longint; 
    dwInDiscards: longint; 
    dwInErrors: longint; 
    dwInUnknownProtos: longint; 
    dwOutOctets: longint; 
    dwOutUcastPkts: longint; 
    dwOutNUcastPkts: longint; 
    dwOutDiscards: longint; 
    dwOutErrors: longint; 
    dwOutQLen: longint; 
    dwDescrLen: longint; 
    bDescr:  string; 
    sIpAddress: string; 
    sIpMask: string; 
    end; 

//////////

function Get_EthernetAdapterDetail(var AdapterDataFound: TAdapterInfo): boolean; 
var 
    pIfTable: ^_IfTable; 
    pIpTable: ^_IpAddrTable; 
    ifTableSize, ipTableSize: longint; 
    tmp:  string; 
    i, j, k, m: integer; 
    ErrCode: longint; 
    sAddr, sMask: in_addr; 
    IPAddresses, IPMasks: TStringList; 
    sIPAddressLine, sIPMaskLine: string; 
    bResult: boolean; 
begin 
    bResult := True; //default return value 
    pIfTable := nil; 
    pIpTable := nil; 

    IPAddresses := TStringList.Create; 
    IPMasks  := TStringList.Create; 

    try 
    // First: just get the buffer size. 
    // TableSize returns the size needed. 
    ifTableSize := 0; // Set to zero so the GetIfTabel function 
    // won't try to fill the buffer yet, 
    // but only return the actual size it needs. 
    GetIfTable(pIfTable, ifTableSize, 1); 
    if (ifTableSize < SizeOf(MIB_IFROW) + Sizeof(longint)) then 
    begin 
     bResult := False; 
     Result := bResult; 
     Exit; // less than 1 table entry?! 
    end; 

    ipTableSize := 0; 
    GetIpAddrTable(pIpTable, ipTableSize, 1); 
    if (ipTableSize < SizeOf(MIB_IPADDRROW) + Sizeof(longint)) then 
    begin 
     bResult := False; 
     Result := bResult; 
     Exit; // less than 1 table entry?! 
    end; 

    // Second: 
    // allocate memory for the buffer and retrieve the 
    // entire table. 
    GetMem(pIfTable, ifTableSize); 
    ErrCode := GetIfTable(pIfTable, ifTableSize, 1); 

    if ErrCode <> ERROR_SUCCESS then 
    begin 
     bResult := False; 
     Result := bResult; 
     Exit; // OK, that did not work. 
     // Not enough memory i guess. 
    end; 

    GetMem(pIpTable, ipTableSize); 
    ErrCode := GetIpAddrTable(pIpTable, ipTableSize, 1); 

    if ErrCode <> ERROR_SUCCESS then 
    begin 
     bResult := False; 
     Result := bResult; 
     Exit; 
    end; 

    for k := 1 to pIpTable^.dwNumEntries do 
    begin 
     sAddr.S_addr := pIpTable^.table[k].dwAddr; 
     sMask.S_addr := pIpTable^.table[k].dwMask; 

     sIPAddressLine := Format('0x%8.8x', [(pIpTable^.table[k].dwIndex)]) + 
     '=' + Format('%s', [inet_ntoa(sAddr)]); 
     sIPMaskLine := Format('0x%8.8x', [(pIpTable^.table[k].dwIndex)]) + 
     '=' + Format('%s', [inet_ntoa(sMask)]); 

     IPAddresses.Add(sIPAddressLine); 
     IPMasks.Add(sIPMaskLine); 
    end; 

    SetLength(AdapterDataFound, pIfTable^.nRows); //initialize the array or records 
    for i := 1 to pIfTable^.nRows do 
     try 
     //if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then 
     //begin 
     m := i - 1; 
     AdapterDataFound[m].dwIndex := 4;//(pIfTable^.ifRow[i].dwIndex); 
     AdapterDataFound[m].dwType := (pIfTable^.ifRow[i].dwType); 
     AdapterDataFound[m].dwIndex := (pIfTable^.ifRow[i].dwIndex); 
     AdapterDataFound[m].sIpAddress := 
      IPAddresses.Values[Format('0x%8.8x', [(pIfTable^.ifRow[i].dwIndex)])]; 
     AdapterDataFound[m].sIpMask := 
      IPMasks.Values[Format('0x%8.8x', [(pIfTable^.ifRow[i].dwIndex)])]; 
     AdapterDataFound[m].dwMtu := (pIfTable^.ifRow[i].dwMtu); 
     AdapterDataFound[m].dwSpeed := (pIfTable^.ifRow[i].dwSpeed); 
     AdapterDataFound[m].dwAdminStatus := (pIfTable^.ifRow[i].dwAdminStatus); 
     AdapterDataFound[m].dwOperStatus := (pIfTable^.ifRow[i].dwOperStatus); 
     AdapterDataFound[m].dwInUcastPkts := (pIfTable^.ifRow[i].dwInUcastPkts); 
     AdapterDataFound[m].dwInNUcastPkts := (pIfTable^.ifRow[i].dwInNUcastPkts); 
     AdapterDataFound[m].dwInDiscards := (pIfTable^.ifRow[i].dwInDiscards); 
     AdapterDataFound[m].dwInErrors := (pIfTable^.ifRow[i].dwInErrors); 
     AdapterDataFound[m].dwInUnknownProtos := (pIfTable^.ifRow[i].dwInUnknownProtos); 
     AdapterDataFound[m].dwOutNUcastPkts := (pIfTable^.ifRow[i].dwOutNUcastPkts); 
     AdapterDataFound[m].dwOutUcastPkts := (pIfTable^.ifRow[i].dwOutUcastPkts); 
     AdapterDataFound[m].dwOutDiscards := (pIfTable^.ifRow[i].dwOutDiscards); 
     AdapterDataFound[m].dwOutErrors := (pIfTable^.ifRow[i].dwOutErrors); 
     AdapterDataFound[m].dwOutQLen := (pIfTable^.ifRow[i].dwOutQLen); 
     AdapterDataFound[m].bDescr := (pIfTable^.ifRow[i].bDescr); 

     tmp := ''; 
     for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen - 1 do 
     begin 
      if Length(tmp) > 0 then 
      tmp := tmp + '-' + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]) 
      else 
      tmp := tmp + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]); 
     end; 

     if Length(tmp) > 0 then 
     begin 
      AdapterDataFound[m].bPhysAddr := tmp; 
     end; 
     except 
     bResult := False; 
     Result := bResult; 
     Exit; 
     end; 
    finally 
    if Assigned(pIfTable) then 
    begin 
     FreeMem(pIfTable, ifTableSize); 
    end; 

    FreeAndNil(IPMasks); 
    FreeAndNil(IPAddresses); 
    end; 

    Result := bResult; 
end; 

En un lado por completo, no e, también usé esta unidad y casi exactamente el mismo código para crear un duplicado de ifconfig -a, que can be found on github. Principalmente lo hice como un ejercicio para enseñarme a mí mismo cómo lograr esta tarea.

+0

Tu código se bloquea en esta línea (error de comprobación de rango): para k: = 1 a pIpTable^.dwNumEntries do ... – Ampere

+0

Un comentarista me envió un correo electrónico con una corrección (que actualicé aquí): "Hizo un enunciado bien después de que cambié el declaraciones de "wszName" y "bDescr" de "char" a "ansichar" en el tipo "MIB_IFROW". Utilicé su unidad en Delphi 10.1 en Win 10. " – Mick

3

Mira InternetGetConnectedState en WinINet.

Algunas aplicaciones también pueden sondear en busca de un servidor conocido y no hacer nada hasta que obtengan una conexión válida.

12
uses WinInet; 

function IsConnected: boolean; 
const 
    // local system uses a modem to connect to the Internet. 
    INTERNET_CONNECTION_MODEM  = 1; 
    // local system uses a local area network to connect to the Internet. 
    INTERNET_CONNECTION_LAN  = 2; 
    // local system uses a proxy server to connect to the Internet. 
    INTERNET_CONNECTION_PROXY  = 4; 
    // local system's modem is busy with a non-Internet connection. 
    INTERNET_CONNECTION_MODEM_BUSY = 8; 

var 
    dwConnectionTypes : DWORD; 
begin 
    dwConnectionTypes := INTERNET_CONNECTION_MODEM + 
         INTERNET_CONNECTION_LAN + 
         INTERNET_CONNECTION_PROXY; 
    Result := InternetGetConnectedState(@dwConnectionTypes,0); 
end; 
+0

Sí. Eso es lo que uso. Aunque no estoy seguro si es 100% confiable. – lkessler

+0

No es 100% confiable. – Mick

2

Aquí hay un ejemplo práctico de cómo usar la unidad auxiliar. Es de un pequeño proyecto que escribí para emular "ifconfig -a". Este es un proyecto de aplicación de consola.

program ifconfig; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils, 
    Classes, 
    Winsock, 
    uAdapterInfo in 'uAdapterInfo.pas'; 

type 
    TAdapterInfo = array of record 
    dwIndex: longint; 
    dwType:  longint; 
    dwMtu:  longint; 
    dwSpeed: extended; 
    dwPhysAddrLen: longint; 
    bPhysAddr: string; 
    dwAdminStatus: longint; 
    dwOperStatus: longint; 
    dwLastChange: longint; 
    dwInOctets: longint; 
    dwInUcastPkts: longint; 
    dwInNUcastPkts: longint; 
    dwInDiscards: longint; 
    dwInErrors: longint; 
    dwInUnknownProtos: longint; 
    dwOutOctets: longint; 
    dwOutUcastPkts: longint; 
    dwOutNUcastPkts: longint; 
    dwOutDiscards: longint; 
    dwOutErrors: longint; 
    dwOutQLen: longint; 
    dwDescrLen: longint; 
    bDescr:  string; 
    sIpAddress: string; 
    sIpMask: string; 
    end; 




    function Get_EthernetAdapterDetail(var AdapterDataFound: TAdapterInfo): boolean; 
    var 
    pIfTable: ^_IfTable; 
    pIpTable: ^_IpAddrTable; 
    ifTableSize, ipTableSize: longint; 
    tmp:  string; 
    i, j, k, m: integer; 
    ErrCode: longint; 
    sAddr, sMask: in_addr; 
    IPAddresses, IPMasks: TStringList; 
    sIPAddressLine, sIPMaskLine: string; 
    bResult: boolean; 
    begin 
    bResult := True; //default return value 
    pIfTable := nil; 
    pIpTable := nil; 

    IPAddresses := TStringList.Create; 
    IPMasks  := TStringList.Create; 

    try 
     // First: just get the buffer size. 
     // TableSize returns the size needed. 
     ifTableSize := 0; // Set to zero so the GetIfTabel function 
     // won't try to fill the buffer yet, 
     // but only return the actual size it needs. 
     GetIfTable(pIfTable, ifTableSize, 1); 
     if (ifTableSize < SizeOf(MIB_IFROW) + Sizeof(longint)) then 
     begin 
     bResult := False; 
     Result := bResult; 
     Exit; // less than 1 table entry?! 
     end; 

     ipTableSize := 0; 
     GetIpAddrTable(pIpTable, ipTableSize, 1); 
     if (ipTableSize < SizeOf(MIB_IPADDRROW) + Sizeof(longint)) then 
     begin 
     bResult := False; 
     Result := bResult; 
     Exit; // less than 1 table entry?! 
     end; 

     // Second: 
     // allocate memory for the buffer and retrieve the 
     // entire table. 
     GetMem(pIfTable, ifTableSize); 
     ErrCode := GetIfTable(pIfTable, ifTableSize, 1); 

     if ErrCode <> ERROR_SUCCESS then 
     begin 
     bResult := False; 
     Result := bResult; 
     Exit; // OK, that did not work. 
     // Not enough memory i guess. 
     end; 

     GetMem(pIpTable, ipTableSize); 
     ErrCode := GetIpAddrTable(pIpTable, ipTableSize, 1); 

     if ErrCode <> ERROR_SUCCESS then 
     begin 
     bResult := False; 
     Result := bResult; 
     Exit; 
     end; 

     for k := 1 to pIpTable^.dwNumEntries do 
     begin 
     sAddr.S_addr := pIpTable^.table[k].dwAddr; 
     sMask.S_addr := pIpTable^.table[k].dwMask; 

     sIPAddressLine := Format('0x%8.8x', [(pIpTable^.table[k].dwIndex)]) + 
      '=' + Format('%s', [inet_ntoa(sAddr)]); 
     sIPMaskLine := Format('0x%8.8x', [(pIpTable^.table[k].dwIndex)]) + 
      '=' + Format('%s', [inet_ntoa(sMask)]); 

     IPAddresses.Add(sIPAddressLine); 
     IPMasks.Add(sIPMaskLine); 
     end; 

     SetLength(AdapterDataFound, pIfTable^.nRows); //initialize the array or records 
     for i := 1 to pIfTable^.nRows do 
     try 
      //if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then 
      //begin 
      m := i - 1; 
      AdapterDataFound[m].dwIndex := 4;//(pIfTable^.ifRow[i].dwIndex); 
      AdapterDataFound[m].dwType := (pIfTable^.ifRow[i].dwType); 
      AdapterDataFound[m].dwIndex := (pIfTable^.ifRow[i].dwIndex); 
      AdapterDataFound[m].sIpAddress := 
      IPAddresses.Values[Format('0x%8.8x', [(pIfTable^.ifRow[i].dwIndex)])]; 
      AdapterDataFound[m].sIpMask := 
      IPMasks.Values[Format('0x%8.8x', [(pIfTable^.ifRow[i].dwIndex)])]; 
      AdapterDataFound[m].dwMtu := (pIfTable^.ifRow[i].dwMtu); 
      AdapterDataFound[m].dwSpeed := (pIfTable^.ifRow[i].dwSpeed); 
      AdapterDataFound[m].dwAdminStatus := (pIfTable^.ifRow[i].dwAdminStatus); 
      AdapterDataFound[m].dwOperStatus := (pIfTable^.ifRow[i].dwOperStatus); 
      AdapterDataFound[m].dwInUcastPkts := (pIfTable^.ifRow[i].dwInUcastPkts); 
      AdapterDataFound[m].dwInNUcastPkts := (pIfTable^.ifRow[i].dwInNUcastPkts); 
      AdapterDataFound[m].dwInDiscards := (pIfTable^.ifRow[i].dwInDiscards); 
      AdapterDataFound[m].dwInErrors := (pIfTable^.ifRow[i].dwInErrors); 
      AdapterDataFound[m].dwInUnknownProtos := (pIfTable^.ifRow[i].dwInUnknownProtos); 
      AdapterDataFound[m].dwOutNUcastPkts := (pIfTable^.ifRow[i].dwOutNUcastPkts); 
      AdapterDataFound[m].dwOutUcastPkts := (pIfTable^.ifRow[i].dwOutUcastPkts); 
      AdapterDataFound[m].dwOutDiscards := (pIfTable^.ifRow[i].dwOutDiscards); 
      AdapterDataFound[m].dwOutErrors := (pIfTable^.ifRow[i].dwOutErrors); 
      AdapterDataFound[m].dwOutQLen := (pIfTable^.ifRow[i].dwOutQLen); 
      AdapterDataFound[m].bDescr := (pIfTable^.ifRow[i].bDescr); 

      tmp := ''; 
      for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen - 1 do 
      begin 
      if Length(tmp) > 0 then 
       tmp := tmp + '-' + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]) 
      else 
       tmp := tmp + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]); 
      end; 

      if Length(tmp) > 0 then 
      begin 
      AdapterDataFound[m].bPhysAddr := tmp; 
      end; 
     except 
      bResult := False; 
      Result := bResult; 
      Exit; 
     end; 
    finally 
     if Assigned(pIfTable) then 
     begin 
     FreeMem(pIfTable, ifTableSize); 
     end; 

     FreeAndNil(IPMasks); 
     FreeAndNil(IPAddresses); 
    end; 

    Result := bResult; 
    end; 



var 
    AdapterData: TAdapterInfo; 
    i: integer; 
begin 
    try 
    WriteLn(''); 
    if Get_EthernetAdapterDetail(AdapterData) then 
    begin 
     for i := 0 to Length(AdapterData) - 1 do 
     begin 
     WriteLn(Format('0x%8.8x', [AdapterData[i].dwIndex])); 
     WriteLn('"' + AdapterData[i].bDescr + '"'); 
     Write(Format(#9 + 'Link encap: %s ', [Get_if_type(AdapterData[i].dwType)])); 

     if Length(AdapterData[i].bPhysAddr) > 0 then 
      Write('HWaddr: ' + AdapterData[i].bPhysAddr); 

     Write(#13 + #10 + #9 + 'inet addr:' + AdapterData[i].sIpAddress); 
     WriteLn(' Mask: ' + AdapterData[i].sIpMask); 
     WriteLn(Format(#9 + 'MTU: %d Speed:%.2f Mbps', [AdapterData[i].dwMtu, 
      (AdapterData[i].dwSpeed)/1000/1000])); 
     Write(#9 + 'Admin status:' + Get_if_admin_status(AdapterData[i].dwAdminStatus)); 
     WriteLn(' Oper status:' + Get_if_oper_status(AdapterData[i].dwOperStatus)); 
     WriteLn(#9 + Format('RX packets:%d dropped:%d errors:%d unkown:%d', 
      [AdapterData[i].dwInUcastPkts + AdapterData[i].dwInNUcastPkts, 
      AdapterData[i].dwInDiscards, AdapterData[i].dwInErrors, 
      AdapterData[i].dwInUnknownProtos])); 
     WriteLn(#9 + Format('TX packets:%d dropped:%d errors:%d txqueuelen:%d', 
      [AdapterData[i].dwOutUcastPkts + AdapterData[i].dwOutNUcastPkts, 
      AdapterData[i].dwOutDiscards, AdapterData[i].dwOutErrors, 
      AdapterData[i].dwOutQLen])); 

     WriteLn(''); 
     end; 
    end 
    else 
    begin 
     WriteLn(#13+#10+'*** Error retrieving adapter information'); 
    end; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 
+0

Tu código se bloquea en esta línea (error de comprobación de rango): para k: = 1 a pIpTable^.dwNumEntries do ... – Ampere

+0

Debería arreglarse ahora.Originalmente compilé con Delphi 2007 (y lo escribí hace casi 10 años), pero un comentarista detectó y corrigió el error y dijo que compila en Delphi 10.1 Berlin. – Mick

Cuestiones relacionadas