• 64位读取注册表与32位的区别


    有一个读取注册表信息的程序  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkeystring , 0, KEY_READ, &hKey) == ERROR_SUCCESS)/

    ,在32位下完全正常,但是在64位返回值正确,但就是读不到东西。后来单步发现读不到东西,就搜64位读注册表失败,发现需要加

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkeystring , 0,KEY_READ|KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)就可以了,我是全部把权限提高,还可以根据不同的操作系统,设置不同的参数。

    IsWow64Process 判断64位操作系统

    typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
    LPFN_ISWOW64PROCESS fnIsWow64Process;
    IsWow64返回TRUE则是64位系统,否则为32位系统。
    BOOL IsWow64()
    {
        BOOL bIsWow64 = FALSE;
        fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
            GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

        if(NULL != fnIsWow64Process)
        {
            if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
            {
                            return FALSE;
            }
        }
        return bIsWow64;
    }

    可参考的文献:

    http://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx

    http://www.codeproject.com/Articles/51326/Net-Compilation-registry-accessing-and-applicatio

    http://boluns.blog.163.com/blog/static/69845968201071132032313/

    The code

    The next code is a personal translation to C# of several pieces of code I found, mostly from here:

    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyEx")]
    static extern int RegOpenKeyEx(IntPtr hKey, string subKey, uint options, int sam,
        out IntPtr phkResult);
    
    [Flags]
    public enum eRegWow64Options : int
    {
        None =              0x0000,
        KEY_WOW64_64KEY =   0x0100,
        KEY_WOW64_32KEY =   0x0200,
        // Add here any others needed, from the table of the previous chapter
    }
     
    [Flags]
    public enum eRegistryRights : int
    {
        ReadKey =  131097,
        WriteKey = 131078,
    }
    
    public static RegistryKey OpenSubKey(RegistryKey pParentKey, string pSubKeyName,
                                         bool pWriteable, 
                                         eRegWow64Options pOptions)
    {
        if (pParentKey == null || GetRegistryKeyHandle(pParentKey).Equals(System.IntPtr.Zero))
            throw new System.Exception("OpenSubKey: Parent key is not open");
     
        eRegistryRights Rights = eRegistryRights.ReadKey;
        if (pWriteable)
            Rights = eRegistryRights.WriteKey;
     
        System.IntPtr SubKeyHandle;
        System.Int32 Result = RegOpenKeyEx(GetRegistryKeyHandle(pParentKey), pSubKeyName, 0, 
                                          (int)Rights | (int)pOptions, out SubKeyHandle);
        if (Result != 0)
        {
            System.ComponentModel.Win32Exception W32ex =
                new System.ComponentModel.Win32Exception();
            throw new System.Exception("OpenSubKey: Exception encountered opening key",
                W32ex);
        }
     
        return PointerToRegistryKey(SubKeyHandle, pWriteable, false);
    }
     
    private static System.IntPtr GetRegistryKeyHandle(RegistryKey pRegisteryKey)
    {
        Type Type = Type.GetType("Microsoft.Win32.RegistryKey");
        FieldInfo Info = Type.GetField("hkey", BindingFlags.NonPublic | BindingFlags.Instance);
     
        SafeHandle Handle = (SafeHandle)Info.GetValue(pRegisteryKey);
        IntPtr RealHandle = Handle.DangerousGetHandle();
     
        return Handle.DangerousGetHandle();
    }
     
    private static RegistryKey PointerToRegistryKey(IntPtr hKey, bool pWritable,
        bool pOwnsHandle)
    {
        // Create a SafeHandles.SafeRegistryHandle from this pointer - this is a private class
        BindingFlags privateConstructors = BindingFlags.Instance | BindingFlags.NonPublic;
        Type safeRegistryHandleType = typeof(
            SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType(
            "Microsoft.Win32.SafeHandles.SafeRegistryHandle");
     
        Type[] safeRegistryHandleConstructorTypes = new Type[] { typeof(System.IntPtr),
            typeof(System.Boolean) };
        ConstructorInfo safeRegistryHandleConstructor =
            safeRegistryHandleType.GetConstructor(privateConstructors, 
            null, safeRegistryHandleConstructorTypes, null);
        Object safeHandle = safeRegistryHandleConstructor.Invoke(new Object[] { hKey,
            pOwnsHandle });
     
        // Create a new Registry key using the private constructor using the
        // safeHandle - this should then behave like 
        // a .NET natively opened handle and disposed of correctly
        Type registryKeyType = typeof(Microsoft.Win32.RegistryKey);
        Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType,
            typeof(Boolean) };
        ConstructorInfo registryKeyConstructor =
            registryKeyType.GetConstructor(privateConstructors, null, 
            registryKeyConstructorTypes, null);
        RegistryKey result = (RegistryKey)registryKeyConstructor.Invoke(new Object[] {
            safeHandle, pWritable });
        return result;
    }

    How to use the Code

    The OpenSubKey will return the searched key, allowing you to specify reading from the normal registry, or from the alternative 32-bit, WOW64 registry. The following example reads from the 32-bit WOW64 registry:

    try 
    { 
        RegistryKey key = OpenSubKey(Registry.LocalMachine,"Software\[Key]",false,
            eRegWow64Options.KEY_WOW64_32KEY); 
    }
    catch 
    { 
        // Parent key not open, exception found at opening (probably related to
        // security permissions requested)
    }

    You just need to place your key name where “[Key]” is.

  • 相关阅读:
    JVM 关于对象分配在堆、栈、TLAB的理解
    分布式唯一 ID 生成方案有哪些?
    JVM 栈帧之操作数栈与局部变量表 转
    C# TreeHelper帮助类
    Java:Top K问题的解法
    C#单例模式
    C#分组方式比较
    Vue实现登录
    git使用总结
    js实现无色彩球
  • 原文地址:https://www.cnblogs.com/waw/p/6375435.html
Copyright © 2020-2023  润新知