开发者

How to get Router Name & IP as shown in Windows Network Tab? (in code)

If you go to Start and click Computer and then click on the Network link on the left hand side, you'll notice on the right hand side several cat开发者_JAVA百科egories, one of which is titled "Network Infrastructure", in that category, my router is listed, and in my case, it is "LINKSYS WAG160N Wireless-N ADSL2+ Gateway" and when you right-click and select properties, it lists basic info such as internal/gateway IP address, on mine it is "192.168.1.1"

I would like to know how to retrieve this information in code, preferably a Windows API so that I can call it using a legacy VB6 app. Also, even if you just know a .NET version or a Delphi version, please do list that as well as I can code in both. However, the answer I'm ultimately seeking is a method to access this via VB6 so that would probably be a WinAPI call, however, other methods are also welcome in case I can't find a legacy method.


There is a bit more code required than I'd like. If there is a more compact approach I'd be interested myself.

As I understand this, Windows gets the information via UPnP. UPnP works as a sort of Web Service over UDP. It has quirks because it uses UDP multicasts so it can be dificult to code explicitly, but Windows offers a helper library. This library is not "wrapped" well for use from a VB6 program, but with a few tricks you can get access to most of its functionality.

The sample below is written so that it can compile on Win XP as well as later versions of Windows. The Win XP version of the library lacks critical typelib info that prevents VB6 from using everything it offers. This was corrected in Vista, however for this application we don't need the full callback capabilities it offers. You could use an external typelib if you needed full access, or you can compile on Vista or later. A progam compiled on Vista works fine on XP.

The code below is abstracted from a larger Class I use for UPnP NAT port mapping in VB6 servers. This subset may do what you require though.

UPnPNAT.cls

Option Explicit
'Requires reference to:
'
'   UPnP 1.0 Type Library (Control Point)
'

Private Const CONN_SVCTYPEID_URI As String = "urn:schemas-upnp-org:service:WANIPConnection:1"
Private Const CONN_ID_URI As String = "urn:upnp-org:serviceId:WANIPConn1"

Private UDFinder As UPNPLib.UPnPDeviceFinder
Private WithEvents UNCBs As UPnPNATCBs
Private findData As Long
Private blnSuccess As Boolean

Public Event Result(ByVal Success As Boolean, ByVal FriendlyName As String, ByVal IP As String)

Public Sub Fetch()
    blnSuccess = False
    Set UDFinder = New UPNPLib.UPnPDeviceFinder
    Set UNCBs = New UPnPNATCBs
    findData = CallByName(UDFinder, "CreateAsyncFind", VbMethod, CONN_SVCTYPEID_URI, 0, UNCBs)
    UDFinder.StartAsyncFind findData
End Sub

Private Sub UNCBs_DeviceAdded(ByVal Device As UPNPLib.IUPnPDevice)
    Dim Services As UPNPLib.UPnPServices
    Dim Service As UPNPLib.UPnPService
    Dim varInActionArgs, varOutActionArgs
    Dim strFriendlyName As String
    Dim strIP As String

    strFriendlyName = Device.FriendlyName
    On Error Resume Next
    Set Services = Device.Services
    If Err.Number = 0 Then
        On Error GoTo 0
        With Services
            If .Count > 0 Then
                On Error Resume Next
                Set Service = .Item(CONN_ID_URI)
                If Err.Number = 0 Then
                    On Error GoTo 0
                    ReDim varInActionArgs(0 To 0)
                    ReDim varOutActionArgs(0 To 0)
                    Service.InvokeAction "GetExternalIPAddress", _
                                         varInActionArgs, _
                                         varOutActionArgs
                    strIP = varOutActionArgs(0)
                    blnSuccess = True
                Else
                    On Error GoTo 0
                End If
            End If
        End With
    Else
        On Error GoTo 0
    End If

    UDFinder.CancelAsyncFind findData
    RaiseEvent Result(blnSuccess, strFriendlyName, strIP)
    Set UDFinder = Nothing
    Set UNCBs = Nothing
End Sub

Private Sub UNCBs_SearchComplete()
    If Not blnSuccess Then
        RaiseEvent Result(False, "", "")
    End If
End Sub

UPnPNATCBs.cls

Option Explicit

Public Event DeviceAdded(ByVal Device As UPNPLib.IUPnPDevice)
Public Event DeviceRemoved(ByVal UDN As String)
Public Event SearchComplete()

Public Sub IDispatchCallback( _
    ByVal pDevice As Variant, _
    ByVal bstrUDN As Variant, _
    ByVal lType As Variant)
    'NOTE: Must be dispID = 0, i.e. the default method of the class.

    Select Case lType
        Case 0
            RaiseEvent DeviceAdded(pDevice)
        Case 1
            RaiseEvent DeviceRemoved(bstrUDN)
        Case 2
            RaiseEvent SearchComplete
    End Select
End Sub

Form1.frm

Option Explicit

Private WithEvents UN As UPnPNAT

Private Sub Form_Load()
    Set UN = New UPnPNAT
    lblStatus.Caption = "Searching..."
    UN.Fetch
End Sub

Private Sub UN_Result(ByVal Success As Boolean, ByVal FriendlyName As String, ByVal IP As String)
    If Success Then
        lblStatus.Caption = FriendlyName & " " & IP
    Else
        lblStatus.Caption = "Failed"
    End If
End Sub

You may have to tweak this some if you have multiple UPnP devices providing connections in your network.


You might try capturing the output of the "route print -4" command and parsing it for the default route. If you are using IPv6 then change -4 to -6.


if (!NetworkInterface.GetIsNetworkAvailable())
    return "Not connected.";

var networkDevices = NetworkInterface.GetAllNetworkInterfaces();
if (networkDevices.Length == 0)
    return "No network devices.";

networkDevices = networkDevices
    .Where(n => n.OperationalStatus == OperationalStatus.Up
        || n.OperationalStatus == OperationalStatus.Dormant)
    .ToArray();
if (networkDevices.Length == 0)
    return "Network not connected.";

networkDevices = networkDevices
    .Where(n => n.Supports(NetworkInterfaceComponent.IPv4))
    .ToArray();
if (networkDevices.Length == 0)
    return "No IPv4 network found.";

var router = networkDevices.First().GetIPProperties()
    .GatewayAddresses.First();

var routerIp = router.Address.ToString();


NetworkInterface Class


connect to the webpage http:[ip]. The title of this webpage as the name of the device (the device model). This works with devices that displays login page. If the device wants to get the username and password with the request, an WebException occurs and you can read the WebException.Response.Headers["WWW-Authenticate"] which contains the string: Basic realm="X", where X is a string that describes the device.

        private string GetDeviceName(string ip)
    {
        WebClient myWebClient = new WebClient(1000);
        try
        {
            System.IO.Stream s = myWebClient.OpenRead("http://" + ip);
            var sr = new System.IO.StreamReader(s);
            while (!sr.EndOfStream)
            {
                var L = sr.ReadLine();
                var sb = new StringBuilder();
                var st = 0;
                var end = 0;
                if ((st = L.ToLower().IndexOf("<title>")) != -1)
                {
                    sb.Append(L);
                    while ((end = L.ToLower().IndexOf("</title>")) == -1)
                    {
                        L = sr.ReadLine();
                        sb.Append(L);
                    }
                    sr.Close();
                    s.Close();
                    myWebClient.Dispose();
                    var title = sb.ToString().Substring(st + 7, end - st - 7);
                    Regex r = new Regex("&#[^;]+;");
                    title = r.Replace(title, delegate (Match match)
                    {
                        string value = match.Value.ToString().Replace("&#", "").Replace(";", "");
                        int asciiCode;
                        if (int.TryParse(value, out asciiCode))
                            return Convert.ToChar(asciiCode).ToString();
                        else
                            return value;
                    });
                    return $"Router/AP ({title})";
                }
            }
            sr.Close();
            s.Close();
            myWebClient.Dispose();
        }
        catch (System.Net.WebException ex)
        {
            var response = ex.Response as HttpWebResponse;
            if (response == null)
                return "";

            var name = response.Headers?["WWW-Authenticate"]?.Substring(12).Trim('"');
            myWebClient.Dispose();
            return name;
        }
        return "";
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜