0

我想扫描网络并枚举所有 Windows 机器的主机名。有一个接口方法将 IP 范围作为输入并返回主机名。我必须实施它。所以,这是我的代码:

public ICollection<string> EnumerateWindowsComputers(ICollection<string> ipList)
{
    ICollection<string> hostNames = new List<string>();

    foreach (var ip in ipList)
    {
        var hostName = GetHostName(ip);

        if (string.IsNullOrEmpty(hostName) == false)
        {
            hostNames.Add(hostName)
        }
    }

    return hostNames;
}

private static string GetHostName(string ipAddress)
{
    try
    {
        IPHostEntry entry = Dns.GetHostEntry(ipAddress);
        if (entry != null)
        {
            return entry.HostName;
        }
    }
    catch (SocketException ex)
    {
        System.Console.WriteLine(ex.Message + " - " + ipAddress);
    }

    return null;
}

此方法枚举所有windows机器成功,但里面有网络打印机。我可以轻松忽略打印机的主机名,但这不是一个好的解决方案。我必须确保只返回装有 Windows 操作系统的设备。

知道如何在没有第三方库的情况下做到这一点吗?如果有更好的方法,我们不必使用GetHostName方法。

没有按预期找到 PS Linux、MacOS、Android 和 IOS 设备。

4

3 回答 3

0

根据@Jeroen van Langen 的评论,我GetHostNameGetWindowsHostName.

private string GetWindowsHostName(string ipAddress)
{
    try
    {
        IPHostEntry entry = Dns.GetHostEntry(ipAddress);
        if (entry != null)
        {
            try
            {
                using (TcpClient tcpClient = new TcpClient())
                {
                    // 445 is default TCP SMB port
                    tcpClient.Connect(ipAddress, 445);
                }

                using (TcpClient tcpClient = new TcpClient())
                {
                    // 139 is default TCP NetBIOS port.
                    tcpClient.Connect(ipAddress, 139);
                }

                return entry.HostName;
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }
        }
    }
    catch (SocketException ex)
    {
        System.Console.WriteLine(ex.Message + " - " + ipAddress);
    }

    return null;
}

可能会有误报,但这对我来说不太可能并且可以接受。

于 2017-03-08T09:44:09.153 回答
0

您可以尝试检测远程计算机中的操作系统的一种方法是使用 ping。Ping 每个 IP 地址并获取 TTL。这应该让您了解您正在处理的操作系统。可以在此处找到将 TTL 与 OS 匹配的表:http: //www.kellyodonnell.com/content/determining-os-type-ping

于 2017-03-08T08:59:16.790 回答
0

服务检测不会是真的,因为可能有 linux 或其他模拟Windows FileSharing的机器

使用systeminfo /s IPADDRESS来自 Windows 机器的 shell 命令可靠地获取远程 Windows 操作系统详细信息。您的代码将如下所示:

string IPADDRESS = "192.168.1.1";

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;

p.startInfo.FileName = "cmd.exe";
p.startInfo.Arguments = "/C systeminfo /s IPADDRESS";
p.Start();
p.WaitForExit();

string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();

if(output.Contains("Microsoft Windows")) { Console.WriteLine("Windows OS"); }
于 2017-03-08T08:56:38.983 回答