c# c++ winapi networking

c# - ¿Cómo obtener una lista de las computadoras de la red local?



c++ winapi (5)

Estoy tratando de obtener una lista de las computadoras de la red local. Traté de utilizar NetServerEnum y WNetOpenEnum API, pero ambas API devuelven el código de error 6118 (ERROR_NO_BROWSER_SERVERS_FOUND) . Active Directory en la red local no se usa.

Lo más extraño de Windows Explorer muestra todas las computadoras locales sin ningún problema.

¿Hay otras maneras de obtener una lista de computadoras en la LAN?


Hice una función de eso. SchemaClassName tiene que ser una computadora

public List<string> NetworkComputers() { return ( from Computers in (new DirectoryEntry("WinNT:")).Children from Computer in Computers.Children where Computer.SchemaClassName == "Computer" orderby Computer.Name select Computer.Name).ToList; }


Encontré una solución usando la interfaz IShellItem con CSIDL_NETWORK. Tengo todas las PC de red.

C ++: use el método IShellFolder :: EnumObjects

C #: puede usar Gong Solutions Shell Library

using System.Collections; using System.Collections.Generic; using GongSolutions.Shell; using GongSolutions.Shell.Interop; public sealed class ShellNetworkComputers : IEnumerable<string> { public IEnumerator<string> GetEnumerator() { ShellItem folder = new ShellItem((Environment.SpecialFolder)CSIDL.NETWORK); IEnumerator<ShellItem> e = folder.GetEnumerator(SHCONTF.FOLDERS); while (e.MoveNext()) { Debug.Print(e.Current.ParsingName); yield return e.Current.ParsingName; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }


Use el espacio de nombres System.DirectoryService y pruebe lo siguiente

DirectoryEntry root = new DirectoryEntry("WinNT:"); foreach (DirectoryEntry computers in root.Children) { foreach (DirectoryEntry computer in computers.Children) { if (computer.Name != "Schema") { textBox1.Text += computer.Name + "/r/n"; } } }

Funcionó para mí


Una extensión menor a la respuesta de toddmo, si realmente no le gusta la sintaxis de estilo de consulta LINQ y desea incluir también grupos de trabajo como una opción:

public IEnumerable<string> VisibleComputers(bool workgroupOnly = false) { Func<string, IEnumerable<DirectoryEntry>> immediateChildren = key => new DirectoryEntry("WinNT:" + key) .Children .Cast<DirectoryEntry>(); Func<IEnumerable<DirectoryEntry>, IEnumerable<string>> qualifyAndSelect = entries => entries.Where(c => c.SchemaClassName == "Computer") .Select(c => c.Name); return ( !workgroupOnly ? qualifyAndSelect(immediateChildren(String.Empty) .SelectMany(d => d.Children.Cast<DirectoryEntry>())) : qualifyAndSelect(immediateChildren("//WORKGROUP")) ).ToArray(); }


Aquí una propiedad que utiliza una consulta LINQ

private List<string> NetworkHosts { get { var result = new List<string>(); var root = new DirectoryEntry("WinNT:"); foreach (DirectoryEntry computers in root.Children) { result.AddRange(from DirectoryEntry computer in computers.Children where computer.Name != "Schema" select computer.Name); } return result; } }