【问题标题】:How can I get local IP in .NET?如何在 .NET 中获取本地 IP?
【发布时间】:2009-06-05 16:40:58
【问题描述】:

我有以下返回本地 IP 地址的 vbscript 代码。它工作得很好。我正在尝试在我的 winform .net 应用程序中提供相同的功能。

我遇到的所有解决方案都涉及使用 DNS。关于如何“移植”此脚本以在 .net 中使用的任何想法?

也许有不同的方法来做到这一点?

谢谢!

Function GetIP()

 Dim ws : Set ws = CreateObject("WScript.Shell")
  Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
  Dim TmpFile : TmpFile = fso.GetSpecialFolder(2) & "/ip.txt"
  Dim ThisLine, IP
  If ws.Environment("SYSTEM")("OS") = "" Then
    ws.run "winipcfg /batch " & TmpFile, 0, True
  Else
    ws.run "%comspec% /c ipconfig > " & TmpFile, 0, True
  End If
  With fso.GetFile(TmpFile).OpenAsTextStream
    Do While NOT .AtEndOfStream
      ThisLine = .ReadLine
      If InStr(ThisLine, "Address") <> 0 Then IP = Mid(ThisLine, InStr(ThisLine, ":") + 2)
    Loop
    .Close
  End With

  If IP <> "" Then
    If Asc(Right(IP, 1)) = 13 Then IP = Left(IP, Len(IP) - 1)
  End If
  GetIP = IP
  fso.GetFile(TmpFile).Delete  
  Set fso = Nothing
  Set ws = Nothing
End Function

【问题讨论】:

    标签: .net vbscript wmi


    【解决方案1】:

    您可以通过查询网络接口来做到这一点,尽管这将包括所有本地地址,因此如果有多个接口(可能会有),您可能必须添加一个where 子句来选择您想要的一个。它当然不是您脚本的直接端口,但希望会有一些用处:

    var localAddress = 
        (from ni in NetworkInterface.GetAllNetworkInterfaces()
         where ni.NetworkInterfaceType != NetworkInterfaceType.Loopback
         let props = ni.GetIPProperties()
         from ipAddress in props.UnicastAddresses
         select ipAddress).FirstOrDefault();    
    

    注意:如果您只想要 IPv4 地址,那么您可以将查询更改为:

    var localAddress = 
        (from ni in NetworkInterface.GetAllNetworkInterfaces()
         where ni.NetworkInterfaceType != NetworkInterfaceType.Loopback
         let props = ni.GetIPProperties()
         from ipAddress in props.UnicastAddresses
         where ipAddress.AddressFamily == AddressFamily.InterNetwork // IPv4
         select ipAddress).FirstOrDefault();     
    

    【讨论】:

    • 与我上面的评论相同的问题。它正在返回 --> fe80::ad11:2dc5:58af:a24b%14 我现在发现它是我的 IPv6 地址。
    • 嗯。我将接受这个作为答案,因为它实际上会在任何没有 IPv6 的盒子上返回正确的 IPv4 地址;这是我的目标受众中的每个人,所以这很有效。我很想知道如何选择一个特定的条目,但是......唉!
    • 我添加了它以使其工作 --> where ipAddress.Address.AddressFamily == AddressFamily.InterNetwork // IPv4 但后来发生了一些奇怪的事情。它正在报告我不知道的 IP...
    • 您应该从 GetAllNetworkInterfaces 获得的输出应该对应于在命令提示符下键入“ipconfig /all”的输出。网络接口具有可用于识别它们的名称和其他属性,因此如果您删除对 FirstOrDefault 的调用,您可以枚举序列并列出所有网络接口。
    • 您可能还需要在第一个where 子句中添加ni.OperationalStatus == OperationalStatus.Up 和-ed,否则您可能会获得当前无法运行的适配器的IP。在带有无线和有线适配器的笔记本电脑上发现了这一点;当无线适配器关闭时,我正在获取它的 IP。
    【解决方案2】:
    using System.Net;
    
    IPAddress localAddr = Dns.GetHostEntry(Dns.GetHostName().ToString()).AddressList[0];
    

    [edit] 嗯...刚刚意识到您提到您不想使用 DNS...这是为什么呢?

    [edit] 从 cmets 向上移动....

    如果您只关心本地,则更简单的版本,传递给 GetHostEntry 的空字符串将默认返回本地

    IPAddress localAddr = Dns.GetHostEntry("").AddressList[0];
    

    【讨论】:

    • 感谢您抽出宝贵时间发帖! DNS 要求他们当前可以访问我们的 DNS,对吗?除非该声明不真实,否则我的问题存在于我的应用程序是有时连接的应用程序,它并不总是在我们的家庭网络上。他们可能在家里或客户的家中。附言--> 我觉得有趣的是,你得到了 4 个反对我发布的答案的赞成票。我的意思不是冒犯,只是我在这里越来越多地注意到的一个观察。再次感谢!
    • 嗯,知道为什么这会返回这个 --> fe80::ad11:2dc5:58af:a24b%14 ??
    • @Refracted Paladin - 这是一个 IPv6 IP 地址。
    • 您应该注意,自 XP 以来(甚至可以追溯到 2000 年)的所有 Windows 系统都包含内部 DNS 服务。即使您没有连接到任何网络,使用 Dns 查找计算机主机条目应该仍然有效。我认为这是迄今为止最好的答案......它很简单,即使在客户家中也应该完成工作。
    • 你永远不会有一个空的地址列表,它会首先抛出异常......一个更简单的版本是 IPAddress localAddr = Dns.GetHostEntry("").AddressList[0];如果您在 GetHostEntry 中放置一个空字符串,则默认情况下会返回本地 ip
    【解决方案3】:

    看起来您的脚本正在调用 ipconfig,将输出保存到文件,然后解析文件。如果你想这样做,你会做这样的事情:

    using System.Threading;
    
    ...
    
    static void Main(string[] args)
    {
        Process p = new Process();
    
        ProcessStartInfo psi = new ProcessStartInfo("ipconfig");
        psi.CreateNoWindow = true;
        psi.RedirectStandardOutput = true;
        psi.UseShellExecute = false;
    
        p.StartInfo = psi;
        p.Start();
    
        string s = p.StandardOutput.ReadToEnd();
        int startPos = s.IndexOf(":", s.IndexOf("IPv4 Address"));
        string output = s.Substring(startPos + 2, s.IndexOf("\r\n", startPos) - startPos - 2);
        Console.WriteLine(output);
        Console.ReadLine();
    }
    

    请注意,我不是特别喜欢这种方法 - 您可能会更好地使用此线程中列出的其他一些解决方案 - 但它是您原始脚本的更直接翻译。

    【讨论】:

      【解决方案4】:

      我个人建议使用 DNS,但如果您绝对不想这样做,您可以通过调用 System.Management 命名空间来获取信息

      string ipAddress = "";
      ManagementObjectSearcher query =
          new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
      ManagementObjectCollection queryCollection = query.Get();
      foreach (ManagementObject mo in queryCollection)
      {
          string[] addresses = (string[]) mo["IPAddress"];
          if (addresses.Length == 1 && addresses[0] != "0.0.0.0")
          {
              ipAddress = addresses[0];
              break;
          }
      
      }
      Console.WriteLine(ipAddress);
      

      这应该可以正确获取 ip,但可能需要一些调整。

      【讨论】:

      • 我可能只是粗,但我的 System.Management 命名空间中似乎不存在 ManagementObjectSearcher ??? .net 35 sp1
      • @Refracted Paladin:您是否已将 System.Management 程序集添加到项目的引用中?
      【解决方案5】:

      您可以滚动查看所有 IP 地址。

          String hostName = Dns.GetHostName();                      
          IPHostEntry local = Dns.GetHostByName(hostName);
          foreach (IPAddress ipaddress in local.AddressList)
          {
              ipaddress.ToString();  //this gives you the IP address
              //logic here 
          }
      

      【讨论】:

        猜你喜欢
        • 2011-08-12
        • 2014-06-26
        • 2012-05-31
        • 2015-07-09
        • 2011-03-27
        • 2021-01-28
        • 1970-01-01
        相关资源
        最近更新 更多