32位程序无法读取HKEY_LOCAL_MACHINE子键的原因及解决方法
问题:32位进程读取64位注册表键异常
代码示例
public static bool IsInstallationRequired() { using (var key1 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE")) { if (key1 == null) return true; using (var key2 = key1.OpenSubKey(@"CompanyName")) { if (key2 == null) return true; string[] subKeys = key2.GetSubKeyNames(); using (var key3 = key2.OpenSubKey(@"Product Name")) { if (key3 == null) return true; using (var key4 = key3.OpenSubKey(@"Install")) { if (key4 == null) return true; } } } } return false; }
问题现象与环境
- 确认代码中提及的所有注册表键均存在,但
GetSubKeyNames()返回空数组,key3赋值后为null key1和key2可正常打开;Windows账号拥有管理员权限,但程序以普通模式运行- 环境:Windows 11(64位),.NET Framework 4.8.1,进程以32位模式构建运行
已尝试操作
- 在
HKLM\Software\CompanyName下添加更多子键,未出现在GetSubKeyNames()返回数组中 - 为
CompanyName及其子键添加“Everyone”读取权限,无效果
原因分析
这是注册表重定向机制导致的问题。64位Windows系统中,32位进程访问HKLM\SOFTWARE时,会被系统自动重定向到HKLM\SOFTWARE\Wow6432Node路径。你实际在HKLM\SOFTWARE下创建的子键,32位进程无法直接看到,它只会读取Wow6432Node下的对应路径,而该路径下不存在你创建的Product Name等子键,因此出现GetSubKeyNames()返回空、key3为null的现象。
解决方法
方法1:修改代码指定64位注册表视图
在打开注册表键时,通过RegistryKey.OpenBaseKey指定RegistryView.Registry64,让32位进程绕过重定向直接读取64位注册表路径:
public static bool IsInstallationRequired() { using (var key1 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) .OpenSubKey(@"SOFTWARE")) { if (key1 == null) return true; using (var key2 = key1.OpenSubKey(@"CompanyName")) { if (key2 == null) return true; string[] subKeys = key2.GetSubKeyNames(); using (var key3 = key2.OpenSubKey(@"Product Name")) { if (key3 == null) return true; using (var key4 = key3.OpenSubKey(@"Install")) { if (key4 == null) return true; } } } } return false; }
注:普通用户权限通常可读取64位注册表,若涉及写入则需管理员权限。
方法2:将程序改为64位进程
在项目属性的生成设置中,将目标平台从x86改为x64,或选择Any CPU并取消勾选“首选32位”。64位进程访问HKLM\SOFTWARE时会直接读取原生64位注册表路径,不会触发重定向。
方法3:将注册表键迁移至Wow6432Node下
若需兼容32位进程,可将CompanyName及其子键创建到HKLM\SOFTWARE\Wow6432Node路径下,32位进程即可正常读取这些键值。
内容的提问来源于stack exchange,提问作者ivan.ukr
相关产品推荐
相关产品推荐

