How do i get the true path to a reg key?
Categories:
Navigating the Windows Registry: Uncovering the True Path to a Key

Understand how to accurately locate and access Registry keys in Windows, especially when dealing with 32-bit and 64-bit system differences in .NET applications.
The Windows Registry is a hierarchical database that stores low-level settings for the Microsoft Windows operating system and for applications that opt to use the Registry. When working with the Registry, especially in .NET applications, it's crucial to understand how to obtain the 'true' or canonical path to a Registry key. This becomes particularly important when dealing with the complexities introduced by 32-bit and 64-bit Windows environments, where Registry redirection and reflection can obscure the actual location of keys.
Understanding Registry Virtualization and Redirection
On 64-bit versions of Windows, the operating system maintains separate views of the Registry for 32-bit and 64-bit applications. This mechanism, known as Registry redirection and reflection, ensures backward compatibility for 32-bit applications while allowing 64-bit applications to access their native Registry paths.
Specifically, 32-bit applications accessing HKEY_LOCAL_MACHINE\SOFTWARE
are often redirected to HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node
. This redirection is largely transparent to the 32-bit application, but it means that the 'true' path from a 64-bit perspective is different from what a 32-bit application might perceive. When you need to programmatically determine the actual, physical path of a Registry key, you must account for these architectural differences.
flowchart TD A[Application Request Registry Key] --> B{Is Application 32-bit?} B -->|Yes| C{Is Key in HKLM\SOFTWARE?} C -->|Yes| D[Redirect to HKLM\SOFTWARE\Wow6432Node] C -->|No| E[Access Native Path] B -->|No| E[Access Native Path] D --> F[Return Key from Wow6432Node] E --> G[Return Key from Native Path] F --> H[Application Receives Key] G --> H[Application Receives Key]
Registry Redirection Flow for 32-bit Applications on 64-bit Windows
Accessing the True Path in .NET
The .NET framework provides the Microsoft.Win32.Registry
class for interacting with the Windows Registry. To get the 'true' path, you need to be aware of the RegistryView
enumeration, which allows you to specify whether you want to access the 32-bit or 64-bit Registry view.
When opening a Registry key, you can explicitly request a specific view. If you open a key using RegistryView.Registry64
, you will always get the 64-bit view of the Registry, regardless of whether your application is running as 32-bit or 64-bit. This is the key to bypassing redirection and obtaining the canonical path.
using Microsoft.Win32;
using System;
public class RegistryPathResolver
{
public static string GetTrueRegistryPath(RegistryHive hive, string subKeyPath)
{
// Attempt to open the key using the 64-bit view first
using (RegistryKey baseKey = RegistryKey.OpenBaseKey(hive, RegistryView.Registry64))
{
using (RegistryKey key = baseKey.OpenSubKey(subKeyPath, false))
{
if (key != null)
{
// The 'Name' property returns the full path including the hive name
return key.Name;
}
}
}
// If not found in 64-bit view, try the 32-bit view (Wow6432Node)
// This is useful if the key genuinely only exists in the 32-bit view
using (RegistryKey baseKey = RegistryKey.OpenBaseKey(hive, RegistryView.Registry32))
{
using (RegistryKey key = baseKey.OpenSubKey(subKeyPath, false))
{
if (key != null)
{
return key.Name;
}
}
}
return null; // Key not found in either view
}
public static void Main(string[] args)
{
string softwareKeyPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion";
string truePath = GetTrueRegistryPath(RegistryHive.LocalMachine, softwareKeyPath);
if (truePath != null)
{
Console.WriteLine($"True path for '{softwareKeyPath}': {truePath}");
}
else
{
Console.WriteLine($"Key '{softwareKeyPath}' not found.");
}
// Example for a key that might only exist in Wow6432Node for 32-bit apps
string wow64TestKeyPath = "SOFTWARE\\My32BitApp";
string trueWow64Path = GetTrueRegistryPath(RegistryHive.LocalMachine, wow64TestKeyPath);
if (trueWow64Path != null)
{
Console.WriteLine($"True path for '{wow64TestKeyPath}': {trueWow64Path}");
}
else
{
Console.WriteLine($"Key '{wow64TestKeyPath}' not found.");
}
}
}
C# code to retrieve the true Registry path by explicitly specifying RegistryView.
RegistryKey
objects by wrapping them in using
statements to prevent resource leaks. The RegistryKey.Name
property provides the full path of the opened key, including the hive (e.g., HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft
).Considerations for Cross-Platform and Bitness Compatibility
When developing applications that need to interact with the Registry, especially those that might run on both 32-bit and 64-bit systems, or those that need to inspect both views, it's essential to design your Registry access logic carefully.
If your application is compiled as 'Any CPU' and runs on a 64-bit OS, it will execute as a 64-bit process. In this scenario, accessing Registry.LocalMachine.OpenSubKey("SOFTWARE")
will directly access the 64-bit SOFTWARE
hive. To access the 32-bit Wow6432Node
from a 64-bit process, you must explicitly use RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE")
.
Conversely, if your application is compiled as 'x86' (32-bit) and runs on a 64-bit OS, it will run under WOW64. Accessing Registry.LocalMachine.OpenSubKey("SOFTWARE")
will automatically be redirected to HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node
. To access the 64-bit SOFTWARE
hive from this 32-bit process, you must explicitly use RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey("SOFTWARE")
.
1. Determine Target Registry View
Decide whether you need to access the 32-bit (RegistryView.Registry32
) or 64-bit (RegistryView.Registry64
) view of the Registry. If you need the 'true' 64-bit path, always specify RegistryView.Registry64
.
2. Open Base Key with Specified View
Use RegistryKey.OpenBaseKey(RegistryHive hive, RegistryView view)
to get the root of the desired Registry view. For example, RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)
.
3. Open SubKey
From the base key, use OpenSubKey(string name, bool writable)
to navigate to your specific Registry key. Remember to handle null
returns if the key does not exist.
4. Retrieve True Path
Once you have a valid RegistryKey
object, its Name
property will contain the full, canonical path to that key within the view you specified (e.g., HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\My32BitApp
).
5. Dispose Resources
Ensure all RegistryKey
objects are properly disposed of using using
statements to release system resources.