Some actions require a process to run with administrator rights – for example, writing a registry key in HKLM, changing system settings, or writing a file to Program Files. Avoid this when possible, but sometimes it is necessary.
#Check if the current process run as administrator
There are multiple ways to check whether a process runs as administrator:
C#
public bool IsCurrentProcessAdmin()
{
using var identity = System.Security.Principal.WindowsIdentity.GetCurrent();
var principal = new System.Security.Principal.WindowsPrincipal(identity);
return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
}
C#
[DllImport("shell32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsUserAnAdmin();
static bool IsCurrentProcessAdmin()
{
return IsUserAnAdmin();
}
These methods check whether the current process is running as Administrator. They do not check whether the current user is a member of the Administrators group. Due to User Account Control (UAC), an administrator can run a process without elevated privileges.
The next section explains how UAC works, followed by how to check whether the current user is a member of the Administrators group.
#User Account Control (UAC) & Access token
When you log on, Windows generates an access token containing your security information: identity, groups, privileges, and so on. When you start a process, this token is associated with it. When the process accesses a resource, Windows uses the token to determine whether access is allowed.
When UAC is enabled, Windows generates two access tokens at logon: an administrator token and a standard user token. The standard user token strips all elevated groups and privileges. By default, Windows uses the standard user token when creating processes, which prevents applications from making harmful changes without your consent. To use the administrator token, right-click the application and select "Run as Administrator".
Source: How User Account Control works
You can inspect a process's access token using Process Explorer. In the screenshot below, the admin token is on the left and the filtered token is on the right, showing the difference for the BUILTINS\Administrators group.
the administrator token on the left, the filtered token on the right
In the standard user access token, the BUILTIN\Administrators group has the Deny flag. This means the group is only evaluated against "Deny" rules in ACLs and cannot satisfy "Allow" rules. As a result, a process using the standard user token is not considered to have administrator rights.
#Check if the current user is an administrator
Windows provides an API to query access token information (GetTokenInformation). I have written a .NET library that wraps this API: Meziantou.Framework.Win32.AccessToken (NuGet package, GitHub)
First, add the NuGet package to your project:
csproj (MSBuild project file)
<PackageReference Include="Meziantou.Framework.Win32.AccessToken" Version="1.1.5" />
Then, query the access token to check whether it is a filtered token:
C#
using var token = AccessToken.OpenCurrentProcessToken(TokenAccessLevels.Query);
var isRestricted = token.GetElevationType() == TokenElevationType.Limited;
You can also retrieve the administrator access token (linked token) and check whether it contains the BUILTINS\Administrators group:
C#
public static bool IsUserAdministrator()
{
using var token = AccessToken.OpenCurrentProcessToken(TokenAccessLevels.Query);
if (!IsAdministrator(token) && token.GetElevationType() == TokenElevationType.Limited)
{
using var linkedToken = token.GetLinkedToken();
return IsAdministrator(linkedToken);
}
return false;
static bool IsAdministrator(AccessToken accessToken)
{
var adminSid = SecurityIdentifier.FromWellKnown(WellKnownSidType.WinBuiltinAdministratorsSid);
foreach (var group in accessToken.EnumerateGroups())
{
if (group.Attributes.HasFlag(GroupSidAttributes.SE_GROUP_ENABLED) && group.Sid == adminSid)
return true;
}
return false;
}
}
#Restart the process as Administrator
If the current process is using the standard user token and you need administrator rights, you must start a new process. Set the Verb property of ProcessStartInfo to runas to request elevation:
C#
var args = Environment.GetCommandLineArgs();
var psi = new ProcessStartInfo
{
FileName = args[0],
UseShellExecute = true,
Verb = "runas", // Indicate to run the process as admin
};
// Copy the arguments of the command line
foreach (var arg in args.Skip(1))
{
psi.ArgumentList.Add(arg);
}
Process.Start(psi); // Start the new process
Environment.Exit(0); // Terminate the current process
This causes Windows to behave as if the process was launched from Explorer with the "Run as Administrator" command, displaying a UAC consent prompt.
#Use an application manifest to require administrator rights
If your application always requires administrator rights, you can embed an application manifest.
Add a new file of type "Application Manifest File" to create app.manifest, then set <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />:
XML
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- 👇 Add this line -->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Windows displays a UAC prompt each time the user starts the program.
Do you have a question or a suggestion about this post? Contact me!