x86程序读取64位系统注册表失败解决方案

    在做一个项目时,遇到了这么一种情况,在64位操作系统下(WOW),运行一个x86的应用程序,这个程序会读取注册表项目,读取注册表的代码是一样的,只要不交叉访问就是正确的(32位程序运行在x86平台,64位程序运行在x64平台),最后进行了一番调试,才搞明白失败的原因。

    导致原因是这样的,32位与64位两个操作系统版本上的注册表的结构是不一样的,有些键是可以共享的,而有些键是不可以共享的,这个我没有研究得很深入,记得在是MSDN上面看到过,不过链接给忘记了。

    最后我在网上查一下,找到了一种解决方案:
    请参考 http://www.codeproject.com/Articles/51326/Net-Compilation-registry-accessing-and-application.aspx?display=Print

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Reflection;
using Microsoft.Win32.SafeHandles;


namespace Common
{
    public class RegUtil
    {
        [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 null;
            }


            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;
        }
    }
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值