tags:

views:

861

answers:

5

I have the following vbscript code that returns the local IP address. It works great. I am trying to provide the same functionality in my winform .net app.

All the solutions I have come across involve using DNS. Any ideas on how to "port" this script for use in .net?

A different way to do this maybe?

Thanks!

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
+4  A: 
using System.Net;

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

[edit] hmmmm...just realized that you mentioned you don't want to use DNS...why is that?

[edit] moving up from comments....

Simpler version if you only care about local, empty string pass to GetHostEntry will by default return local only

IPAddress localAddr = Dns.GetHostEntry("").AddressList[0];
curtisk
Thanks for taking the time to post! DNS requires that they currently have access to our DNS, correct? Unless that statement is untrue my problem exists in that my App is a sometimes connected App that will not always be on our Home network. They may be at there home or a client's home. P.S. --> I find it interesting that you got 4 upvotes for an answer that goes against what I posted. I mean no offense, just an observation I have noticed more and more here.Thanks again!
Refracted Paladin
hmm, any idea why this would return this --> fe80::ad11:2dc5:58af:a24b%14 ??
Refracted Paladin
@Refracted Paladin - That's an IPv6 IP address.
Greg Beech
I have discovered that the mysterious string is my current IPv6 address
Refracted Paladin
fair enough, no offense taken, that's why right after I posted, I added comment regarding DNS. It's not right...but what you had return looks like its trying to be ipv6 (???)
curtisk
thanks, I agree! Now to filter past that...
Refracted Paladin
You should note that all Windows systems since XP (maybe even as far back as 2000) contain an internal DNS service. Even if you are not connected to any network, using the Dns to look up the computers host entries should still work. I think this is the best answer so far...its simple and should get the job done even at a client's home.
jrista
@jrista: Thank you for clarifying. I did not know about the internal DNS. I will consider this then though I am not sure it is that much simpler then Greg Beech's answer. Thanks!
Refracted Paladin
hmm, the only problem with this approach is that you have to predict what index[] you will need. Works great if you get the right one.
Refracted Paladin
you will never have an empty addresslist, it will throw exception first...a simpler version is IPAddress localAddr = Dns.GetHostEntry("").AddressList[0]; if you put an empty string in GetHostEntry it will by default return local ip
curtisk
+1  A: 

I personally would recommend using the DNS, but if you absolutely don't want to you can get the information from a call to the System.Management namespace

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);

That should correctly get the ip but may need some tweaking.

Stephan
I am probably just thick but ManagementObjectSearcher does not seem to exist in my System.Management namespace??? .net 35 sp1
Refracted Paladin
@Refracted Paladin: Have you added the System.Management assembly to your project's references?
Helen
+5  A: 

You can do this by querying the network interfaces, though this will include all local addresses so you may have to add a where clause to select the one you want if there are multiple interfaces (which there likely will be). It's certainly not a direct port of your script, but hopefully will be of some use:

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

Note: If you only want IPv4 addresses, then you could alter the query to:

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();
Greg Beech
Same issue as the comment I made above. It is returning --> fe80::ad11:2dc5:58af:a24b%14 which I have now discovered is my IPv6 address.
Refracted Paladin
hmm. I am going to accept this as the answer as it actually does return the proper IPv4 address on any box that doesn't have IPv6; which is everyone in my target audience so this works. I would be interested in figuring out how to chose a specific entry but...alas!
Refracted Paladin
hmm, cannot resolve AddressFamily....
Refracted Paladin
I added this to make it work --> where ipAddress.Address.AddressFamily == AddressFamily.InterNetwork // IPv4 but then something strang happened. It is reporting an IP that is unknown to me...
Refracted Paladin
The output that you should get from GetAllNetworkInterfaces should correspond to that of typing "ipconfig /all" at a command prompt. The network interfaces have names and other properties that you can use to identify them, so if you remove the call to FirstOrDefault you can enumerate the sequence and list out all the network interfaces.
Greg Beech
+1  A: 

It looks like your script is calling ipconfig, saving the output to a file, and then parsing the file. If you want to do that, you would do something like this:

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();
}

Note that I'm not particularly fond of this method -- you would probably be better served with some of the other solutions listed in this thread -- but it is a more direct translation of your original script.

Ari Roth
A: 

You can scroll through this to find all ip addresses.

    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 
    }
Aaron
These have been deprecated.
fARcRY