C# 服务器下拉列表控件






4.13/5 (5投票s)
2001年2月2日

140086

2232
一个 C# 用户控件,用于枚举服务器并在下拉列表中显示列表
引言
以下示例代码展示了枚举域中服务器所需的 API 和代码。ServerType 枚举确定 NetServerEnum 调用的筛选器。
棘手的部分(我发现)是使用 unsafe
关键字来实际获取结构体数组的指针,然后将指针编组回托管代码中的字符串(服务器名称)。我花了几个小时才让它工作...但这种挫败感是值得的。
演示项目包含一个用户控件,该控件实现了 NetServerEnum API。控件的用户只需要设置 ServerType 属性,下拉菜单就会被填充。
public enum ServerTypeEnum { steNone = 0, steWorkstation = 0x00000001, steAll = 0x00000002, steSQLServer = 0x00000004, steDomainController = 0x00000008 } [sysimport(dll="netapi32.dll")] private static extern void NetApiBufferFree([marshal(UnmanagedType.U4)]uint bufptr); [sysimport(dll="netapi32.dll")] unsafe private static extern uint NetServerEnum([marshal(UnmanagedType.LPWStr)] string ServerName, uint level, [marshal(UnmanagedType.LPVoid)]uint* bufptr, uint prefmaxlen, ref uint entriesread, ref uint totalentries, uint servertype, [marshal(UnmanagedType.LPWStr)] string domain, uint resume_handle); [System.Runtime.InteropServices.StructLayoutAttribute (LayoutKind.Sequential, CharSet=CharSet.Auto)] public struct SERVER_INFO_101 { public int dwPlatformID; public int lpszServerName; public int dwVersionMajor; public int dwVersionMinor; public int dwType; public int lpszComment; } protected void GetServers() { string servername = null; string domain = "YourDomainName"; uint level = 101, prefmaxlen = 0xFFFFFFFF, entriesread = 0, totalentries = 0, resume_handle = 0; cboServers.Items.Clear(); unsafe { //get a pointer to the server info structure SERVER_INFO_101* si = null; SERVER_INFO_101* pTmp; //temp pointer for use when looping //through returned (pointer) array //this api requires a pointer to a byte array... //which is actually a pointer to an array of SERVER_INFO_101 structures //If the domain parameter is NULL, the primary domain is implied. uint nRes = NetServerEnum(servername, level, (uint *) &si, prefmaxlen, ref entriesread, ref totalentries, (uint)_ServerType, domain, resume_handle); if (nRes == 0) { if ((pTmp = si) != null) //assign the temp pointer { for (int i = 0; i < entriesread; i++) //loop through the entries { try { //the lpszServerName member of the structure contains a pointer to //the server name string...marshal the pointer from unmanaged //memory to a managed string cboServers.Items.Add(Marshal.PtrToStringAuto(pTmp->lpszServerName)); } catch (Exception e) { MessageBox.Show(e.Message) ; } pTmp++; // increment the pointer...essentially move to the next // structure in the array } } } NetApiBufferFree((uint)si); } }
历史
2002年5月30日 - 更新了源文件