Как найти ПК с Windows в диапазоне IP

Я хочу просканировать сеть и перечислить имя хоста всех машин 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 не найдены должным образом.

3 ответа

Решение

Согласно комментарию @Jeroen van Langen, я изменил свой GetHostName метод с GetWindowsHostName,

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

Там может быть ложное срабатывание, но это вряд ли и приемлемо для меня.

Одним из способов обнаружения ОС на удаленном компьютере является использование ping. Пингуйте каждый IP-адрес и получите TTL. Это должно дать вам представление об ОС, с которой вы имеете дело. Таблицу соответствия TTL и ОС можно найти здесь: http://www.kellyodonnell.com/content/determining-os-type-ping

Обнаружение службы не будет истинным, так как может быть Linux или другое окно, эмулирующее Windows FileSharing

использование systeminfo /s IPADDRESS Команда оболочки с Windows Machine для надежного извлечения подробных сведений об удаленной ОС 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"); }
Другие вопросы по тегам