/// <summary> /// Returns a deduplicated list of all computers in the NetworkNeighborhood /// </summary> /// <returns>List of computers in the NetworkNeighborhood</returns> private async Task <ICollection <IPHostEntry> > GetHostsAsync() { if (!_browsers.Any()) { ServiceRegistration.Get <ILogger>().Error("NeighborhoodBrowserService: No Browsers enabled in NeighborhoodBrowserServiceSettings.xml"); return(new List <IPHostEntry>()); } var stopWatch = System.Diagnostics.Stopwatch.StartNew(); ICollection <IPHostEntry> result = null; var tasks = _browsers.Select(browser => browser.GetHostsAsync()).ToList(); try { await Task.WhenAll(tasks); result = Combine(tasks.Select(task => task.Result).ToList()); NeighborhoodBrowserHelper.LogResult(result, GetType().Name, stopWatch.ElapsedMilliseconds); } catch (Exception e) { ServiceRegistration.Get <ILogger>().Error("NeighborhoodBrowserService: Error collecting neighborhood computers", e); } return(result); }
/// <summary> /// Asynchronously returns a collection of IPHostEntries of all computers found in the NetworkNeighborhood /// </summary> /// <returns></returns> private async Task<ICollection<IPHostEntry>> DoGetHostsAsync() { var stopWatch = Stopwatch.StartNew(); // Enumerate all computers in the NetworkNeighborhood for all Domains / Workgroups var hosts = new Dictionary<String, Task<IPHostEntry>>(); try { using (var root = new DirectoryEntry(PROVIDER_STRING)) { foreach (DirectoryEntry domain in root.Children) { using (domain) { foreach (DirectoryEntry computer in domain.Children) { using (computer) { if (computer.SchemaClassName == COMPUTER_OBJECT) { ServiceRegistration.Get<ILogger>().Info("DirectoryEntryNeighborhoodBrowser: Adding '{0}' to hosts list.", computer.Name); hosts[computer.Name] = Dns.GetHostEntryAsync(computer.Name); } } } } } } } catch (Exception e) { ServiceRegistration.Get<ILogger>().Error("DirectoryEntryNeighborhoodBrowser: Error while enumerating computers in the NetworkNeighborhood", e); } // Wait until an IPHostEntry was found for all computers try { await Task.WhenAll(hosts.Values); } catch (System.Net.Sockets.SocketException) { } catch (Exception e) { ServiceRegistration.Get<ILogger>().Error("DirectoryEntryNeighborhoodBrowser: Error while getting IPHostEntries", e); } // Assemble the result var result = new HashSet<IPHostEntry>(); foreach (var kvp in hosts) { // If the call to GetHostEntryAsync was successful, we return the retrieved IPHostEntry // If not, we return a new IPHostEntry object just with its HostName property set. var host = kvp.Value.IsFaulted ? new IPHostEntry { HostName = kvp.Key } : kvp.Value.Result; NeighborhoodBrowserHelper.ConvertDnsHostNameToNetBiosName(host); result.Add(host); } NeighborhoodBrowserHelper.LogResult(result, GetType().Name, stopWatch.ElapsedMilliseconds); return result; }
/// <summary> /// Asynchronously returns a collection of IPHostEntries of all computers found in the NetworkNeighborhood /// </summary> /// <returns></returns> private async Task <ICollection <IPHostEntry> > DoGetHostsAsync() { var stopWatch = System.Diagnostics.Stopwatch.StartNew(); var networks = NetworkUtils.GetAllLocalIPv4Networks(); ServiceRegistration.Get <ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: Found {0} local IPv4 network(s) with IP address(es) {1}", networks.Count, String.Join(" / ", networks.Select(i => i.Address + " (" + i.IPv4Mask + ")"))); networks = RemoveLargeSubnets(networks); ServiceRegistration.Get <ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: {0} local IPv4 network(s) are used: {1}", networks.Count, String.Join(" / ", networks.Select(i => i.Address + " (" + i.IPv4Mask + ")"))); var tasks = new Dictionary <IPAddress, Task <NbNsNodeStatusResponse> >(); using (var client = new NbNsClient()) { foreach (var target in networks.SelectMany(NetworkUtils.GetAllAddressesInSubnet)) { if (!tasks.ContainsKey(target)) { tasks.Add(target, client.SendUnicastNodeStatusRequestAsync(NbNsNodeStatusRequest.WildCardNodeStatusRequest, target)); } } await Task.WhenAll(tasks.Values); // Uncomment the following two lines for extensive logging // foreach (var kvp in tasks.Where(kvp => kvp.Value.Result != null)) // ServiceRegistration.Get<ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: Found {0} ({1})\r\n{2}", kvp.Value.Result.WorkstationName, kvp.Key, kvp.Value.Result); } // If the computer has multiple network interfaces, it is found multiple times - once for each network interface. // Every occurence of the computer then has a different IP address (the one of the respective network interface). // As result we want this computer only as one IPHostEntry, but IPHostEntry.AddressList should show all IP addresses. var result = new HashSet <IPHostEntry>(); var responses = tasks.Where(kvp => kvp.Value.Result != null); foreach (var kvp in responses) { var alreadyPresentHost = result.FirstOrDefault(host => host.HostName == kvp.Value.Result.WorkstationName); if (alreadyPresentHost == null) { result.Add(new IPHostEntry { AddressList = new[] { kvp.Key }, HostName = kvp.Value.Result.WorkstationName }); } else { if (!alreadyPresentHost.AddressList.Any(address => address.Equals(kvp.Key))) { alreadyPresentHost.AddressList = alreadyPresentHost.AddressList.Union(new[] { kvp.Key }).ToArray(); } } } NeighborhoodBrowserHelper.LogResult(result, GetType().Name, stopWatch.ElapsedMilliseconds); return(result); }
/// <summary> /// Asynchronously returns a collection of IPHostEntries of all computers found in the NetworkNeighborhood /// </summary> /// <returns></returns> private async Task <ICollection <IPHostEntry> > DoGetHostsAsync() { var stopWatch = Stopwatch.StartNew(); // Enumerate all computers in the NetworkNeighborhood for all Domains / Workgroups var hosts = new Dictionary <String, Task <IPHostEntry> >(); ICollection <String> hostNames; // The WNetEnum API requires at least to be impersonated as NetworkService; this is the fallback credential used for // the root path of NetworkNeighborhoodResourceProvider if no other credentials have been entered. using (ServiceRegistration.Get <IImpersonationService>().CheckImpersonationFor(NetworkNeighborhoodResourceProvider.RootPath)) hostNames = NetworkResourcesEnumerator.EnumerateResources(ResourceScope.GlobalNet, ResourceType.Disk, ResourceUsage.All, ResourceDisplayType.Server); // The hostNames returned by the NetworkResourceEnumerator are in the form \\COMPUTERNAME // We have to remove the leading \\ to be able to pass the hostName to GetHostEntryAsync foreach (var hostName in hostNames) { hosts[hostName.Substring(2)] = Dns.GetHostEntryAsync(hostName.Substring(2)); } // Wait until an IPHostEntry was found for all computers try { await Task.WhenAll(hosts.Values); } catch (Exception e) { ServiceRegistration.Get <ILogger>().Error("WNetEnumNeighborhoodBrowser: Error while getting IPHostEntries", e.Message); } // Assemble the result var result = new HashSet <IPHostEntry>(); foreach (var kvp in hosts) { // If the call to GetHostEntryAsync was successful, we return the retrieved IPHostEntry // If not, we return a new IPHostEntry object just with its HostName property set. var host = kvp.Value.IsFaulted ? new IPHostEntry { HostName = kvp.Key } : kvp.Value.Result; NeighborhoodBrowserHelper.ConvertDnsHostNameToNetBiosName(host); result.Add(host); } NeighborhoodBrowserHelper.LogResult(result, GetType().Name, stopWatch.ElapsedMilliseconds); return(result); }