using System; using System.ComponentModel; using System.Diagnostics; using System.Security.Principal; using Microsoft.Win32; using static Vanara.PInvoke.AdvApi32; namespace Vanara.Security { /// /// Provides information about the state of User Access Control for the system. /// public static partial class UAC { private static bool? enabled; /// /// Determines whether the provided process can be elevated. Effectively, this checks that UAC is available and that the process is running under an /// account that belongs to the Administrators group. /// /// The process. If this value is null, then the current process is used. /// true if this process can be elevated; otherwise, false. public static bool CanElevate(Process process = null) => IsEnabled() && IsRunningAsAdmin(process); /// Determines whether the specified process is elevated. /// The process. If this value is null, then the current process is used. /// true if the specified process is elevated; otherwise, false. public static bool IsElevated(Process process = null) { try { // Open the access token of the current process with TOKEN_QUERY. using (var hObject = SafeHTOKEN.FromProcess(process ?? Process.GetCurrentProcess(), TokenAccess.TOKEN_QUERY | TokenAccess.TOKEN_DUPLICATE)) return hObject.IsElevated; } catch { } return false; } /// Determines whether UAC is enabled on this system. /// true if UAC is enabled; otherwise, false. public static bool IsEnabled() { if (!enabled.HasValue) { if (Environment.OSVersion.Version.Major < 6) enabled = true; else enabled = Registry.GetValue( @"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System", "EnableLUA", 0).Equals(1); } return enabled.Value; } /// /// The function checks whether the primary access token of the process belongs to user account that is a member of the local Administrators group, /// even if it currently is not elevated. /// /// The process to check. /// /// Returns true if the primary access token of the process belongs to user account that is a member of the local Administrators group. Returns false /// if the token does not. /// public static bool IsRunningAsAdmin(Process proc = null) { SafeHTOKEN hObjectToCheck = null; // Open the access token of the current process for query and duplicate. using (var hObject = SafeHTOKEN.FromProcess(proc, TokenAccess.TOKEN_QUERY | TokenAccess.TOKEN_DUPLICATE)) { // Determine whether system is running Windows Vista or later operating systems (major version >= 6) because they support linked tokens, but // previous versions (major version < 6) do not. if (Environment.OSVersion.Version.Major >= 6) { // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET. var elevType = hObject.GetInfo(TOKEN_INFORMATION_CLASS.TokenElevationType); // If limited, get the linked elevated token for further check. if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) { // Marshal the linked token value from native to .NET. hObjectToCheck = new SafeHTOKEN(hObject.GetInfo(TOKEN_INFORMATION_CLASS.TokenLinkedToken).LinkedToken.DangerousGetHandle()); } } // CheckTokenMembership requires an impersonation token. If we just got a linked token, it already is an impersonation token. If we did not get a // linked token, duplicate the original into an impersonation token for CheckTokenMembership. if (hObjectToCheck == null) { if (!DuplicateToken(hObject, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, out hObjectToCheck)) throw new Win32Exception(); } } if (hObjectToCheck == null || hObjectToCheck.IsInvalid) return false; // Check if the token to be checked contains admin SID. using (hObjectToCheck) using (var id = new WindowsIdentity(hObjectToCheck.DangerousGetHandle())) return id.IsAdmin(); } /*/// Runs the current application elevated if it isn't already. This will close the current running instance. public static void RunCurrentApplicationElevated() { if (!WindowsIdentity.GetCurrent().IsAdmin()) { // Launch itself as administrator var proc = new ProcessStartInfo(System.Windows.Forms.Application.ExecutablePath) { UseShellExecute = true, WorkingDirectory = Environment.CurrentDirectory, Verb = "runas" }; try { Process.Start(proc); System.Windows.Forms.Application.Exit(); } catch { } } }*/ } }