Working with User Account Control in .NET apps

Sometimes when you are developing a Windows app you’ll find the need to run the application as a different user, often as the administrator.

Windows features a security mechanism called ‘User Account Control’ which prevents applications from launching with elevated privileges without the user’s consent.

In this article, I explain how User Account Control works and how you can work with it when building .NET apps.

User Account Control

User Account Control (or UAC for short) is a fundamental security feature within Windows that is primarily intended to prevent malicious programs from executing without your permission.

With UAC in place, neither malware nor any other program on your machine can launch with administrative privileges without your consent.

Visuals

The UAC feature displays a visual prompt before allowing a program to be run as an administrator.

Below are some examples of UAC prompts as displayed on Windows 10.

User Account Control examples
User Account Control prompt examples (source: Wikipedia)

As you can see from the above examples, the UAC prompt will display differently depending on the severity of the warning and how well (or not) Windows trusts the source of the app.

User contexts

Whenever you are logged onto a Windows machine, it is important to remember that even if your user account has administrative privileges i.e. is part of the Administrators group, your user account will run programs as a standard user by default.

This can cause a lot of confusion for some users who don’t understand why a program isn’t executing with administrative privileges, even though they are an administrator.

When a user with administrative privileges logs into Windows they are issued with both a standard user access token and an administrator access token.

The standard user access token is used when running programs that do not require admin rights. In order for a program to be launched as an administrator, the user must either request this action explicitly, or the application must automatically signal that it requires admin rights.

In either case, an elevation/UAC prompt will be displayed which the user must confirm prior to the application launching.

If the logged-in user has admin rights, then the prompt will be a simple Yes/No prompt. Otherwise, the user will be prompted to enter the username and password of an admin account.

Automatic elevation prompt

Ok, so most of us already know how to right-click on a program icon and launch it as an administrator explicitly. But what if we are developing a .NET app and we know that we’re going to need admin rights to do our thing?

In this case, we will need a way of automatically prompting the user to grant us the required permissions.

In the following section, I cover how to accomplish this using a manifest file.

Application Manifest File

By using an Application Manifest File, we can signal to Windows that our app needs to run in an admin context.

Apps that require admin rights tend to be programs that need to write files to restricted directories or access the Registry (think software update programs or utilities like CCleaner).

An Application Manifest File is an XML file with a specific structure that is inspected by Windows.

Creating a manifest

If you are using Visual Studio to create your app, adding a manifest file is very straightforward.

Within your solution right-click on the project node of your app then click on Add –> New Item…

From the ‘Add New Item’ window, type the text ‘manifest’ into the ‘Search’ box.

An item named ‘Application Manifest File’ should appear. Make sure it is selected and press the ‘Add’ button.

An ‘app.manifest’ file should now be visible within your project tree.

Sample manifest

Here’s what the default manifest file generated by Visual Studio looks like.

<?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">
        <!-- 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" />
 
            Specifying requestedExecutionLevel element will disable file and registry virtualization. 
            Remove this element if your application requires this virtualization for backwards
            compatibility.
        -->
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
 
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- A list of the Windows versions that this application has been tested on
           and is designed to work with. Uncomment the appropriate elements
           and Windows will automatically select the most compatible environment. -->
 
      <!-- Windows Vista -->
      <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
 
      <!-- Windows 7 -->
      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
 
      <!-- Windows 8 -->
      <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
 
      <!-- Windows 8.1 -->
      <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
 
      <!-- Windows 10 -->
      <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
 
    </application>
  </compatibility>
 
  <!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
       DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need 
       to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should 
       also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
  <!--
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>
  -->
 
  <!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
  <!--
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
  </dependency>
  -->
 
</assembly>

As you can see from the contents of the above manifest file, a manifest can be used to control many different aspects of a Windows app such as compatibility, DPI and theme settings.

Many of the XML elements are commented out and you can simply uncomment the relevant elements where appropriate.

Execution Levels

In this article, we are focusing on User Account Control so I would like to draw your attention to the requestedExecutionLevel element within the manifest file.

By default the requestedExecutionLevel is set to ‘asInvoker’ which means that the app will launch in the context of the current user (using their standard user access token).

The requestedExecutionLevel can also be set to ‘highestAvailable’ which will run the app using the highest privileges available to the current user. If the user is an admin they will get a UAC prompt, otherwise, the app will launch as a standard user.

If you want to ensure that your application will always run with admin rights, you should use the ‘requireAdministrator’ execution level. The user will always get a UAC prompt when using this setting. The only exception to this rule is in cases where UAC is turned off on the machine (not recommended!).

Note that you should never turn off User Account Control; you’ll end up with a much less secure system and put yourself at a higher risk of malware infection.

Test flight

Now that you have a manifest file in place and have configured the appropriate execution level, your app should now cause a UAC prompt to appear upon launch.

I recommend that you try out each of the available execution levels to see what effect they have and then decide on which one works best for your app.

If you’re interested you can find out more about manifest files in the Microsoft Docs and explore the full list of available settings and how each of them work.

Summary

We now know that User Account Control is a fundamental protection mechanism within Windows and it is essential that it is turned on at all times.

Windows apps run in the context of a standard user by default, even when the logged-in user is an administrator.

In order to execute in an administrative context, a Windows app must either be run as administrator explicitly by the user, or the user must grant permission via an elevation prompt which is signalled automatically by the app.

Lastly, we’ve seen how to work with User Account Control in .NET apps to trigger an elevation prompt on app start-up via the use of an Application Manifest File.


I hope you enjoyed this post! Comments are always welcome and I respond to all questions.

If you like my content and it helped you out, please check out the button below 🙂

Comments