我正在尝试获取本地网络计算机的列表。我尝试使用
NetServerEnum
和 WNetOpenEnum
API,但这两个 API 都返回错误代码 6118 (ERROR_NO_BROWSER_SERVERS_FOUND)
。不使用本地网络中的 Active Directory。
最奇怪的 Windows 资源管理器显示所有本地计算机,没有任何问题。
还有其他方法获取局域网中的计算机列表吗?
您将需要使用
System.DirectoryServices
命名空间并尝试以下操作:
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";
}
}
}
它对我有用。
我找到了使用接口 IShellItem 和 CSIDL_NETWORK 的解决方案。我得到了所有网络PC。
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();
}
}
我用它做了一个函数。
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;
}
这里是使用 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;
}
}
如果您不太喜欢 LINQ 查询样式语法并且还希望将工作组作为选项包含在内,那么这是对 toddmo 答案的一个小扩展:
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();
}
使用 LINQ lambda 语法和非托管资源解析器的解决方案
public List<String> GetNetworkHostNames()
{
using (var directoryEntry = new DirectoryEntry("WinNT:"))
{
return directoryEntry
.Children
.Cast<DirectoryEntry>()
.SelectMany(x=>x.Children.Cast<DirectoryEntry>())
.Where(c => c.SchemaClassName == "Computer")
.Select(c => c.Name)
.ToList();
}
}