C#操作注册表

1、微软为了让32位程序不做任何修改就能运行在64的操作系统上,添加了一个十分重要的WOW64子系统来实现这个功能,WOW64是Windows-32-on-Windows-64的简称,从总体上来说,WOW64是一套基于用户模式的动态链接库,它可以把32位应用程序的发出的命令       翻译成64位系统可以接受的格式,即:WOW 层处理诸如在 32 位和 64 位模式之间切换处理器以及模拟 32 位系统的事务。

  32位与64位特点的两个重要表现方面为:文件系统与注册表

      文件系统:32位进程不能加载64位Dll,64位进程也不可以加载32位Dll。

      注册表:为了防止注册表键冲突,64位机器注册表信息分成了两个部分。一部分是专门给64位系统(即:64位程序)访问的,另一部分是专门给32位系统(即:32位程序)访问的,放在Wow6432Node下面。(Wow6432Node这个节 点存在于                                HKEY_LOCAL_MACHINE和HKEY_CURRENT_USER下面)

2、举例说明

首先下载了32位软件Winrar(下载地址:http://www.winrar.com.cn/),分别在32位和64位机器上进行安装,版本号请看截图  

  

  通过查询注册表可知,Winrar的版本号在32位机器里的注册表里的路径Path:"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver ".且Key值为:"DisplayVersion"

  Winrar的版本号在32位机器里的注册表里的路径Path:"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver ".且Key值为:"DisplayVersion"

3、现在编写一个代码分别进行读取,更改,以实现C#读取注册表 

 写一个注册表类RegUtil.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace ToolUtils
{
    public static class RegUtil
    {
        static readonly IntPtr HKEY_CLASSES_ROOT = new IntPtr(unchecked((int)0x80000000));
        static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001));
        static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002));
        static readonly IntPtr HKEY_USERS = new IntPtr(unchecked((int)0x80000003));
        static readonly IntPtr HKEY_PERFORMANCE_DATA = new IntPtr(unchecked((int)0x80000004));
        static readonly IntPtr HKEY_CURRENT_CONFIG = new IntPtr(unchecked((int)0x80000005));
        static readonly IntPtr HKEY_DYN_DATA = new IntPtr(unchecked((int)0x80000006));

        // 获取操作Key值句柄 
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int RegOpenKeyEx(IntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult);

        //创建或打开Key值
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int RegCreateKeyEx(IntPtr hKey, string lpSubKey, int reserved, string type, int dwOptions, int REGSAM, IntPtr lpSecurityAttributes, out IntPtr phkResult,
                                                 out int lpdwDisposition);

        //关闭注册表转向(禁用特定项的注册表反射)
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int RegDisableReflectionKey(IntPtr hKey);

        //使能注册表转向(开启特定项的注册表反射)
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int RegEnableReflectionKey(IntPtr hKey);

        //获取Key值(即:Key值句柄所标志的Key对象的值)
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved, out uint lpType, System.Text.StringBuilder lpData, ref uint lpcbData);

        //设置Key值
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int RegSetValueEx(IntPtr hKey, string lpValueName, uint unReserved, uint unType, byte[] lpData, uint dataCount);

        //关闭Key值
        [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int RegCloseKey(IntPtr hKey);

        public static IntPtr TransferKeyName(string keyName)
        {
            IntPtr ret = IntPtr.Zero;
            switch (keyName)
            {
                case "HKEY_CLASSES_ROOT":
                    ret = HKEY_CLASSES_ROOT;
                    break;
                case "HKEY_CURRENT_USER":
                    ret = HKEY_CURRENT_USER;
                    break;
                case "HKEY_LOCAL_MACHINE":
                    ret = HKEY_LOCAL_MACHINE;
                    break;
                case "HKEY_USERS":
                    ret = HKEY_USERS;
                    break;
                case "HKEY_PERFORMANCE_DATA":
                    ret = HKEY_PERFORMANCE_DATA;
                    break;
                case "HKEY_CURRENT_CONFIG":
                    ret = HKEY_CURRENT_CONFIG;
                    break;
                case "HKEY_DYN_DATA":
                    ret = HKEY_DYN_DATA;
                    break;
                default:
                    ret = HKEY_LOCAL_MACHINE;
                    break;
            }
            return ret;
        }

        /// <summary>
        /// 设置64位注册表
        /// </summary>
        /// <param name="key"></param>
        /// <param name="subKey"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int Set64BitRegistryKey(string key, string subKey, string name, string value)
        {
            int STANDARD_RIGHTS_ALL = (0x001F0000);
            int KEY_QUERY_VALUE = (0x0001);
            int KEY_SET_VALUE = (0x0002);
            int KEY_CREATE_SUB_KEY = (0x0004);
            int KEY_ENUMERATE_SUB_KEYS = (0x0008);
            int KEY_NOTIFY = (0x0010);
            int KEY_CREATE_LINK = (0x0020);
            int SYNCHRONIZE = (0x00100000);
            int KEY_WOW64_64KEY = (0x0100);
            int REG_OPTION_NON_VOLATILE = (0x00000000);
            int KEY_ALL_ACCESS = (STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS
                                 | KEY_NOTIFY | KEY_CREATE_LINK) & (~SYNCHRONIZE);

            int ret = 0;
            try
            {
                //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
                IntPtr hKey = TransferKeyName(key);

                //声明将要获取Key值的句柄 
                IntPtr pHKey = IntPtr.Zero;

                //获得操作Key值的句柄
                int lpdwDisposition = 0;
                ret = RegCreateKeyEx(hKey, subKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | KEY_WOW64_64KEY, IntPtr.Zero, out pHKey, out lpdwDisposition);
                if (ret != 0)
                {
                    Log2.Log(string.Format("Unable to create key {0} - {1}: {2}!", key, subKey, ret));
                    return ret;
                }

                //关闭注册表转向(禁止特定项的注册表反射)
                RegDisableReflectionKey(pHKey);

                //设置访问的Key值
                uint REG_SZ = 1;
                byte[] data = Encoding.Unicode.GetBytes(value);

                RegSetValueEx(pHKey, name, 0, REG_SZ, data, (uint)data.Length);

                //打开注册表转向(开启特定项的注册表反射)
                RegEnableReflectionKey(pHKey);

                RegCloseKey(pHKey);
            }
            catch (Exception ex)
            {
                Log2.Log(ex.ToString());
                return -1;
            }

            return ret;
        }

        public static void SetRegistryKey(string key, string subKey, string name, string value)
        {
            Log2.Log("SetRegistryKey start.");
            if (System.IntPtr.Size == 8)
            {
                // 写SOFTWARE\Huawei\VirtualDesktopAgent,需要关闭注册表重定向,再写64位路径的注册表
                int ret = RegUtil.Set64BitRegistryKey(key, subKey, name, value);
                if (ret != 0)
                {
                    Log2.Log(string.Format("Failed to write Reg {0}\\{1}\\{2},return {3}", key, subKey, name, ret));
                }
            }

            try
            {
                Microsoft.Win32.Registry.SetValue(key + "\\" + subKey, name, value);
            }
            catch (Exception ex)
            {
                Log2.Log(ex.ToString());
            }

            Log2.Log("SetRegistryKey exit.");
        }

        public static string GetRegistryValue(string path, string key)
        {
            RegistryKey regkey = null;
            try
            {
                regkey = Registry.LocalMachine.OpenSubKey(path);
                if (regkey == null)
                {
                    Log2.Log("Cannot find Registry path:" + path);
                    return null;
                }

                object val = regkey.GetValue(key);
                if (val == null)
                {
                    Log2.Log("Cannot find Registry key:" + key);
                    return null;
                }

                return val.ToString();
            }
            catch (Exception ex)
            {
                Log2.Log(ex.ToString());
                return null;
            }
            finally
            {
                if (regkey != null)
                {
                    regkey.Close();
                }
            }
        }
    }
}

主函数进行操作注册表

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Regedit
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //public const string vLanID_X86 = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";


        string Winrarpath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver";
        string key = "DisplayVersion";

        private void Form1_Load(object sender, EventArgs e)
        {
            //获取注册表值(32位和64位都可以)
            string value = Common.GetRegistryValue(Winrarpath,key);
            lb_version.Text = value;  
        }

        //改注册表值
        private void button1_Click(object sender, EventArgs e)
        {
            string value = textBox1.Text.ToString();
            Common.SetRegistryKey("HKEY_LOCAL_MACHINE", Winrarpath, "DisPlayVersion", value);
            string newValue = Common.GetRegistryValue(Winrarpath, "DisPlayVersion");
            lb_newVersion.Text = newValue;
        }
    }
}

结果,32\64位都可以改变

 

喝的不是酒,是心痛;抽的不是烟,是忧愁;
posted @ 2019-04-04 10:18  风情单车  阅读(7511)  评论(1编辑  收藏  举报