在.NET / C#中testing进程是否具有pipe理权限

有没有规范的方法来testing,以查看过程是否在计算机上具有pipe理权限?

我将要开始一个漫长的运行过程,在这个过程的很长一段时间里,它将尝试一些需要pipe理员权限的事情。

如果stream程拥有这些权利,而不是以后,我希望能够事先进行testing。

这将检查用户是否在本地pipe理员组(假设您没有检查域pipe理员权限)

using System.Security.Principal; public bool IsUserAdministrator() { //bool value to hold our return value bool isAdmin; WindowsIdentity user = null; try { //get the currently logged in user user = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(user); isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator); } catch (UnauthorizedAccessException ex) { isAdmin = false; } catch (Exception ex) { isAdmin = false; } finally { if (user != null) user.Dispose(); } return isAdmin; } 

从Wadih M的代码开始,我有一些额外的P / Invoke代码来尝试处理UAC打开的情况。

http://www.davidmoore.info/blog/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/

首先,我们需要一些代码来支持GetTokenInformation API调用:

 [DllImport("advapi32.dll", SetLastError = true)] static extern bool GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength); /// <summary> /// Passed to <see cref="GetTokenInformation"/> to specify what /// information about the token to return. /// </summary> enum TokenInformationClass { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, TokenOrigin, TokenElevationType, TokenLinkedToken, TokenElevation, TokenHasRestrictions, TokenAccessInformation, TokenVirtualizationAllowed, TokenVirtualizationEnabled, TokenIntegrityLevel, TokenUiAccess, TokenMandatoryPolicy, TokenLogonSid, MaxTokenInfoClass } /// <summary> /// The elevation type for a user token. /// </summary> enum TokenElevationType { TokenElevationTypeDefault = 1, TokenElevationTypeFull, TokenElevationTypeLimited } 

然后,检测用户是否是pipe理员的实际代码(如果是则返回true,否则为false)。

 var identity = WindowsIdentity.GetCurrent(); if (identity == null) throw new InvalidOperationException("Couldn't get the current user identity"); var principal = new WindowsPrincipal(identity); // Check if this user has the Administrator role. If they do, return immediately. // If UAC is on, and the process is not elevated, then this will actually return false. if (principal.IsInRole(WindowsBuiltInRole.Administrator)) return true; // If we're not running in Vista onwards, we don't have to worry about checking for UAC. if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6) { // Operating system does not support UAC; skipping elevation check. return false; } int tokenInfLength = Marshal.SizeOf(typeof(int)); IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength); try { var token = identity.Token; var result = GetTokenInformation(token, TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, out tokenInfLength); if (!result) { var exception = Marshal.GetExceptionForHR( Marshal.GetHRForLastWin32Error() ); throw new InvalidOperationException("Couldn't get token information", exception); } var elevationType = (TokenElevationType)Marshal.ReadInt32(tokenInformation); switch (elevationType) { case TokenElevationType.TokenElevationTypeDefault: // TokenElevationTypeDefault - User is not using a split token, so they cannot elevate. return false; case TokenElevationType.TokenElevationTypeFull: // TokenElevationTypeFull - User has a split token, and the process is running elevated. Assuming they're an administrator. return true; case TokenElevationType.TokenElevationTypeLimited: // TokenElevationTypeLimited - User has a split token, but the process is not running elevated. Assuming they're an administrator. return true; default: // Unknown token elevation type. return false; } } finally { if (tokenInformation != IntPtr.Zero) Marshal.FreeHGlobal(tokenInformation); } 

如果您想确保您的解决scheme在Vista UAC中有效,并且具有.Net Framework 3.5或更高版本,则可能需要使用System.DirectoryServices.AccountManagement命名空间。 你的代码看起来像这样:

 bool isAllowed = false; using (PrincipalContext pc = new PrincipalContext(ContextType.Machine, null)) { UserPrincipal up = UserPrincipal.Current; GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "Administrators"); if (up.IsMemberOf(gp)) isAllowed = true; } 

使用.NET Framework 4.5,似乎更容易检查用户是否在pipe理员组中:

 WindowsPrincipal principal = WindowsPrincipal.Current; bool canBeAdmin = principal.Claims.Any((c) => c.Value == "S-1-5-32-544"); 

试过Erwin的代码,但没有编译。

得到这样的工作:

 [DllImport("shell32.dll")] public static extern bool IsUserAnAdmin(); 

使用可以使用类似这样的WMI来找出该帐户是否是pipe理员,以及其他任何你想了解的帐户

 using System; using System.Management; using System.Windows.Forms; namespace WMISample { public class MyWMIQuery { public static void Main() { try { ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_UserAccount"); foreach (ManagementObject queryObj in searcher.Get()) { Console.WriteLine("-----------------------------------"); Console.WriteLine("Win32_UserAccount instance"); Console.WriteLine("-----------------------------------"); Console.WriteLine("AccountType: {0}", queryObj["AccountType"]); Console.WriteLine("FullName: {0}", queryObj["FullName"]); Console.WriteLine("Name: {0}", queryObj["Name"]); } } catch (ManagementException e) { MessageBox.Show("An error occurred while querying for WMI data: " + e.Message); } } } } 

为了更容易开始下载WMI Creator

您也可以使用它访问活动目录(LDAP)或您计算机/networking上的任何其他内容

利用IsInRole方法的其他答案只会在用户使用提升标记运行时返回true,正如其他人所评论的那样。 以下是在标准和高级环境中检查本地pipe理员组成员的潜在替代方法:

 bool isAdmin = false; using (var user = WindowsIdentity.GetCurrent()) { var principal = new WindowsPrincipal(user); // Check for token claim with well-known Administrators group SID const string LOCAL_ADMININSTRATORS_GROUP_SID = "S-1-5-32-544"; if (principal.Claims.SingleOrDefault(x => x.Value == LOCAL_ADMININSTRATORS_GROUP_SID) != null) { isAdmin = true; } } return isAdmin; 

关于什么:

 using System.Runtime.InteropServices; internal static class Useful { [DllImport("shell32.dll", EntryPoint = "IsUserAnAdmin")] public static extern bool IsUserAnAdministrator(); } 

有4种可能的方法 – 我更喜欢:

 (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator); 

这里是代码给你的当前用户的身份所有相关的索赔数据列表。

注意:WindowsPrincipal.Current .Claims和(新的WindowsPrincipal(WindowsIdentity.GetCurrent())之间返回的声明列表之间有很大的区别.Claims

 Console.WriteLine("press the ENTER key to start listing user claims:"); Console.ReadLine(); Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); bool canBeAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator); Console.WriteLine("GetCurrent IsInRole: canBeAdmin:{0}", canBeAdmin); Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); canBeAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).Claims.Any((c) => c.Value == "S-1-5-32-544"); Console.WriteLine("GetCurrent Claim: canBeAdmin?:{0}", canBeAdmin); Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); canBeAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole("Administrator"); Console.WriteLine("GetCurrent IsInRole \"Administrator\": canBeAdmin?:{0}", canBeAdmin); Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); canBeAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole("Admin"); Console.WriteLine("GetCurrent IsInRole \"Admin\": canBeAdmin?:{0}", canBeAdmin); Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); canBeAdmin = WindowsPrincipal.Current.IsInRole("Admin"); Console.WriteLine("Current IsInRole \"Admin\": canBeAdmin:{0}", canBeAdmin); Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); canBeAdmin = WindowsPrincipal.Current.IsInRole("Administrator"); Console.WriteLine("Current IsInRole \"Administrator\": canBeAdmin:{0}", canBeAdmin); Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); canBeAdmin = WindowsPrincipal.Current.Claims.Any((c) => c.Value == "S-1-5-32-544"); Console.WriteLine("Current Claim: canBeAdmin?:{0}", canBeAdmin); Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); Console.WriteLine("WindowsPrincipal Claims:"); Console.WriteLine("---------------------"); var propertyCount = 0; foreach (var claim in WindowsPrincipal.Current.Claims) { Console.WriteLine("{0}", propertyCount++); Console.WriteLine("{0}", claim.ToString()); Console.WriteLine("Issuer:{0}", claim.Issuer); Console.WriteLine("Subject:{0}", claim.Subject); Console.WriteLine("Type:{0}", claim.Type); Console.WriteLine("Value:{0}", claim.Value); Console.WriteLine("ValueType:{0}", claim.ValueType); } Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); Console.WriteLine("WindowsPrincipal Identities Claims"); Console.WriteLine("---------------------"); propertyCount = 0; foreach (var identity in WindowsPrincipal.Current.Identities) { int subPropertyCount = 0; foreach (var claim in identity.Claims) { Console.WriteLine("{0} {1}", propertyCount, subPropertyCount++); Console.WriteLine("{0}", claim.ToString()); Console.WriteLine("Issuer:{0}", claim.Issuer); Console.WriteLine("Subject:{0}", claim.Subject); Console.WriteLine("Type:{0}", claim.Type); Console.WriteLine("Value:{0}", claim.Value); Console.WriteLine("ValueType:{0}", claim.ValueType); } Console.WriteLine(); propertyCount++; } Console.WriteLine("---------------------"); Console.WriteLine("---------------------"); Console.WriteLine("Principal Id Claims"); Console.WriteLine("---------------------"); var p = new WindowsPrincipal(WindowsIdentity.GetCurrent()); foreach (var claim in (new WindowsPrincipal(WindowsIdentity.GetCurrent())).Claims) { Console.WriteLine("{0}", propertyCount++); Console.WriteLine("{0}", claim.ToString()); Console.WriteLine("Issuer:{0}", claim.Issuer); Console.WriteLine("Subject:{0}", claim.Subject); Console.WriteLine("Type:{0}", claim.Type); Console.WriteLine("Value:{0}", claim.Value); Console.WriteLine("ValueType:{0}", claim.ValueType); } Console.WriteLine("press the ENTER key to end"); Console.ReadLine();