2010-04-01 7 views
14

Estoy tratando de obtener una lista de las computadoras de la red local. Traté de usar 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.¿Cómo obtener la lista de las computadoras de la red local?

El 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?

+0

Esta es la misma pregunta básicamente: [http://stackoverflow.com/ questions/105676/get-a-list-of-all-computers-on-a-network-wo-dns] (http://stackoverflow.com/questions/105676/get-a-list-of-all-computers -on-a-network-wo-dns) – Avitus

+4

No. Nmap no es adecuado para mí. La salida de Parse de otro programa no es muy buena – KindDragon

Respuesta

10

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

C++: Método de uso IShellFolder :: EnumObjects

C#: se 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(); 
     } 
    } 
+1

El valor de 'CSIDL.NETWORK' es 18, ¿verdad? Lo mismo que 'Environment.SpecialFolder.NetworkShortcuts', ¿verdad? Entonces puedo usar .Net directo para esto, ¿verdad? – user34660

+0

@ user34660 Sí, si solo usa .Net 4.0 o superior (3.5 no lo admite) – KindDragon

11

utilizar el espacio de nombres System.DirectoryService y tratar el 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í .

+4

Hmm, también enumera todos los dominios: usuario y grupo de dominio – LuckyLikey

+1

Sí, es necesario agregar 'computer.SchemaClassName ==" Computer "' en esa declaración 'if'. De lo contrario, funciona muy bien! – vapcguy

5

Hice una función fuera de él. El SchemaClassName tiene que ser ordenador

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

Este funciona. Básicamente es la línea 'donde Computer.SchemaClassName ==" Computer "' que filtra a cada grupo y usuario de la red, que aún aparecerá en la lista de @Cynfeal, hasta que se modifique. – LuckyLikey

1

Una extensión menor a la respuesta de toddmo, si no lo hace realmente como sintaxis de estilo consulta LINQ y quiere 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(); 
    } 
1

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