2009-02-23 18 views
16

Jeder kann einen Weg in Delphi bekommen eine einfache Liste (zB Tstrings) der lokalen IP-Adresse.Delphi, Wie bekomme ich alle lokalen IPs?

Ich habe mir die andere verwandte Frage angeschaut, und kann nicht scheinen, meinen Kopf herum zu bekommen, sie zu Delphi umzuwandeln.

+0

Es würde helfen, wenn Sie bereits mit den funktionierenden Lösungen verknüpfen würden. Sie fragen nicht, wie Sie eine Liste von IP-Adressen erhalten können. Sie fragen, wie Sie anderen Code nach Delphi konvertieren. Zeigen Sie den Originalcode. –

+0

Es ist bestenfalls schwierig ... hängt davon ab, auf welchen Betriebssystemen der Code funktionieren sollte ... es ist wahrscheinlich ein Pufferüberlauf/Absturzanfälligkeit. Zum Glück haben spätere Windows-Betriebssysteme zumindest eine bessere Unterstützung. –

Antwort

14

in indy 9 gibt es eine Einheit IdStack ist, mit der Klasse TIdStack

fStack := TIdStack.CreateStack; 
try 
    edit.caption := fStack.LocalAddress; //the first address i believe 
    ComboBox1.Items.Assign(fStack.LocalAddresses); //all the address' 
finally 
    freeandnil(fStack); 
end; 

great :) funktioniert

aus Remy Lebeaus Kommentar

Das gleiche gibt es in Indy 10, aber der Code ist ein wenig anders:

TIdStack.IncUsage; 
try 
    GStack.AddLocalAddressesToList(ComboBox1.Items); 
    Edit.Caption := ComboBox1.Items[0]; 
finally 
    TIdStack.DecUsage; 
end; 
+2

Das gleiche existiert in Indy 10, aber der Code ist ein wenig anders: TIdStack.IncUsage; versuchen Sie GStack.AddLocalAddressesToList (ComboBox1.Items); Edit.Caption: = ComboBox1.Items [0]; schließlich TIdStack.DECUsage; Ende; –

+0

@RemyLebeau Ich versuche dies mit Indy 10 in XE2 ohne Glück (mit TStringList und TStrings - ich bekomme "Abstract Error" nur beim Aufruf von 'AddLocalAddressesToList (L);' –

+0

Seltsam, wie die Prozedur abstrahiert wo es deklariert ist: 'Prozedur AddLocalAddressesToList (AAddresses: TStrings); virtual; abstract;' –

8

Wenn Sie ICS für Socket-Kommunikation verwenden, können Sie die LocalIPList-Funktion verwenden, die in der OverbyteIcsWSocket-Einheit definiert ist.

Auch wenn Sie es nicht verwenden, können Sie den Quellcode herunterladen und die Implementierung nachschlagen. Es verwendet WinSock intern.

+0

danke, du hast mir den Hinweis gegeben, den ich brauchte, ich benutze Indy9, also habe ich einen Snoop herum und fand meine Antwort :) –

4

Ich postete eine solution on SO here. Dies füllt ein Array von Datensätzen mit allen Informationen für jeden Adapter im System auf. Dazu gehören die IP-Adresse, aber auch MAC-Adresse, Subnetzmaske, übertragene/revd-Pakete, Beschreibung usw.

Sobald Sie das Array von Datensätzen gefüllt haben, listen Sie es einfach für die IP-Adressen auf, wenn Sie das alles sind wollen.

Dies emuliert "ifconfig -a" auf Linux:

C:\>ifconfig 
0x00000001 
"MS TCP Loopback interface" 
     Link encap: Local loopback 
     inet addr:127.0.0.1 Mask: 255.0.0.0 
     MTU: 1520 Speed:10.00 Mbps 
     Admin status:UP Oper status:OPERATIONAL 
     RX packets:179805 dropped:0 errors:0 unkown:0 
     TX packets:179804 dropped:0 errors:0 txqueuelen:0 

0x00000002 
"Broadcom NetXtreme 57xx Gigabit Controller - Packet Scheduler Miniport" 
     Link encap: Ethernet HWaddr: XX-XX-XX-XX-XX-XX 
     inet addr:10.101.101.102 Mask: 255.255.255.0 
     MTU: 1500 Speed:100.00 Mbps 
     Admin status:UP Oper status:OPERATIONAL 
     RX packets:6287896 dropped:0 errors:0 unkown:0 
     TX packets:5337100 dropped:0 errors:1 txqueuelen:0 

Hier ist die vollständige Quelle der "ifconfig -a" Projekt. Sie müssen auch grab my helper unit (uAdapterInfo) und fügen Sie es mit diesem Programm ein.

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. 

Und hier ist die Helfer Einheit Sie enthalten müssen:

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. 
+0

Es scheint, dass der obige Code nicht vollständig ist. Die Antwort, auf die Sie verlinken, hat ungefähr doppelt so viel Code. –

+0

@Mick - Sie Code-Abstürze in dieser Zeile (Bereichsprüfung Fehler): für k: = 1 zu pIpTable^.dwNumEntries tun – Ampere

+0

Diese Zeile verursachte eaccess Verletzung Fehler für mich: tmp: = tmp + '-' + Format ('% .2x ', [pIfTable^.ifRow [i] .bPhysAddr [j]]) Weil j von dwPhysAddrLen mit dem Wert 3211316 abgeleitet ist, während das Array bPhysAddr nur Zellen hatte 0-7 – SolarBrian

2

Es kann auch mit WinApi (notwendige Header sind in der Jedi ApiLib) erfolgen. Dies ist, wie ich es in meiner TSAdminEx Anwendung:

function EnumerateIpAddresses(var IPList: TStringList): Boolean; 
var 
    IPAddrTable: PMIB_IPADDRTABLE; 
    Size: DWORD; 
    Res: DWORD; 
    Index: Integer; 
    Addr: IN_ADDR; 
begin 
    Result := False; 

    IPList.Duplicates := dupIgnore; 

    Size := 0; 
    // Get required Size 
    if GetIpAddrTable(nil, Size, False) <> ERROR_INSUFFICIENT_BUFFER then Exit; 

    // Reserve mem 
    GetMem(IPAddrTable, Size); 
    Res := GetIpAddrTable(IPAddrTable, Size, True); 

    if Res <> NO_ERROR then Exit; 

    for Index := 0 to IPAddrTable^.dwNumEntries-1 do 
    begin 
    // Convert ADDR to String and add to IPList 
    Addr.S_addr := IPAddrTable^.table[Index].dwAddr; 
    // Prevent implicit string conversion warning in D2009 by explicit cast to string 
    IPList.Add({$IFDEF UNICODE}String({$ENDIF UNICODE}inet_ntoa(Addr){$IFDEF UNICODE}){$ENDIF UNICODE}); 
    end; 

    // Free Mem 
    FreeMem(IPAddrTable); 

    Result := True; 
end; 
3

Der Jedi Code Library enthält eine Prozedur

procedure GetIpAddresses(Results: TStrings); 

in Einheit JclSysInfo

1

Von Delphi 7 Indy 9 Quelle ich etwas finden, das gelöst das Problem mit GStack. Es ist ein bisschen anders als vorheriger Post.

function GetLocalIPAddress(List: TStringlist): Integer; 
begin  
    if Assigned(GStack) then 
    List.Assign(TStringlist(GStack.LocalAddresses)) 
    else 
    begin 
    GStack := GStackClass.Create; 
    List.Assing(TStringlist(GStack.LocalAddresses)); 
    FreeAndNil(GStack); 
    end; 
end; 

Ich denke, das wird auch mit Indy 10 funktionieren.

Verwandte Themen