2011-11-11 28 views
8

Ho una VM VirtualBox installata sulla mia macchina e come tale c'è una scheda Ethernet che appare per essa. Sto enumerare l'elenco degli indirizzi IP della mia macchina tramite il seguente:C# - Trovare l'indirizzo IP locale della mia macchina e non la VM

 public string GetLocalIpAddress() 
     { 
      try 
      { 
       string strHostName = Dns.GetHostName(); 

       // Then using host name, get the IP address list.. 
       IPHostEntry ipEntry = Dns.GetHostEntry(strHostName); 

       foreach (IPAddress ip in ipEntry.AddressList) 
       { 
        if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
        { 
         return string.Format("({0})", ip.ToString()); 
        } 
       } 
      } 
      catch(Exception e) 
      { 
       Global.ApplicationLog.AddApplicationLog(EnumAppEventTypes.SYSTEM_ERROR, e.ToString()); 
      } 

      return ""; 
     } 

mio problema è che l'adattatore ethernet della macchina virtuale cattura anche sulla condizione:

if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 

c'è un modo di selezionando l'indirizzo IP locale della mia macchina e ignorando la mia macchina virtuale?

risposta

4

È possibile ignorare l'adattatore Ethernet in base al nome. Poiché la scheda Ethernet VM è rappresentata da un driver NIC valido, è completamente equivalente alla scheda NIC fisica della macchina dal punto di vista del sistema operativo.

+0

Sfortunatamente la classe IPAddress non sembra mantenere il nome dell'adattatore ethernet, quindi non posso eliminare l'adattatore Ethernet VM con tale metodo. – n00b

+2

Sì, potrebbe essere necessario cambiare approccio utilizzando il metodo NetworkInterface.GetAllNetworkInterfaces(). Restituirà tutte le interfacce e quindi sarà possibile enumerare attraverso tutti gli indirizzi IP disponibili per ogni interfaccia. – pennanth

+0

Hi pennanth, non riesco a trovare nessuna variabile membro che mostri l'indirizzo IP all'interno della classe NetworkInterface. Correggimi anche se ho torto ma usando il nome della classe NetworkInterface potresti romperlo rinominando i nomi degli adattatori ethernet? Sto cercando una soluzione più affidabile di quella – n00b

4

C'è un'opzione. VM IP non ha un gateway predefinito, quindi escludi tutti gli IP senza Gateway predefinito.

foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) 
{ 
    var addr = ni.GetIPProperties().GatewayAddresses.FirstOrDefault(); 
    if (addr != null) 
    { 
     if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet) 
     { 
      Console.WriteLine(ni.Name); 
      foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) 
      { 
       if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
       { 
        Console.WriteLine(ip.Address.ToString()); 
       } 
      } 
     } 
    } 
} 
+0

Questo funziona per me va bene. Grazie mille – RainClick

8

io sono la risposta di raffinazione Andrej Arh, come l'indirizzo IP riportato da GatewayAddresses può anche essere "0.0.0.0" invece di nulla:

public static string GetPhysicalIPAdress() 
    { 
     foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) 
     { 
      var addr = ni.GetIPProperties().GatewayAddresses.FirstOrDefault(); 
      if (addr != null && !addr.Address.ToString().Equals("0.0.0.0")) 
      { 
       if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet) 
       { 
        foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) 
        { 
         if (ip.Address.AddressFamily == AddressFamily.InterNetwork) 
         { 
          return ip.Address.ToString(); 
         } 
        } 
       } 
      } 
     } 
     return String.Empty; 
    } 
+0

Questo non funziona se non c'è un gateway ma l'indirizzo è ancora fisico. – zezba9000

2

utilizzare WMI e verificare immobili ConnectorPresent per fisica dispositivo.

public static string GetPhysicalIPAdress() 
{ 
    foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) 
    { 
     if (ConnectorPresent(ni)) 
     { 
      if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet) 
      { 
       foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) 
       { 
        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
        { 
         return ip.Address.ToString(); 
        } 
       } 
      } 
     } 
    } 
    return string.Empty; 
} 

private static bool ConnectorPresent(NetworkInterface ni) 
{ 
    ManagementScope scope = new ManagementScope(@"\\localhost\root\StandardCimv2"); 
    ObjectQuery query = new ObjectQuery(String.Format(
     @"SELECT * FROM MSFT_NetAdapter WHERE ConnectorPresent = True AND DeviceID = '{0}'", ni.Id)); 
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); 
    ManagementObjectCollection result = searcher.Get(); 
    return result.Count > 0; 
} 
+0

Questo ha funzionato per me con un tweak: ho anche controllato che ni.OperationalStatus == OperationalStatus.Up. Senza quel controllo in più, si trattava di restituire interfacce che erano effettivamente inattivo. –

Problemi correlati