Read and Write Windows Registry Keys in C

This guide demonstrates how to interact with the Windows Registry in C# using the Microsoft.Win32 namespace. You will learn how to access base registry hives, create new subkeys, write data, read existing values, and safely delete entries using the Registry and RegistryKey classes.

The Microsoft.Win32 Namespace

To work with the registry, include the namespace at the top of your file:

using Microsoft.Win32;

The Registry class provides static references to standard root hives:

  • Registry.CurrentUser (HKEY_CURRENT_USER): Settings specific to the currently logged-in user.
  • Registry.LocalMachine (HKEY_LOCAL_MACHINE): System-wide settings (requires administrator privileges to write).
  • Registry.ClassesRoot (HKEY_CLASSES_ROOT): File association and COM object information.
  • Registry.Users (HKEY_USERS): All active user profiles.
  • Registry.CurrentConfig (HKEY_CURRENT_CONFIG): Hardware configuration profiles.

Creating and Writing Registry Values

Use CreateSubKey to create a new subkey or open an existing one. Use SetValue to assign a name, value, and value kind (RegistryValueKind). Always use a using statement to properly flush and close key handles.

using Microsoft.Win32;

string subKeyPath = @"Software\MyApplication";

// Opens or creates the subkey under HKEY_CURRENT_USER
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(subKeyPath))
{
    if (key != null)
    {
        // Write a standard string value
        key.SetValue("AppVersion", "1.0.0", RegistryValueKind.String);

        // Write an integer (DWORD) value
        key.SetValue("LaunchCount", 42, RegistryValueKind.DWord);

        // Write a boolean (stored as DWORD: 1 or 0)
        key.SetValue("IsFirstRun", 1, RegistryValueKind.DWord);
    }
}

Reading Registry Values

Use OpenSubKey to open a key for reading. If you only need read access, set the second parameter (writable) to false or omit it. Check for null to ensure the key and value exist.

using Microsoft.Win32;

string subKeyPath = @"Software\MyApplication";

using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath))
{
    if (key != null)
    {
        // Read string value
        object versionObj = key.GetValue("AppVersion");
        string version = versionObj != null ? versionObj.ToString() : "Not Found";

        // Read integer with a default fallback if missing
        int launchCount = (int)key.GetValue("LaunchCount", 0);

        System.Console.WriteLine($"Version: {version}");
        System.Console.WriteLine($"Launch Count: {launchCount}");
    }
    else
    {
        System.Console.WriteLine("Key not found.");
    }
}

Modifying Existing Registry Keys

To update an existing key, pass true as the second argument in OpenSubKey to open it with write permissions:

using Microsoft.Win32;

string subKeyPath = @"Software\MyApplication";

using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath, writable: true))
{
    if (key != null)
    {
        key.SetValue("LaunchCount", 43, RegistryValueKind.DWord);
    }
}

Deleting Keys and Values

You can delete individual values or entire key hierarchies using DeleteValue, DeleteSubKey, or DeleteSubKeyTree.

using Microsoft.Win32;

string subKeyPath = @"Software\MyApplication";

// Delete a single value within a key
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath, writable: true))
{
    key?.DeleteValue("LaunchCount", throwOnMissingValue: false);
}

// Delete an entire subkey and all of its child elements
Registry.CurrentUser.DeleteSubKeyTree(subKeyPath, throwOnMissingSubKey: false);

Handling Permissions and 64-bit Views

  • User Account Control (UAC): Writing to Registry.LocalMachine requires elevated administrator rights. If your application lacks elevation, attempting to write will throw an UnauthorizedAccessException. Use Registry.CurrentUser for user-level application settings to avoid elevation requirements.
  • Registry Views (32-bit vs. 64-bit): On 64-bit Windows systems, 32-bit applications are redirected to SysWow64 registry nodes by default. To explicitly target a specific view, use RegistryKey.OpenBaseKey:
using (RegistryKey localMachine64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
    using (RegistryKey subKey = localMachine64.OpenSubKey(@"Software\Example"))
    {
        // Interacts directly with the 64-bit registry hive
    }
}