有没有办法让C#本地组和用户的列表,当Windows机器不是AD成员,并且LDAPsearch不能使用?
您可以使用P / Invoke调用本地网络管理API来获取本地用户名和组名:
static class NativeMethods { [DllImport("netapi32.dll")] public static extern void NetApiBufferFree(IntPtr bufptr); [DllImport("netapi32.dll")] public static extern UInt32 NetUserEnum([MarshalAs(UnmanagedType.LPWStr)] String servername, UInt32 level, UInt32 filter, ref IntPtr bufptr, UInt32 prefmaxlen, ref UInt32 entriesread, ref UInt32 totalentries, IntPtr resumehandle); [DllImport("netapi32.dll")] public static extern UInt32 NetLocalGroupEnum([MarshalAs(UnmanagedType.LPWStr)] String servername, UInt32 level, ref IntPtr bufptr, UInt32 prefmaxlen, ref UInt32 entriesread, ref UInt32 totalentries, IntPtr resumehandle); [DllImport("Netapi32.dll")] public extern static UInt32 NetLocalGroupGetMembers([MarshalAs(UnmanagedType.LPWStr)] String servername, [MarshalAs(UnmanagedType.LPWStr)] String localgroupname, UInt32 level, ref IntPtr bufptr, UInt32 prefmaxlen, ref UInt32 entriesread, ref UInt32 totalentries, IntPtr resumehandle); }
API可以让你获得有关用户的各种信息。 如果你只想要名字,你可以使用这个函数:
IEnumerable<String> GetUserNames() { var buffer = IntPtr.Zero; try { UInt32 entriesRead = 0; UInt32 totalEntries = 0; var result = NativeMethods.NetUserEnum(null, 0, 0, ref buffer, UInt32.MaxValue, ref entriesRead, ref totalEntries, IntPtr.Zero); if (result != 0) throw new Win32Exception((Int32) result); var userNames = Enumerable .Range(0, (Int32) entriesRead) .Select( i => { var userInfo = Marshal.ReadIntPtr(buffer, i*IntPtr.Size); var userName = Marshal.PtrToStringAuto(userInfo); return userName; } ) .ToList(); return userNames; } finally { NativeMethods.NetApiBufferFree(buffer); } }
LINQ语句用于“解析”包含USER_INFO_0
strutures的缓冲区。 如果你正在查询更多的信息,你将不得不做更详细的“解析”。
同样你可以得到本地组名:
IEnumerable<String> GetLocalGroupNames() { var buffer = IntPtr.Zero; try { UInt32 entriesRead = 0; UInt32 totalEntries = 0; var result = NativeMethods.NetLocalGroupEnum(null, 0, ref buffer, UInt32.MaxValue, ref entriesRead, ref totalEntries, IntPtr.Zero); if (result != 0) throw new Win32Exception((Int32) result); var localGroupNames = Enumerable .Range(0, (Int32) entriesRead) .Select( i => { var localGroupInfo = Marshal.ReadIntPtr(buffer, i*IntPtr.Size); var groupName = Marshal.PtrToStringAuto(localGroupInfo); return groupName; } ) .ToList(); return localGroupNames; } finally { NativeMethods.NetApiBufferFree(buffer); } }
缓冲区中的结构是LOCALGROUP_INFO_0
,其布局与USER_INFO_0
结构相同,所以“解析”代码是相同的。
最后,这里是如何使用LOCALGROUP_MEMBERS_INFO_3
结构获取组成员资格:
IEnumerable<String> GetLocalGroupUsers(String localGroupName) { var buffer = IntPtr.Zero; try { UInt32 entriesRead = 0; UInt32 totalEntries = 0; var result = NativeMethods.NetLocalGroupGetMembers(null, localGroupName, 3, ref buffer, UInt32.MaxValue, ref entriesRead, ref totalEntries, IntPtr.Zero); if (result != 0) throw new Win32Exception((Int32) result); var userNames = Enumerable .Range(0, (Int32) entriesRead) .Select( i => { var membersInfo = Marshal.ReadIntPtr(buffer, i*IntPtr.Size); var userName = Marshal.PtrToStringAuto(membersInfo ); return userName; } ) .ToList(); return userNames; } finally { NativeMethods.NetApiBufferFree(buffer); } }