2010-04-01 116 views
14

我想獲得本地網絡計算機的列表。我嘗試使用NetServerEnumWNetOpenEnum API,但這兩個API都返回錯誤代碼6118 (ERROR_NO_BROWSER_SERVERS_FOUND)。本地網絡中的Active Directory未被使用。如何獲取本地網絡計算機的列表?

最奇怪的Windows資源管理器顯示所有本地計算機沒有任何問題。

是否有其他方法可以獲得局域網中的計算機列表?

+0

這是基本相同的問題: [http://stackoverflow.com/問題/ 105676/GET-A-列表中,所有的計算機上,一個網絡-WO-DNS(http://stackoverflow.com/questions/105676/get-a-list-of-all-computers -on-a-network-wo-dns) – Avitus 2010-04-01 01:08:51

+4

不,Nmap不適合我。解析其他程序的輸出效果不是很好 – KindDragon 2010-04-01 11:39:37

回答

10

我發現使用接口IShellItem與CSIDL_NETWORK的解決方案。我得到所有的網絡電腦。

C++:使用方法的IShellFolder :: EnumObjects

C#:您可以使用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的值是18,對不對?與'Environment.SpecialFolder.NetworkShortcuts'相同,對嗎?所以我可以直接使用.Net,對吧? – user34660 2018-01-02 10:03:09

+0

@ user34660是的,如果你只使用.Net 4.0或更高版本(3.5不支持它) – KindDragon 2018-01-29 09:20:36

11

使用System.DirectoryService命名空間和嘗試以下

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

它爲我。

+4

嗯它也列出每個域用戶和域組 – LuckyLikey 2015-06-24 09:47:06

+1

是的,需要添加'computer.SchemaClassName ==「計算機「'在那個if語句中。否則,偉大的作品! – vapcguy 2017-01-18 16:35:05

5

我做了一個函數。該SchemaClassName必須計算機

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

這一個工程。從本質上講,它的'Computer.SchemaClassName =='Computer''這一行會過濾掉網絡中的每個組和用戶,它們仍然會在@Cynfeal的awer中列出,直到它被修改爲止。 – LuckyLikey 2015-06-24 10:04:02

1

A小調擴展toddmo的答案,如果你真的不喜歡LINQ查詢風格的語法,並希望也包括工作組作爲一個選項:

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

這裏使用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; 
     } 
    } 
相關問題