Как найти ПК с 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"); }