# Implementing Localization for PowerToys Modules Using .resx and .resw Files

> Learn to implement localization for PowerToys modules using .resx and .resw files. Discover how PowerToys manages culture-specific resources for a seamless user experience.

- Repository: [Microsoft/PowerToys](https://github.com/microsoft/PowerToys)
- Tags: how-to-guide
- Published: 2026-02-25

---

**PowerToys implements localization through standard .NET resource files, using `.resx` for WinForms modules and `.resw` for XAML-based Settings UI, accessed via strongly-typed designer classes or a singleton `ResourceLoader` that automatically loads culture-specific PRI packages based on the user's display language.**

PowerToys, Microsoft's open-source utility suite for Windows, supports multiple languages across its numerous C# modules by leveraging the standard .NET localization infrastructure. Whether you are contributing to the WinForms-based PowerRename utility or the WinUI XAML Settings interface, understanding how to properly implement localization for PowerToys modules using `.resx` and `.resw` files ensures your UI text displays correctly across all supported locales.

## Understanding Resource Types: .resx vs .resw

PowerToys uses two distinct resource file formats depending on the UI technology stack. The project structure separates these clearly to maintain compatibility with both classic Windows Forms and modern WinUI applications.

**`.resx` files** serve WinForms and classic .NET modules. These XML resource files live in paths like `src/modules/powerrename/dll/Resources.resx` and compile into strongly-typed C# accessor classes via `ResGen`. The auto-generated [`Resources.Designer.cs`](https://github.com/microsoft/PowerToys/blob/main/Resources.Designer.cs) exposes static properties such as `Resources.PowerRename_DeleteConfirmation` that map directly to resource keys.

**`.resw` files** support UWP and WinUI XAML interfaces, primarily in the Settings UI and Quick Access modules. Located in folders like `src/settings-ui/Settings.UI/Strings/en-us/Resources.resw`, these files require runtime resolution through `Windows.ApplicationModel.Resources.ResourceLoader` rather than compile-time properties.

Both formats ultimately package into **`.pri`** (Package Resource Index) files—such as `PowerToys.Settings.pri`—that Windows loads dynamically based on the current UI culture.

## How Resource Loading Works in PowerToys

The localization system operates through a predictable pipeline that handles culture resolution automatically without requiring runtime logic in individual modules.

1. **Base and satellite resources**: Each module includes a base English resource file plus optional culture-specific variants (e.g., `Resources.resx` → `Resources.fr.resx` or `Resources.resw` → `Resources.fr-FR.resw`).

2. **Designer generation**: MSBuild executes `GenerateResource` tasks to create strongly-typed [`.Designer.cs`](https://github.com/microsoft/PowerToys/blob/main/.Designer.cs) classes for `.resx` files, exposing a lazy-loaded `ResourceManager` property.

3. **Singleton loader pattern**: XAML-based modules implement a thin wrapper class called `ResourceLoaderInstance` that instantiates a `ResourceLoader` pointing to the module's PRI file:

   ```csharp
   // From src/settings-ui/Settings.UI/Helpers/ResourceLoaderInstance.cs
   internal static class ResourceLoaderInstance
   {
       internal static ResourceLoader ResourceLoader { get; }

       static ResourceLoaderInstance() =>
           ResourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("PowerToys.Settings.pri");
   }
   ```

4. **Runtime resolution**: UI code calls `ResourceLoaderInstance.ResourceLoader.GetString("KeyName")` to retrieve localized strings. The OS automatically selects the appropriate language from the PRI, falling back to English if a key is missing in the requested culture.

5. **Culture selection**: Windows determines the active language from the user's display language settings; developers add new translation files without modifying runtime code.

## Adding New Localized Strings Step-by-Step

Follow this workflow when introducing new UI text that requires translation support.

### Step 1: Select the Appropriate Resource Type

Choose `.resx` for WinForms modules and command-line utilities. Choose `.resw` for any XAML-based interface in Settings UI or Quick Access.

### Step 2: Add the Resource Entry

For **WinForms modules** using `.resx`:

- Open the file (e.g., `src/modules/powerrename/dll/Resources.resx`) in Visual Studio's resource editor.
- Add a name-value pair such as `PowerRename_DeleteConfirmation` = `"Delete selected items?"`.
- Save to trigger regeneration of [`Resources.Designer.cs`](https://github.com/microsoft/PowerToys/blob/main/Resources.Designer.cs).

For **XAML modules** using `.resw`:

- Open `src/settings-ui/Settings.UI/Strings/en-us/Resources.resw`.
- Add an XML data entry:
  ```xml
  <data name="PowerRename_DeleteConfirmation" xml:space="preserve">
    <value>Delete selected items?</value>
  </data>
  ```

- Create culture-specific folders (e.g., `fr-fr/`, `de-de/`) containing identically-named `.resw` files with translated values.

### Step 3: Reference the String in Code

Access your new resource using the pattern appropriate to the file type:

```csharp
// .resx usage via generated designer class (WinForms)
using Microsoft.PowerToys.PowerRename.Resources;

var message = Resources.PowerRename_DeleteConfirmation;

// .resw usage via ResourceLoader (XAML/Settings UI)
var message = ResourceLoaderInstance.ResourceLoader.GetString("PowerRename_DeleteConfirmation");

```

### Step 4: Build and Validate

Rebuild the solution. The build pipeline automatically packages updated resources into the relevant `.pri` files. Test by running PowerToys under different language settings to verify string retrieval.

## Code Implementation Examples

### Loading .resx Strings in WinForms

The PowerRename module demonstrates classic resource access through the auto-generated designer file:

```csharp
// src/modules/powerrename/dll/Resources.Designer.cs provides this API
using Microsoft.PowerToys.PowerRename.Resources;

public void ShowDeleteConfirmation()
{
    var message = Resources.PowerRename_DeleteConfirmation;
    var title = Resources.PowerRename_DeleteTitle;
    MessageBox.Show(message, title, MessageBoxButtons.YesNo);
}

```

### Loading .resw Strings in Settings UI ViewModels

ViewModels in the Settings UI utilize the singleton loader pattern to maintain testability and consistency:

```csharp
// Example pattern from src/settings-ui/Settings.UI/ViewModels/ZoomItViewModel.cs
public class PowerRenameSettingsViewModel
{
    private readonly ResourceLoader _loader = ResourceLoaderInstance.ResourceLoader;

    public string DeleteConfirmationText => 
        _loader.GetString("PowerRename_DeleteConfirmation");
}

```

### Adding French Localization

Create the culture-specific file at `src/settings-ui/Settings.UI/Strings/fr-fr/Resources.resw` with the translated content:

```xml
<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="PowerRename_DeleteConfirmation" xml:space="preserve">
    <value>Supprimer les éléments sélectionnés ?</value>
  </data>
</root>

```

Commit this file to include French support in the next build cycle.

## Key Files and Locations

| Purpose | File Path | Access Pattern |
|---------|-----------|----------------|
| PowerRename WinForms resources | `src/modules/powerrename/dll/Resources.resx` | `Resources.<Key>` via designer |
| PowerRename designer class | [`src/modules/powerrename/dll/Resources.Designer.cs`](https://github.com/microsoft/PowerToys/blob/main/src/modules/powerrename/dll/Resources.Designer.cs) | Auto-generated properties |
| Settings UI base strings | `src/settings-ui/Settings.UI/Strings/en-us/Resources.resw` | `ResourceLoader.GetString` |
| Settings UI loader singleton | [`src/settings-ui/Settings.UI/Helpers/ResourceLoaderInstance.cs`](https://github.com/microsoft/PowerToys/blob/main/src/settings-ui/Settings.UI/Helpers/ResourceLoaderInstance.cs) | Singleton instance accessor |
| Quick Access loader | [`src/QuickAccess.UI/Helpers/ResourceLoaderInstance.cs`](https://github.com/microsoft/PowerToys/blob/main/src/QuickAccess.UI/Helpers/ResourceLoaderInstance.cs) | Singleton instance accessor |
| ZoomIt ViewModel example | [`src/settings-ui/Settings.UI/ViewModels/ZoomItViewModel.cs`](https://github.com/microsoft/PowerToys/blob/main/src/settings-ui/Settings.UI/ViewModels/ZoomItViewModel.cs) | Runtime string retrieval |

## Best Practices for PowerToys Localization

- **Keep resource keys descriptive but concise**—they become C# property names in generated designer files.

- **Never embed UI strings directly in code**—always route through resource files to maintain translation capability.
- **Comment ambiguous entries** in `.resx` or `.resw` files using the comment field to provide context for translators.
- **Use BCP-47 culture tags** consistently in folder naming (`fr-fr`, `de-de`, `zh-cn`) to match Windows language pack identifiers.
- **Validate fallback behavior** by testing with incomplete translations to ensure graceful degradation to English when keys are missing.

## Summary

- **Use `.resx` files** for WinForms modules and `.resw` files** for XAML-based Settings UI and Quick Access modules.
- **Access resources** through strongly-typed `ResourceManager` properties for `.resx`, or via the `ResourceLoaderInstance` singleton calling `GetString()` for `.resw`.
- **Add translations** by creating culture-specific folders using BCP-47 tags and duplicating resource files with localized values.
- **Build integration** handles PRI compilation automatically; no manual packaging steps are required for localization updates.

## Frequently Asked Questions

### What is the difference between .resx and .resw files in PowerToys?

**`.resx` files** serve classic .NET and WinForms modules, compiling into strongly-typed C# classes with static properties for compile-time validation. **`.resw` files** support WinUI XAML applications and require runtime resolution through `ResourceLoader`, offering more flexibility for dynamic UI scenarios but requiring string-based key lookups.

### How do I access localized strings in a Settings UI ViewModel?

Import the `ResourceLoaderInstance` helper from [`src/settings-ui/Settings.UI/Helpers/ResourceLoaderInstance.cs`](https://github.com/microsoft/PowerToys/blob/main/src/settings-ui/Settings.UI/Helpers/ResourceLoaderInstance.cs) and call `ResourceLoader.GetString("YourResourceKey")`. This singleton wraps the `PowerToys.Settings.pri` resource package and automatically returns the appropriate language based on the current system culture.

### Where should I place new language resource files for a module?

Place `.resx` satellite assemblies in the same directory as the base file using the culture code as the filename suffix (e.g., `Resources.fr.resx`). For `.resw` files, create a subfolder under `Strings/` using the BCP-47 culture tag (e.g., `Strings/fr-fr/Resources.resw`) to match the packaging expectations of the PRI compiler.

### Do I need to manually compile PRI files when adding translations?

No. The MSBuild pipeline automatically compiles resource files into `.pri` packages during the standard build process. Adding a new `.resw` or `.resx` file and rebuilding the solution is sufficient to include the translations in the output.