Question

I'm trying to insert some simple registry keys using Microsoft.Win32.RegistryKey in c# but the path automatically changes from:

HKEY_LOCAL_MACHINE\SOFTWARE\Test

to

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Test

I tried google but I only get some vague and confusing results. Has anyone dealt with this issue before? Some example code would be much appereciated.

Was it helpful?

Solution

You can use RegistryKey.OpenBaseKey to solve this problem:

var baseReg = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var reg = baseReg.CreateSubKey("Software\\Test");

OTHER TIPS

Under WOW64, certain registry keys are redirected (SOFTWARE). When a 32-bit or 64-bit application makes a registry call for a redirected key, the registry redirector intercepts the call and maps it to the key's corresponding physical registry location. For more information, see Registry Redirector.

You can use the RegistryView Enumeration on RegistryKey.OpenBaseKey Method to open the 32-bit view explicitly and access HKLM\Software\ directly.

I don't know how to solve it using a .reg file. But only in a BAT file, as follow:

You must add /reg:64 at the end of the command line. ex:

REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\Background" /v "OEMBackground" /t REG_DWORD /d 0x00000001 /f /reg:64

Source: Wow6432Node and how to Deploy Registry settings to 64 bit systems via Sccm

Here is the working code I have developed to both read and write ONLY the 32-bit registry. It works in both 32-bit and 64-bit applications. The 'read' call updates the registry if the value is not set, but it is very obvious how to remove that. It requires .Net 4.0, and uses the OpenBaseKey/OpenSubKey methods.

I currently use it to allow a 64-bit background service and a 32-bit tray application to access the same registry keys seamlessly.

using Microsoft.Win32;

namespace SimpleSettings
{
public class Settings
{
    private static string RegistrySubKey = @"SOFTWARE\BlahCompany\BlahApp";

    public static void write(string setting, string value)
    {
        using (RegistryKey registryView = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
        using (RegistryKey registryCreate = registryView.CreateSubKey(RegistrySubKey))
        using (RegistryKey registryKey = registryView.OpenSubKey(RegistrySubKey, true))
        {
            registryKey.SetValue(setting, value, RegistryValueKind.String);
        }        
    }
    public static string read(string setting, string def)
    {
        string output = string.Empty;
        using (RegistryKey registryView = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
        using (RegistryKey registryCreate = registryView.CreateSubKey(RegistrySubKey))
        using (RegistryKey registryKey = registryView.OpenSubKey(RegistrySubKey, false))
        {
            // Read the registry, but if it is blank, update the registry and return the default.
            output = (string)registryKey.GetValue(setting, string.Empty);
            if (string.IsNullOrWhiteSpace(output))
            {
                output = def;
                write(setting, def);
            }
        }
        return output;
    }
}
}

Usage: Put this in it's own class file (.cs) and call it as such:

using SimpleSettings;
string mysetting = Settings.read("SETTINGNAME","DEFAULTVALUE");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top