سؤال

لدي بعض الكود الذي يقرأ السجل ويبحث عن قيمة في HKEY_LOCAL_MACHINE\Software\App\ ولكن عند تشغيل إصدارات 64 بت من Windows القيمة قيد HKEY_LOCAL_MACHINE\Software\Wow6432Node\App\.

كيف يجب أن أقترب من هذا؟ هل أحتاج إلى مثبت 64 بت أو يجب إعادة كتابة التعليمات البرمجية الخاصة بي للكشف عن كلا المكانين؟

هل كانت مفيدة؟

المحلول

إذا قمت بتمييز برنامجك C # ك X86 (وليس أي وحدة المعالجة المركزية)، فسترى HKEY_LOCAL_MACHINE\Software\Wow6432Node\App كما HKEY_LOCAL_MACHINE\Software\App\.

سيتم تشغيل برنامج .NET لأي وحدة تخزين وحدة المعالجة المركزية كعملية 64 بت إذا تم تثبيت 64 بت .NET. السجل 32 بت هو تحت Wow6432Node لبرامج 64 بت.

نصائح أخرى

على آلة X64، إليك مثال على كيفية الوصول إلى طريقة العرض 32 بت من السجل:

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

... مقارنة ب...

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

+1 إلى الإجابة والي، لكن حله يعمل من أجل .NET 4.0 والأعلى.

لقد وجدت حل آخر، والذي يعمل أيضا ل .NET 2.0 هنا

#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

الاستعمال:

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");

إليك حل متعدد الإمكانات التي من شأنها أن تغطي أنظمة X32 / X64 وتطبيقات التقاط مثبتة على الجهاز المحلي أو حساب المستخدم.

    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;
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top