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:

Hide   Shrink    Copy Code

[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:

Hide   Copy Code

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.

时间: 2024-10-27 03:33:09

64位读取注册表与32位的区别的相关文章

C# 32位程序访问64位系统注册表

原文:C# 32位程序访问64位系统注册表 我的上一篇文章已经阐述了"32位程序和64位程序在64位平台上读\写注册表的区别",那么接下来将要回答上篇所留下来的一个问题:32位程序如何访问64位系统注册表(即:64位程序所访问的注册表位置). 我们已经知道: ①:本机模式 64 位程序运行在纯模式下,并且访问键和存储在以下注册表子键中的值:HKEY_LOCAL_MACHINE\Software ②:32 位程序运行在 WOW64 模式下,并且访问键和值存储在以下注册表子项中:HKEY_

自动化测试之读写64位操作系统的注册表

非Web程序(桌面程序)的设置一般都存在注册表中. 给这些程序做自动化测试时, 需要经常要跟注册表打交道. 通过修改注册表来修改程序的设置. 本章介绍如何利用C#程序如何操作注册表, 特别是如何操作64位操作系统的注册表. 阅读目录 自动化测试经常需要修改注册表 Windows注册表简介 C#修改注册表 32位机器和64位机器注册表的区别 C#程序访问64位操作系统的注册表 自动化测试经常需要修改注册表 很多系统的设置(比如:IE的设置)都是存在注册表中. 桌面应用程序的设置也是存在注册表中.

解决64位Win7系统无法连接32位XP网络共享打印机

  在使用WIN7 64位旗舰版操作系统的时候发现一个问题,64位Windows7系统无法连接32位XP网络共享打印机,而32位WIN7就可以. HP客服解释说XP 32位的操作系统与WIN 7 64位的数据不匹配,无法达到共享打印的效果,微软官网的方法是要安装WIN 7SP1补丁可解决此问题- 这里分享个简单的解决方法: 方法一: 先去下载一个64位的打印机驱动,然后添加打印机,注意这里要添加的是本地打印机,安装官网的驱动,不要检测打印机,安装完后打开打印机属性配置窗口,点击<端口>页,在该

win7 32位-vs2005 64位编译时变成编译32位的工程

问题描述 vs2005 64位编译时变成编译32位的工程 操作系统为:WIN7 32位,旗舰版:使用VS2005编译器(由于项目限制要求,我也知道有VS2010),属于SP2补丁,已经设置活动平台为X64,但每次编译时,都是启动的编译Release32位的编译过程并且成功,那64位设置根本没用,请问到底如何解决这个无法编译的问题.附上一些图片: 如果看不到图片大家可看http://zhidao.baidu.com/question/431965115531269684.html?quesup2&

vmware-VMware中有两个centos,但是64位的可以上网,32位的却不行,请问是什么原因呢

问题描述 VMware中有两个centos,但是64位的可以上网,32位的却不行,请问是什么原因呢 VMware中有两个centos,但是64位的可以上网,32位的却不行,请问是什么原因呢.谢谢!!! 解决方案 配置问题吧,点开VMware里的虚拟机工具栏下有个设置,看下你的Centos系统的那个网络配置是否为NAT,如下图所示: 解决方案二: 网络配置问题,这个应该和多少位没关系 解决方案三: 跟系统没关系的,看下你自己的配置吧

Advanced Installer读取注册表时将Program Files读取为Program Files (x86)的解决办法

原文:Advanced Installer读取注册表时将Program Files读取为Program Files (x86)的解决办法 今天同事在做安装包的时候,有一个读取注册表路径的需求,需要根据读取的值来写配置文件,按照常规的做法,写好了注册表搜索方法,但是在测试的时候,发现总是会将系统盘下的Program Files\xxx路径读取为Program Files (x86)\xxx,如下图所示: 之后测试了如果读取非系统盘下的此路径,不会出现这个问题. 但是这个路径一般情况下都是默认安装在

代码-如何用VC读取注册表二进制值,比如ShutdownTime?求助~

问题描述 如何用VC读取注册表二进制值,比如ShutdownTime?求助~ 用RegQueryValueEx读取数据,应该放在哪种数据类型中呢,求有效代码~ 下面这段是自己的提取TypedURLsTime的代码.不知问题在哪.. int main() { HKEY hKey; DWORD lpType = REG_BINARY; BYTE time[64]; DWORD timeSize = sizeof(time); RegOpenKeyEx(HKEY_CURRENT_USER, "Soft

.Net 2.0 原汁原味读取注册表

注册表 在.Net 1.x当中,使用Microsoft.Win32.RegistryKey类的GetValue方法读取注册表数据时,其实数据都是经过"处理"的: 例如,某个字符串数据本来的值是%SystemRoot%\System32\IoLogMsg.dll但是用GetValue方法得到的数据却是C:\WINDOWS\System32\IoLogMsg.dll 也就是说,在读取注册表中的字符串时,系统会自作主张地替你展开环境变量. 这的确省去我们调用Environment.Expan

c++读取注册表详解

  1.读注册表 // 读取注册表 CString ReadRegisteTable(CString root,CString path, CString key) { HKEY hAppKey; LPCTSTR WINDS_SERVICE_REGISTRY_KEY=path; LPCTSTR DATA_FILE_SUB_KEY=key; char szDataFile[80]; if(root=="HKEY_LOCAL_MACHINE") { if (ERROR_SUCCESS ==