Lecture du registre et de la clé Wow6432Node

J’ai du code qui lit le Registre et recherche une valeur dans HKEY_LOCAL_MACHINE\Software\App\ mais lorsque vous exécutez sur des versions 64 bits de Windows, la valeur est sous HKEY_LOCAL_MACHINE\Software\Wow6432Node\App\ .

Comment devrais-je mieux aborder cela? Ai-je besoin d’un installateur 64 bits ou devrais-je réécrire mon code pour détecter les deux endroits?

Si vous marquez le programme C # comme étant x86 (et non Any CPU), HKEY_LOCAL_MACHINE\Software\Wow6432Node\App apparaîtra sous le nom HKEY_LOCAL_MACHINE\Software\App\ .

Un programme .NET pour Any CPU s’exécutera en tant que processus 64 bits si .NET 64 bits est installé. Le registre 32 bits est sous le Wow6432Node pour les programmes 64 bits.

Sur un ordinateur x64, voici un exemple d’access à la vue 32 bits du registre:

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

… comparé à…

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

+1 à la réponse de Wally, mais sa solution fonctionne pour .NET 4.0 et supérieur.

J’ai trouvé une autre solution qui fonctionne également pour .NET 2.0 ici

 #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, ssortingng 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, ssortingng lpValueName, int lpReserved, ref uint lpType, System.Text.SsortingngBuilder lpData, ref uint lpcbData); static public ssortingng GetRegKey64(UIntPtr inHive, Ssortingng inKeyName, ssortingng inPropertyName) { return GetRegKey64(inHive, inKeyName, RegSAM.WOW64_64Key, inPropertyName); } static public ssortingng GetRegKey32(UIntPtr inHive, Ssortingng inKeyName, ssortingng inPropertyName) { return GetRegKey64(inHive, inKeyName, RegSAM.WOW64_32Key, inPropertyName); } static public ssortingng GetRegKey64(UIntPtr inHive, Ssortingng inKeyName, RegSAM in32or64key, ssortingng 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; SsortingngBuilder AgeBuffer = new SsortingngBuilder(1024); RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, AgeBuffer, ref lpcbData); ssortingng Age = AgeBuffer.ToSsortingng(); return Age; } finally { if (0 != hkey) RegCloseKey(hkey); } } } #endregion 

Usage:

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

Voici une solution tout-en-un qui couvrirait les systèmes x32 / x64 et les applications de capture installées sur un ordinateur ou un compte d’utilisateur local.

  public class InstalledProgramInfo { public ssortingng name; public ssortingng path; } public static InstalledProgramInfo FindInstalledApp(ssortingng findname, bool dump = false) { if (Ssortingng.IsNullOrEmpty(findname)) return null; ssortingng 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.ToSsortingng()); foreach (ssortingng 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("UninstallSsortingng"); if (skpath == null) continue; FileInfo fi = new FileInfo(skpath.ToSsortingng()); skpath = fi.Directory.FullName; } if (skname == null || skpath == null) continue; ssortingng thisname = skname.ToSsortingng(); ssortingng thispath = skpath.ToSsortingng(); if (dump) Console.WriteLine("{0}: {1}", thisname, thispath); if (!thisname.Equals(findname, SsortingngComparison.CurrentCultureIgnoreCase)) continue; InstalledProgramInfo inf = new InstalledProgramInfo(); inf.name = thisname; inf.path = thispath; return inf; } catch (Exception ex) { // todo } } } // view } // hive return null; }