Lectura del registro y la clave Wow6432Node

Tengo un código que lee el registro y busca un valor en HKEY_LOCAL_MACHINE\Software\App\ pero cuando se ejecuta en versiones de 64 bits de Windows, el valor está en HKEY_LOCAL_MACHINE\Software\Wow6432Node\App\ .

¿Cómo debería acercarme a esto? ¿Necesito un instalador de 64 bits o debería volver a escribir mi código para detectar ambos lugares?

Si marca su progtwig C # como x86 (y no como cualquier CPU), entonces verá HKEY_LOCAL_MACHINE\Software\Wow6432Node\App como HKEY_LOCAL_MACHINE\Software\App\ .

Un progtwig .NET para cualquier CPU se ejecutará como un proceso de 64 bits si está instalado .NET de 64 bits. El registro de 32 bits está bajo el Wow6432Node para progtwigs de 64 bits.

En una máquina x64, aquí hay un ejemplo de cómo acceder a la vista de 32 bits del registro:

 using (var view32 = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32)) { using (var clsid32 = view32.OpenSubKey(@"Software\Classes\CLSID\", false)) { // actually accessing Wow6432Node } } 

… en comparación con…

 using (var view64 = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) { using (var clsid64 = view64.OpenSubKey(@"Software\Classes\CLSID\", true)) { .... } } 

+1 a la respuesta de Wally, pero su solución funciona para .NET 4.0 y superior.

He encontrado otra solución, que también funciona para .NET 2.0 aquí

 #region RegHelper enum RegSAM { QueryValue = 0x0001, SetValue = 0x0002, CreateSubKey = 0x0004, EnumerateSubKeys = 0x0008, Notify = 0x0010, CreateLink = 0x0020, WOW64_32Key = 0x0200, WOW64_64Key = 0x0100, WOW64_Res = 0x0300, Read = 0x00020019, Write = 0x00020006, Execute = 0x00020019, AllAccess = 0x000f003f } static class RegHive { public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u); public static UIntPtr HKEY_CURRENT_USER = new UIntPtr(0x80000001u); } static class RegistryWOW6432 { [DllImport("Advapi32.dll")] static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out int phkResult); [DllImport("Advapi32.dll")] static extern uint RegCloseKey(int hKey); [DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx")] public static extern int RegQueryValueEx(int hKey, string lpValueName, int lpReserved, ref uint lpType, System.Text.StringBuilder lpData, ref uint lpcbData); static public string GetRegKey64(UIntPtr inHive, String inKeyName, string inPropertyName) { return GetRegKey64(inHive, inKeyName, RegSAM.WOW64_64Key, inPropertyName); } static public string GetRegKey32(UIntPtr inHive, String inKeyName, string inPropertyName) { return GetRegKey64(inHive, inKeyName, RegSAM.WOW64_32Key, inPropertyName); } static public string GetRegKey64(UIntPtr inHive, String inKeyName, RegSAM in32or64key, string inPropertyName) { //UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002; int hkey = 0; try { uint lResult = RegOpenKeyEx(RegHive.HKEY_LOCAL_MACHINE, inKeyName, 0, (int)RegSAM.QueryValue | (int)in32or64key, out hkey); if (0 != lResult) return null; uint lpType = 0; uint lpcbData = 1024; StringBuilder AgeBuffer = new StringBuilder(1024); RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, AgeBuffer, ref lpcbData); string Age = AgeBuffer.ToString(); return Age; } finally { if (0 != hkey) RegCloseKey(hkey); } } } #endregion 

Uso:

 string value64 = RegistryWOW6432.GetRegKey64(RegHive.HKEY_LOCAL_MACHINE, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "RegisteredOrganization"); string value32 = RegistryWOW6432.GetRegKey32(RegHive.HKEY_LOCAL_MACHINE, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "RegisteredOrganization"); 

Aquí hay una solución todo en uno que cubriría sistemas x32 / x64 y aplicaciones de captura instaladas en una máquina local o cuenta de usuario.

  public class InstalledProgramInfo { public string name; public string path; } public static InstalledProgramInfo FindInstalledApp(string findname, bool dump = false) { if (String.IsNullOrEmpty(findname)) return null; string uninstallKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; RegistryHive[] keys = new RegistryHive[] { RegistryHive.CurrentUser, RegistryHive.LocalMachine }; RegistryView[] views = new RegistryView[] { RegistryView.Registry32, RegistryView.Registry64 }; foreach (var hive in keys) { foreach (var view in views) { RegistryKey rk = null, basekey = null; try { basekey = RegistryKey.OpenBaseKey(hive, view); rk = basekey.OpenSubKey(uninstallKey); } catch (Exception ex) { continue; } if (basekey == null || rk == null) continue; if (rk == null) { if (dump) Console.WriteLine("ERROR: failed to open subkey '{0}'", uninstallKey); return null; } if (dump) Console.WriteLine("Reading registry at {0}", rk.ToString()); foreach (string skName in rk.GetSubKeyNames()) { try { RegistryKey sk = rk.OpenSubKey(skName); if (sk == null) continue; object skname = sk.GetValue("DisplayName"); object skpath = sk.GetValue("InstallLocation"); if (skpath == null) { skpath = sk.GetValue("UninstallString"); if (skpath == null) continue; FileInfo fi = new FileInfo(skpath.ToString()); skpath = fi.Directory.FullName; } if (skname == null || skpath == null) continue; string thisname = skname.ToString(); string thispath = skpath.ToString(); if (dump) Console.WriteLine("{0}: {1}", thisname, thispath); if (!thisname.Equals(findname, StringComparison.CurrentCultureIgnoreCase)) continue; InstalledProgramInfo inf = new InstalledProgramInfo(); inf.name = thisname; inf.path = thispath; return inf; } catch (Exception ex) { // todo } } } // view } // hive return null; }