2010-04-01 16 views
14

Yerel ağ bilgisayarlarının bir listesini almaya çalışıyorum. NetServerEnum ve WNetOpenEnum API'yi kullanmayı denedim, ancak her iki API dönüş hatası kodu 6118 (ERROR_NO_BROWSER_SERVERS_FOUND). Yerel ağdaki Active Directory kullanılmıyor.Yerel ağ bilgisayarlarının listesini nasıl alabilirim?

En garip Windows Gezgini, tüm yerel bilgisayarları sorunsuz bir şekilde gösterir.

LAN'daki bilgisayarların bir listesini almak için başka yollar var mı?

+0

Bu temelde aynı soru kullanır İşte özelliği: [http://stackoverflow.com/ sorular/105676/get-a-listesi-of-all-bilgisayarlar-on-a-ağa-wo-dns] (http://stackoverflow.com/questions/105676/get-a-list-of-all-computers -on ağ-wo-dns) – Avitus

+4

Hayır. Nmap benim için uygun değil. Diğer programdan ayrıştırma çok iyi değil – KindDragon

cevap

10

CSIDL_NETWORK ile IShellItem arabirimini kullanarak çözüm buldum. Tüm ağ bilgisayarlarım var.

C++: kullanım yöntemi IShellFolder :: EnumObjects

C#: Eğer System.DirectoryService ad kullanın 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

"CSIDL.NETWORK" değeri 18, değil mi? "Environment.SpecialFolder.NetworkShortcuts" ile aynı, değil mi? Yani bunun için doğru. Net kullanabilirim, değil mi? – user34660

+0

@ user34660 Evet, yalnızca .NET 4.0 veya üstü kullanıyorsanız (3.5 bunu desteklemiyorsa) – KindDragon

11

kullanabilir ve deneyebilirsiniz aşağıdaki

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"; 
     } 
    } 
} 
Benim için çalıştı

.

+4

Hmm, her Domain-User ve Domain-Grubunu da listelemektedir – LuckyLikey

+1

Evet, 'computer.SchemaClassName ==' bilgisayarını eklemeniz gerekir "Bu" ifadesinde. Aksi takdirde, harika çalışıyor! – vapcguy

5

Bunun dışında bir işlev yaptım.

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

Bu bir çalışır. Esas olarak, buradaki "Bilgisayarın Bilgisayarı" adlı dizini "Bilgisayar" 'ın bulunduğu, her bir grubu ve ağdaki kullanıcıyı filtreleyip, yine de bu değişime kadar @Cynfeal'ın anonim listesinde yer alacaktır. – LuckyLikey

1

toddmo cevabı minör uzantısı olmak zorunda bir LINQ sorgusu

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

: Eğer LINQ sorgu tarzı sözdizimi pek hoşlanmadığını ve ayrıca bir seçenek olarak çalışma grupları dahil etmek istiyorsanız SchemaClassName, Bilgisayar

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; 
    } 
İlgili konular