Handling Process Elevation and Running Modules as Administrator in PowerToys

PowerToys detects administrator rights through a lightweight IElevationHelper interface that checks the Windows principal at startup, registers the result via dependency injection, and gates privileged file operations like editing the hosts file or system environment variables based on this read-only flag.

Microsoft PowerToys requires administrator privileges to perform system-level modifications such as updating the hosts file or editing system environment variables. The solution implements a clean abstraction layer that isolates Windows-specific elevation checks into a testable helper class, allowing modules to query IsElevated without directly invoking platform APIs.

Detecting Administrator Rights with IElevationHelper

PowerToys centralizes elevation detection in the ElevationHelper class, which implements the minimal IElevationHelper interface. This interface exposes a single read-only boolean property that captures the process elevation state at construction time.

The concrete implementation checks the current Windows principal using standard .NET security APIs:

_isElevated = new WindowsPrincipal(WindowsIdentity.GetCurrent())
              .IsInRole(WindowsBuiltInRole.Administrator);

This logic appears in both the Hosts and Environment Variables modules, each maintaining their own copy compiled into the respective UI projects:

Wiring Elevation State via Dependency Injection

Each module registers the elevation helper with the built-in Microsoft.Extensions.DependencyInjection container during application startup. This registration occurs in the App.xaml.cs files using singleton lifetime to ensure consistent state across the process:

services.AddSingleton<IElevationHelper, ElevationHelper>();

Specific registration locations include:

Modules retrieve the helper via the service locator pattern using Host.GetService<IElevationHelper>() or App.GetService<IElevationHelper>(). This decouples UI code from the concrete Windows-specific implementation while enabling unit tests to inject mocks.

Propagating Elevation Status to the UI Layer

The global settings model mirrors the elevation flag so the Settings UI can react instantly to privilege changes. The GeneralSettings class stores this state at src/settings-ui/Settings.UI.Library/GeneralSettings.cs (line 40), while the GeneralViewModel exposes it to the view layer at src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs (lines 450-473).

When PowerToys launches, the runner passes elevation status to the Settings UI via the ElevatedStatus command-line argument. The Settings App stores this value in App.IsElevated during startup at src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs (line 196), ensuring the UI accurately reflects whether the current session possesses administrative rights.

Gating Privileged Operations

Modules guard privileged actions by checking IElevationHelper.IsElevated before executing system-level modifications. In the Hosts module, the service refuses to write the hosts file when running without elevation:

if (!_elevationHelper.IsElevated)
{
    // abort or request elevation
}

This guard appears at src/modules/Hosts/HostsUILib/Helpers/HostsService.cs (line 123). Similarly, the Environment Variables UI only enables editing of system-level variables when ElevationHelper.ElevationHelperInstance.IsElevated returns true, preventing unauthorized modifications to machine-wide configuration.

Restarting PowerToys with Maintained Elevation

PowerToys supports restarting the application while preserving administrator privileges through an IPC-based restart protocol. When a user clicks Restart as administrator, the GeneralViewModel constructs a specific action message:

var msg = ActionMessage.Create("restart_maintain_elevation");
var json = JsonSerializer.Serialize(msg, 
            SourceGenerationContextContext.Default.ActionMessage);
// send via IPC to the runner...

This implementation resides at src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs (lines 1321-1343). The runner receives the message, relaunches the executable with the runas verb, and updates GeneralSettings.IsElevated to reflect the new elevated state.

Unit Testing Elevated Code Paths

All privileged execution paths are covered by unit tests that inject mock implementations of IElevationHelper. Test suites use Mock<IElevationHelper> to simulate both elevated and non-elevated states without requiring actual administrator privileges or Windows API calls.

The Hosts module demonstrates this pattern at src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs, where tests verify that file write operations are correctly blocked or allowed based on the mocked elevation status. The Environment Variables module follows an identical testing strategy, ensuring reliable validation of permission-dependent functionality.

Summary

  • ElevationHelper encapsulates Windows-specific administrator detection in a testable interface (IElevationHelper) with a single IsElevated property.
  • Modules register the helper via dependency injection in their App.xaml.cs startup files, retrieving it through the service locator pattern to maintain loose coupling.
  • The Settings UI synchronizes elevation state through GeneralSettings and command-line arguments, enabling real-time UI updates based on privilege levels.
  • Privileged operations in HostsService.cs and Environment Variables explicitly check IsElevated before modifying protected system files or variables.
  • Restart with elevation uses IPC messages (restart_maintain_elevation) to relaunch the process with the runas verb while maintaining configuration state.
  • Comprehensive unit testing employs mocked elevation helpers to verify behavior in both administrative and standard user contexts without requiring actual privilege changes.

Frequently Asked Questions

How does PowerToys check if it is running as administrator?

PowerToys checks administrator status by constructing a WindowsPrincipal from the current identity and testing for the WindowsBuiltInRole.Administrator role. This logic resides in the ElevationHelper class at src/modules/Hosts/HostsUILib/Helpers/ElevationHelper.cs, which exposes the result through the IElevationHelper.IsElevated interface property.

Why does PowerToys use dependency injection for elevation detection?

The project uses Microsoft.Extensions.DependencyInjection to register IElevationHelper as a singleton, allowing modules to query elevation status without directly referencing Windows security APIs. This architecture keeps platform-specific code isolated to a few files while enabling test doubles (mocks) for unit testing, as seen in HostsServiceTest.cs.

How does the Settings UI know whether PowerToys is elevated?

The PowerToys runner passes the current elevation status via the ElevatedStatus command-line argument when launching the Settings UI. The Settings App stores this value in App.IsElevated during startup at src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs (line 196), and the GeneralViewModel exposes it to the interface through GeneralSettings.IsElevated.

Can PowerToys restart itself with administrator privileges?

Yes. When a user selects Restart as administrator, the GeneralViewModel sends an IPC message named restart_maintain_elevation to the runner. The runner then relaunches the PowerToys executable using the runas verb, preserving the current configuration while acquiring elevated rights for the new process instance.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →