需求:列出網路鄰居中的所有工作群組/網域、各群組下的電腦名稱、以及本機或遠端電腦的共享資料夾。.NET 提供兩大技術棧:
Win32_Share 取得共享資料夾資訊。using System.DirectoryServices;
public class NetworkBrowser {
public List GetNetworkTopology() {
var result = new List();
using (var root = new DirectoryEntry("WinNT:")) { // 根節點:網路鄰居
foreach (DirectoryEntry domain in root.Children) {
// domain.Name 為工作群組或網域名稱
var wg = new WorkgroupInfo { Name = domain.Name, Computers = new List() };
foreach (DirectoryEntry computer in domain.Children) {
// 僅處理電腦物件
if (computer.SchemaClassName.Equals("Computer", StringComparison.OrdinalIgnoreCase)) {
wg.Computers.Add(computer.Name);
}
}
result.Add(wg);
}
}
return result;
}
}
public class WorkgroupInfo {
public string Name { get; set; }
public List Computers { get; set; }
}
using System.Management;
public List GetShares(string computerName = ".") {
var shares = new List();
// "." 代表本機,遠端電腦需格式 @"\\ServerName\root\cimv2"
string scope = computerName == "." ? @"root\cimv2" : $@"\\{computerName}\root\cimv2";
// 遠端連線需 ConnectionOptions (帳號/密碼/權限)
var options = new ConnectionOptions {
// Username = "admin", Password = "pwd", Authority = "ntlmdomain:DOMAIN"
Impersonation = ImpersonationLevel.Impersonate,
Authentication = AuthenticationLevel.PacketPrivacy
};
using (var mgmtScope = new ManagementScope(scope, options)) {
mgmtScope.Connect();
var query = new ObjectQuery("SELECT Name, Path, Description, Type FROM Win32_Share");
using (var searcher = new ManagementObjectSearcher(mgmtScope, query)) {
foreach (ManagementObject share in searcher.Get()) {
shares.Add(new ShareInfo {
Name = share["Name"]?.ToString() ?? "",
Path = share["Path"]?.ToString() ?? "",
Description = share["Description"]?.ToString() ?? "",
Type = ParseShareType(share["Type"])
});
}
}
}
return shares;
}
private string ParseShareType(object typeObj) {
if (typeObj == null) return "Unknown";
// Win32_Share Type: 0=Disk, 1=Print, 2=Device, 3=IPC, 2147483648=Admin
return typeObj.ToString() switch {
"0" => "Disk",
"1" => "Print",
"2" => "Device",
"3" => "IPC",
"2147483648" => "Admin$",
_ => "Other"
};
}
public class ShareInfo {
public string Name { get; set; }
public string Path { get; set; }
public string Description { get; set; }
public string Type { get; set; }
}
private void LoadNetworkTree() {
tvNetwork.Nodes.Clear();
var browser = new NetworkBrowser();
var topology = browser.GetNetworkTopology();
foreach (var wg in topology) {
var wgNode = tvNetwork.Nodes.Add(wg.Name, wg.Name);
wgNode.Tag = "Workgroup";
foreach (var comp in wg.Computers) {
var compNode = wgNode.Nodes.Add(comp, comp);
compNode.Tag = "Computer";
compNode.Nodes.Add("Shares", "共享資料夾 (點擊展開)"); // 虛擬節點,延遲載入
}
}
}
private void tvNetwork_BeforeExpand(object sender, TreeViewCancelEventArgs e) {
if (e.Node.Tag?.ToString() == "Computer" && e.Node.Nodes.Count == 1 && e.Node.Nodes[0].Name == "Shares") {
e.Node.Nodes.Clear(); // 移除虛擬節點
string compName = e.Node.Name;
var shares = new NetworkBrowser().GetShares(compName);
foreach (var sh in shares) {
var shareNode = e.Node.Nodes.Add(sh.Name, $"{sh.Name} ({sh.Type}) - {sh.Path}");
shareNode.Tag = "Share";
shareNode.ToolTipText = sh.Description;
}
}
}
| 議題 | 說明與對策 |
|---|---|
| WinNT 提供者限制 | 僅能列舉同網段/廣播域內的工作群組與電腦,無法跨路由器列舉 Active Directory 網域物件。跨網域需改用 LDAP 提供者 (LDAP://) 查詢 AD。 |
| WMI 遠端連線權限 | 需目標電腦開啟 WMI 服務、防火牆允許 WMI/RPC、呼叫端具備管理員權限或 DCOM 權限。建議提供 ConnectionOptions 參數化帳密。 |
| 效能與延遲 | 網路列舉涉及廣播與 RPC,耗時不可預測。UI 必須放入 BackgroundWorker/Task.Run 非同步執行,避免凍結主執行緒。 |
| 重複電腦名稱 | 不同工作群組可能有同名電腦,TreeView 節點 Key 需加前綴 (如 WORKGROUP1\PC01) 避免衝突。 |
| 共享類型過濾 | Win32_Share 包含管理用共享 (Admin$, C$, IPC$),UI 可依 Type 過濾僅顯示 Disk 類型。 |
| .NET Core / 5+ 相容性 | System.DirectoryServices、System.Management 需安裝對應 NuGet 套件 (System.DirectoryServices, System.Management),且僅支援 Windows 平台。 |
System.Net.NetworkInformation.Ping 掃描 IP 區段,配合 ARP 表解析 MAC/廠商。SharpCifs、SMBLibrary 等純 managed 實作,無需 WMI/DCOM,跨平台支援較好。System.DirectoryServices.Protocols (LdapConnection) 或 Microsoft.Graph (Azure AD)。結合 DirectoryServices (WinNT:) 列舉網域/電腦 與 WMI (Win32_Share) 獲取共享,即可構建功能完整的網路鄰居瀏覽器。注意權限、效能、平台相容性三大挑戰,並在 UI 採用非同步延遲載入,打造流暢好用的網路資產管理工具。