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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.


















以上是关于64位读取注册表与32位的区别的主要内容,如果未能解决你的问题,请参考以下文章

C# 32位程序在64位系统下注册表操作

32位和64位有啥区别 32位和64位区别都有哪些

win32与win64的操作系统的区别是啥?

64位系统与32位系统区别

电脑32位和64位有啥区别 电脑32位和64位的区别

2021-09-11:给你一个32位的有符号整数x,返回将x中的数字部分反转后的结果。反转后整数超过 32 位的有符号整数的范围就返回0,假设环境不允许存储 64 位整数(有符号或无符号)。(代码片段