Reputation: 6871
I am trying to get a list of local network computers. I tried to use NetServerEnum
and WNetOpenEnum
API, but both API return error code 6118 (ERROR_NO_BROWSER_SERVERS_FOUND)
. Active Directory in the local network is not used.
Most odd Windows Explorer shows all local computers without any problems.
Are there other ways to get a list of computers in the LAN?
Upvotes: 22
Views: 44641
Reputation: 359
You will need to use the System.DirectoryServices
namespace and try the following:
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";
}
}
}
It worked for me.
Upvotes: 16
Reputation: 370
Solution with LINQ lambda syntax and unmanaged resource resolver
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();
}
}
Upvotes: 1
Reputation: 2018
Here a property that uses a LINQ query
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;
}
}
Upvotes: 3
Reputation: 701
A minor extension to toddmo's answer, if you don't really like LINQ query style syntax and want to also include workgroups as an option:
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();
}
Upvotes: 2
Reputation: 22466
I made a function out of it. The SchemaClassName
has to be Computer
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;
}
Upvotes: 8
Reputation: 6871
I found solution using interface IShellItem with CSIDL_NETWORK. I get all network PC.
C++: use method IShellFolder::EnumObjects
C#: you can use 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();
}
}
Upvotes: 13