Reading the registry and Wow6432Node key

后端 未结 4 1660
天涯浪人
天涯浪人 2020-11-29 00:02

I have some code that reads the registry and looks for a value in HKEY_LOCAL_MACHINE\\Software\\App\\ but when running on 64-bit versions of Windows the value i

相关标签:
4条回答
  • 2020-11-29 00:11

    +1 to Wally's answer, but his solution works for .NET 4.0 and higher.

    I've found another solution, which also works for .NET 2.0 here

    #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
    

    Usage:

    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");
    
    0 讨论(0)
  • 2020-11-29 00:21

    Here's an all-in-one solution that would cover x32 / x64 systems and capture apps installed on local machine or user account.

        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;
        }
    
    0 讨论(0)
  • 2020-11-29 00:25

    If you mark you C# program as x86 (and not Any CPU) then it will see HKEY_LOCAL_MACHINE\Software\Wow6432Node\App as HKEY_LOCAL_MACHINE\Software\App\.

    A .NET program for Any CPU will run as a 64-bit process if 64-bit .NET is installed. The 32-bit registry is under the Wow6432Node for 64-bit programs.

    0 讨论(0)
  • 2020-11-29 00:26

    On an x64 machine, here is an example of how to access the 32-bit view of the registry:

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

    ... as compared to...

    using (var view64 = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser,
                                                RegistryView.Registry64))
    {
      using (var clsid64 = view64.OpenSubKey(@"Software\Classes\CLSID\", true))
      {
        ....
      }
    }
    
    0 讨论(0)
提交回复
热议问题