Note: I only have one computer in my home network, so only one computer is shown in the screenshot above. It does work with many computers.
This submission was actually written as part of a University project for my BSc., where I was using .NET Remoting and I had a server application and a client application, and I needed the client application to be able to connect to a given server application.
The problem was, I did not know what machine name the server was running on, in fact I wanted this to be flexible, and selectable by the user. So after I searched the .NET documentation on MSDN and couldn't find any managed classes which dealt with network computers or anything like that, I consulted a C++ programming friend of mine (Nick Cross, you know who you are), who mentioned the NetApi32.dll and the
NetServerEnum method. After I looked at the NetApi32.dll documentation, it looked as though it seemed to provide a list network computer names. Lovely.
Eureka I thought, but then I had to trawl the MSDN documentation for the relevant structures and methods I need to consume the NetApi32.dll unmanaged methods within my C# (managed) code.
So this article is really a culmination of research and pain, that I had, trying to get my head around how to consume the NetApi32 C++ DLL within C#. It was not fun, but I got there in the end.
I hope this article helps someone out, as it helped me.
Using the code
The demo project provided actually contains all the source code needed. The demo is based on a simple Windows Forms application written in Visual Studio 2005. The code works the same in .NET v1.1.
So now onto the code. The main class is called
NetworkBrowser which really does all the work. The demo form is a throw away, which is simply used to demo the code submission.
#region NetworkBrowser CLASS
public sealed class NetworkBrowser
#region Dll Imports
[DllImport("Netapi32", CharSet = CharSet.Auto,
SetLastError = true),
public static extern int NetServerEnum(
string ServerNane, int dwLevel,
ref IntPtr pBuf,
out int dwEntriesRead,
out int dwTotalEntries,
string domain, out int dwResumeHandle
[DllImport("Netapi32", SetLastError = true),
public static extern int NetApiBufferFree(
public struct _SERVER_INFO_100
internal int sv100_platform_id;
internal string sv100_name;
#region Public Constructor
#region Public Methods
public ArrayList getNetworkComputers()
ArrayList networkComputers = new ArrayList();
const int MAX_PREFERRED_LENGTH = -1;
int SV_TYPE_WORKSTATION = 1;
int SV_TYPE_SERVER = 2;
IntPtr buffer = IntPtr.Zero;
IntPtr tmpBuffer = IntPtr.Zero;
int entriesRead = 0;
int totalEntries = 0;
int resHandle = 0;
int sizeofINFO = Marshal.SizeOf(typeof(_SERVER_INFO_100));
int ret = NetServerEnum(null, 100, ref buffer,
out totalEntries, SV_TYPE_WORKSTATION |
SV_TYPE_SERVER, null, out
if (ret == 0)
for (int i = 0; i < totalEntries; i++)
tmpBuffer = new IntPtr((int)buffer +
(i * sizeofINFO));
_SERVER_INFO_100 svrInfo = (_SERVER_INFO_100)
catch (Exception ex)
MessageBox.Show("Problem with acessing " +
"network computers in NetworkBrowser " +
"\r\n\r\n\r\n" + ex.Message,
I have tried to comment the code as much as possible, so I'll just let the code do the talking. You've heard enough about me.
Points of Interest
On a personal level, I have found this to be quite a rewarding exercise, and I found that consuming DLLs within C# is quite a black art. But in the end, it's all worth it.