To enhance security, the operating systems of Vista and Windows 7 have added the UAC (User Account Control) mechanism. If UAC is enabled, even if the user logs on as administrator, by default, its applications cannot perform write operations on System directories, system registries, and other settings that may affect system operation. This mechanism greatly enhances the security of the system, but for application developers, we cannot force users to close UAC, but sometimes our applications need to run in Administrator mode, that is, if Windows 7 runs as administrator, how can we implement this function?
When we run some installation programs in win7, we will find that a dialog box pops up first, asking the user to confirm whether they agree to allow this program to change your computer configuration, however, this prompt is not displayed for the applications we write by default and cannot be run as administrator. This article describes how to set the C # program to prompt users to run with administrator privileges.
First, add an Application Manifest File to the project.
The default configuration is as follows:
<?xml version="1.0" encoding="utf-8"?><asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <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"> <!-- UAC Manifest Options If you want to change the Windows User Account Control level replace the requestedExecutionLevel node with one of the following. <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> If you want to utilize File and Registry Virtualization for backward compatibility then delete the requestedExecutionLevel node. --> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo></asmv1:assembly>
We can see that there is a requestedExecutionLevel item in this configuration, which is used to configure the execution permission level of the current application request. This item has three values to choose from, as shown in the following table:
Value |
Description |
Comment |
AsInvoker |
The application runs with the same access token as the parent process. |
Recommended for standard user applications. Do refractoring with internal elevation points, as per the guidance provided earlier in this document. |
HighestAvailable |
The application runs with the highest privileges the current user can obtain. |
Recommended for mixed-mode applications. Plan to refractor the application in a future release. |
RequireAdministrator |
The application runs only for administrators and requires that the application must be launched with the full access token of an administrator. |
Recommended for administrator only applications. Internal elevation points are not needed. The application is already running elevated. |
AsInvoker: If this option is selected, the application runs with the current permission.
HighestAvailable: this operation is run with the highest permissions available to the current user.
RequireAdministrator: this operation only runs as a system administrator.
The default value is asInvoker.
Both highestAvailable and requireAdministrator prompts you to obtain system administrator privileges. So what are the differences between the two options?
The difference between them is that if we do not log on with an administrator account, if the application is set to requireAdministrator, the application will directly run and fail to start. If it is set to highestAvailable, the application can run successfully, but it runs with the permissions of the current account rather than the system administrator. If we want the program to run during non-administrator login (some functions should be restricted in this case), we recommend using highestAvailable for configuration.
For more information about requestedExecutionLevel settings, see the following link:
Create and Embed an Application Manifest (UAC)
The modified configuration file is as follows:
<?xml version="1.0" encoding="utf-8"?><asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <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"> <!-- UAC Manifest Options If you want to change the Windows User Account Control level replace the requestedExecutionLevel node with one of the following. <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> If you want to utilize File and Registry Virtualization for backward compatibility then delete the requestedExecutionLevel node. --> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo></asmv1:assembly>
After the configuration file is modified, we run the application. A prompt box is displayed. Click Yes to continue running the program and obtain the privileges of the system administrator.
Next, let's take a look at how the program knows whether it is currently running as a system administrator or not:
public static bool IsAdministrator() { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); }
This code can be used to determine whether the current program runs under the privileges of the system administrator. If asInvoker is configured, false is returned for this function in win7, and true is returned for requireAdministrator.