Probar esto:
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
public static class UacHelper
{
private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
private const string uacRegistryValue = "EnableLUA";
private static uint STANDARD_RIGHTS_READ = 0x00020000;
private static uint TOKEN_QUERY = 0x0008;
private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength);
public enum TOKEN_INFORMATION_CLASS
{
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
}
public enum TOKEN_ELEVATION_TYPE
{
TokenElevationTypeDefault = 1,
TokenElevationTypeFull,
TokenElevationTypeLimited
}
public static bool IsUacEnabled
{
get
{
RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false);
bool result = uacKey.GetValue(uacRegistryValue).Equals(1);
return result;
}
}
public static bool IsProcessElevated
{
get
{
if (IsUacEnabled)
{
IntPtr tokenHandle;
if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle))
{
throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error());
}
TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault;
int elevationResultSize = Marshal.SizeOf((int)elevationResult);
uint returnedSize = 0;
IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize);
bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint)elevationResultSize, out returnedSize);
if (success)
{
elevationResult = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(elevationTypePtr);
bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull;
return isProcessAdmin;
}
else
{
throw new ApplicationException("Unable to determine the current elevation.");
}
}
else
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
bool result = principal.IsInRole(WindowsBuiltInRole.Administrator);
return result;
}
}
}
}
Marshal.SizeOf((int)elevationResult)
todavía no estoy seguro de por qué. El mensaje de excepción es: Método no encontrado. En:Int32 System.Runtime.InteropServices.Marshal.SizeOf(!!0).
(nueva respuesta seis años después de que se hizo la pregunta)
Descargo de responsabilidad: esto es solo algo que sucedió que funcionó en mi sistema operativo particular con mi configuración particular con mi usuario particular:
using System.Security.Principal; // ... static bool IsElevated { get { return WindowsIdentity.GetCurrent().Owner .IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid); } }
Entonces, cuando ejecuto este "Ejecutar como administrador", el descriptor de
get
acceso a la propiedad vuelvetrue
. Cuando se ejecuta normalmente (incluso si mi usuario "es" administrador, pero no ejecuta esta aplicación en particular "como administrador"), vuelvefalse
.Esto parece mucho más simple que muchas otras respuestas.
No tengo idea de si hay casos en los que esto falla.
¡PD! Esto también parece estar bien:
static bool IsElevated { get { var id = WindowsIdentity.GetCurrent(); return id.Owner != id.User; } }
fuente
IsElevated
devuelva falso, pero el proceso puede seguir ejecutándose con un nivel de integridad alto. Un proceso genuinamente no elevado tiene un nivel de integridad medio. Esto probablemente sea irrelevante para el 99% de las aplicaciones, pero vale la pena mencionarlo porque herramientas como Process Hacker aún pueden declarar que dicho proceso es elevado. Un proceso "semi-no elevado" no es algo que vería normalmente; puede ocurrir cuando alguien no inicia correctamente un proceso secundario no elevado.Aquí hay una versión modificada de esta respuesta para incluir cosas como la eliminación adecuada de recursos y el manejo de los administradores de dominio.
public static class UacHelper { private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; private const string uacRegistryValue = "EnableLUA"; private static uint STANDARD_RIGHTS_READ = 0x00020000; private static uint TOKEN_QUERY = 0x0008; private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(IntPtr hObject); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength); public enum TOKEN_INFORMATION_CLASS { 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 } public enum TOKEN_ELEVATION_TYPE { TokenElevationTypeDefault = 1, TokenElevationTypeFull, TokenElevationTypeLimited } public static bool IsUacEnabled { get { using (RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false)) { bool result = uacKey.GetValue(uacRegistryValue).Equals(1); return result; } } } public static bool IsProcessElevated { get { if (IsUacEnabled) { IntPtr tokenHandle = IntPtr.Zero; if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle)) { throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error()); } try { TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; int elevationResultSize = Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE)); uint returnedSize = 0; IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize); try { bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint) elevationResultSize, out returnedSize); if (success) { elevationResult = (TOKEN_ELEVATION_TYPE) Marshal.ReadInt32(elevationTypePtr); bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull; return isProcessAdmin; } else { throw new ApplicationException("Unable to determine the current elevation."); } } finally { if (elevationTypePtr != IntPtr.Zero) Marshal.FreeHGlobal(elevationTypePtr); } } finally { if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle); } } else { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); bool result = principal.IsInRole(WindowsBuiltInRole.Administrator) || principal.IsInRole(0x200); //Domain Administrator return result; } } } }
fuente
Marshal.SizeOf((int)elevationResult)
todavía no estoy seguro de por qué. El mensaje de excepción es: Método no encontrado. En:Int32 System.Runtime.InteropServices.Marshal.SizeOf(!!0).
Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE))
,int elevationResultSize = Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE))
lanza unaArgumentException
aplicación de 32 bits .NET 4.0int elevationResultSize = Marshal.SizeOf((int)elevationResult)
, sin embargo funcionó.El proyecto CodePlex UAChelper tiene un código que verifica la elevación en UserAccountControl.cpp
UserAccountControl::IsUserAdmin
, que verifica si UAC está habilitado y luego verifica si el proceso está elevado.bool UserAccountControl::IsCurrentProcessElevated::get() { return GetProcessTokenElevationType() == TokenElevationTypeFull; //elevated }
de la función:
int UserAccountControl::GetProcessTokenElevationType() { HANDLE hToken; try { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) throw gcnew Win32Exception(GetLastError()); TOKEN_ELEVATION_TYPE elevationType; DWORD dwSize; if (!GetTokenInformation(hToken, TokenElevationType, &elevationType, sizeof(elevationType), &dwSize)) throw gcnew Win32Exception(GetLastError()); return elevationType; } finally { CloseHandle(hToken); } }
fuente
En .net Framwork 4.5 encontré otro método que me funciona. En relación con el siguiente script que se puede encontrar aquí aquí (en alemán)
rem --- Admintest.bat --- whoami /groups | find "S-1-5-32-544" > nul if errorlevel 1 goto ende echo Benutzer %username% ist lokaler Administrator. :ende
En C # se ve así:
private bool IsAdmin { get { WindowsIdentity identity = WindowsIdentity.GetCurrent(); if (identity != null) { WindowsPrincipal principal = new WindowsPrincipal(identity); List<Claim> list = new List<Claim>(principal.UserClaims); Claim c = list.Find(p => p.Value.Contains("S-1-5-32-544")); if (c != null) return true; } return false; } }
Pero en .net <4.5 la
WindowsPrincipal
clase no contiene laUserClaims
propiedad y no encontré forma de obtener esta información.fuente
private bool IsAdmin{ get { ... } }
), entonces no necesita los corchetes si invocaIsAdmin
.El uso
TokenElevationType
funcionaría, pero si PInvokeCheckTokenMembership()
contra el SID del grupo de administración, su código también funcionaría cuando UAC está apagado y encendido 2000 / XP / 2003 y también manejará los SID denegados.También hay una
IsUserAnAdmin()
función que realiza laCheckTokenMembership
verificación por usted, pero MSDN dice que podría no estar allí para siempre.fuente
Esta respuesta tiene algunos problemas. Primero, no obtiene ningún proceso del sistema que se ejecute como administrador (por ejemplo, bajo NT-Authority / SYSTEM). El siguiente ejemplo de código corrige todos los problemas (detecta, LocalAdmins, DomainAdmins y LocalSystemAdmins)
Si solo desea el proceso actual, reemplácelo
pHandle
conProcess.GetCurrentProcess().Handle
internal static bool IsProcessElevatedEx(this IntPtr pHandle) { var token = IntPtr.Zero; if (!OpenProcessToken(pHandle, MAXIMUM_ALLOWED, ref token)) throw new Win32Exception(Marshal.GetLastWin32Error(), "OpenProcessToken failed"); WindowsIdentity identity = new WindowsIdentity(token); WindowsPrincipal principal = new WindowsPrincipal(identity); bool result = principal.IsInRole(WindowsBuiltInRole.Administrator) || principal.IsInRole(0x200); //Domain Administrator CloseHandle(token); return result; }
fuente
Creo que hay un problema más. Verifiqué las soluciones proporcionadas por usted y debo decir que en la instalación de Windows 7 e inicie sesión como administrador, la verificación no funciona. Windows nunca devuelve información de que el proceso se ejecuta en modo elevado. Entonces la secuencia:
if (IsUacEnabled) return IsProcessInElevatedMode(); return IsUserAdmin();
no devuelve verdadero cuando se registra como administrador, pero el proceso tiene todos los privilegios para realizar operaciones del sistema (por ejemplo, detener los servicios del sistema). La secuencia de trabajo es:
if (IsUserAdmin()) return true; if (IsUacEnabled) return IsProcessInElevatedMode(); return false;
Primero debe verificar si el proceso se ejecuta en el contexto del Administrador. Información adicional:
IsUacEnabled() - checks if the UAC has been enabled in the system (Windows) IsProcessInElevatedMode() - checks if the process is run in an elevated mode IsUserAdmin() - checks if the current user has an Administrtor role
Todos esos métodos se han descrito en publicaciones anteriores.
fuente
Usando el paquete nuget de UACHelper: https://www.nuget.org/packages/UACHelper/
if (UACHelper.IsElevated) // something else // something else
Hay muchas otras propiedades que pueden usarse para detectar si el usuario es, de hecho, un administrador, o si el proceso se está ejecutando bajo virtualización UAC, o si el propietario del escritorio es el propietario del proceso. (Ejecutar desde una cuenta limitada)
Consulte el léame para obtener más información.
fuente