Как получить список компьютеров локальной сети?
Я пытаюсь получить список компьютеров локальной сети. Я попытался использовать API NetServerEnum
и WNetOpenEnum
, но оба API возвращают код ошибки 6118 (ERROR_NO_BROWSER_SERVERS_FOUND)
. Active Directory в локальной сети не используется.
Самый нечетный проводник Windows показывает все локальные компьютеры без каких-либо проблем.
Существуют ли другие способы получить список компьютеров в локальной сети?
Ответы
Ответ 1
Я нашел решение, используя интерфейс IShellItem с CSIDL_NETWORK. Я получаю весь сетевой компьютер.
С++: использовать метод IShellFolder:: EnumObjects
С#: вы можете использовать Библиотека решений Gong Solutions
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();
}
}
Ответ 2
Вам нужно будет использовать пространство имен 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";
}
}
}
Это сработало для меня.
Ответ 3
Я сделал из него какую-то функцию. 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;
}
Ответ 4
Незначительное расширение 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();
}
Ответ 5
Здесь свойство, использующее запрос 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;
}
}
Ответ 6
Решение с лямбда-синтаксисом LINQ и распознавателем неуправляемых ресурсов
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();
}
}