En la prueba .NET / C # si el proceso tiene privilegios administrativos

¿Hay alguna manera canónica de probar para ver si el proceso tiene privilegios administrativos en una máquina?

Comenzaré un proceso de ejecución prolongada, y mucho más tarde en la vida del proceso se intentarán algunas cosas que requieren privilegios de administrador.

Me gustaría poder realizar una prueba inicial si el proceso tiene esos derechos en lugar de más adelante.

Esto verificará si el usuario está en el grupo de Administradores locales (suponiendo que no esté buscando permisos de administrador de dominio)

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; } 

Comenzando con el código de Wadih M, tengo un código de P / Invoke adicional para tratar de manejar el caso de cuando UAC está activado.

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

Primero, necesitaremos algún código para admitir la llamada a la API GetTokenInformation:

 [DllImport("advapi32.dll", SetLastError = true)] static extern bool GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength); ///  /// Passed to  to specify what /// information about the token to return. ///  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 } ///  /// The elevation type for a user token. ///  enum TokenElevationType { TokenElevationTypeDefault = 1, TokenElevationTypeFull, TokenElevationTypeLimited } 

Luego, el código real para detectar si el usuario es un administrador (devolviendo verdadero si lo son, de lo contrario es falso).

 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); } 

Si desea asegurarse de que su solución funcione en Vista UAC y tenga .Net Framework 3.5 o superior, es posible que desee utilizar el espacio de nombres System.DirectoryServices.AccountManagement. Tu código sería algo así como:

 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; } 

Usando .NET Framework 4.5, parece ser más fácil verificar si un usuario está en el grupo de administradores:

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

Probé el código de Erwin pero no compiló.

Tengo que funcionar así:

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

Otras respuestas que aprovechan el método IsInRole solo devuelven verdadero si el usuario se está ejecutando con un token elevado, como han comentado otros. Aquí hay una alternativa potencial para verificar la membresía del grupo de Administradores locales en un contexto estándar y elevado:

 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;