C#读取注册表:ProductID在x86目标应用程序中返回null。 “任何CPU”工作正常

我最近搬到了VS 2010的W7 64位机器上。我的项目设置为在Any CPU上运行。 当我将其更改为针对x86我注意到我的一些注册表调用不再有效。

我试图像这样读取ProductID字段:

 RegistryKey windowsNTKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion"); object productID = windowsNTKey.GetValue("ProductId"); 

在x86模式下运行时, productID始终为null ,当在“任何CPU”中运行时,它正常工作。 这里发生了什么?

某些注册表项由WOW64重定向。 有关此主题的更多信息,请访问MSDN http://msdn.microsoft.com/en-us/library/aa384232(v=vs.85).aspx

如果您真的想要始终访问x64节点(.Net4):

  RegistryKey localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); RegistryKey windowsNTKey = localMachine.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion"); object productID = windowsNTKey.GetValue("ProductId"); 

此代码将获得各种os体系结构和程序体系结构的id。 可写得更短,但我喜欢可读性

  static string GetProductId() { RegistryKey localMachine = null; if (Environment.Is64BitOperatingSystem) { localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); } else { localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32); } RegistryKey windowsNTKey = localMachine.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion"); return windowsNTKey.GetValue("ProductId").ToString(); } 

在win64上,32位应用程序的一些注册表项存储在Software\Wow6432Node子项中。

如果要切换到64位密钥,可以使用RegistryView枚举作为RegistryKey.OpenBaseKey参数

个人使用这样的结构使代码始终在主注册表项(而不是WoW6432)中工作:

RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32)