window注册表操作手册

环境:

  • window 10企业版
  • .netcore 3.1
  • vs 2019 16.4.5
  • 控制台程序以管理员身份运行

参照:

一、window注册表简介

1.1 什么是注册表

注册表是window操作系统存储数据的地方,可以认为是window自身的一个小型数据库。所有window软件都可以在安装或运行的时候向注册表添加或读取数据。同时window操作系统也会读取里面的内容以决定自己的行为。
举个例子:

  1. 迅雷软件安装后会在注册表中写入HKEY_CLASSES_ROOT\thunder,从而指示操作系统:当打开thunder://12345这样的地址的时候启动迅雷程序,如下图所示:
    在这里插入图片描述
    在这里插入图片描述
  2. 你可以修改注册表的值,以达到清除快捷方式箭头的目的
    删除HKEY_CLASSES_ROOT\lnkfile项下面的IsShortcut值,然后重启操作系统或者在任务管理器中重启window 资源管理器你就会发现桌面上的图标箭头消失了,如下:
    在这里插入图片描述
  3. 修改注册表项HKEY_CURRENT_USER\Control Panel\Desktop下PaintDesktopVersion的值为1,window桌面右下角将会显示window操作系统版本号:
    在这里插入图片描述
    在这里插入图片描述

1.2 注册表的数据结构

注册表是一个树状结构,它有五大根节点,这五大根节点有不同的作用。根节点下可以有很多子节点,每个子节点称之为“项”,而每个子节点又可以有自己的数据值,这些数据值按照数据类型划分为“字符串”、“扩展字符串”、“多行字符串”、“32位无符号整数”、“64位无符号整数”和“二进制数据”。
在这里插入图片描述

1.2.1 注册表的五大根节点

  • HKEY_CLASSES_ROOT:
    该根键包括启动应用程序所需的全部信息,包括扩展名,应用程序与文档之间的关系,驱动程序名,DDE和OLE信息,类ID编号和应用程序与文档的图标等。
  • HKEY_CURRENT_USER:
    该根键包括当前登录用户的配置信息,包括环境变量,个人程序以及桌面设置等
  • HKEY_LOCAL_MACHINE:
    该根键包括本地计算机的系统信息,包括硬件和操作系统信息,安全数据和计算机专用的各类软件设置信息
  • HKEY_USERS:
    该根键包括计算机的所有用户使用的配置数据,这些数据只有在用户登录系统时才能访问。这些信息告诉系统当前用户使用的图标,激活的程序组,开始菜单的内容以及颜色,字体。
  • HKEY_CURRENT_CONFIG:
    该根键包括当前硬件的配置信息,其中的信息是从KEY_LOCAL_MACHINE中映射出来的。

1.2.2 数据值的数据类型

  • 字符串
    简单字符串:REG_SZ
    多行字符串:REG_MULTI_SZ,获取的是字符串数组,不能解析%windir%等变量
    扩展字符串:REG_EXPAND_SZ,简单字符串上增加解析%windir%等变量的功能
  • 数字(正整数)
    int32:REG_DWORD,双子节 0 - 4294967295(2^32-1)
    int64:REG_QWORD,四个字节 0 - (Math.Pow(2,64)-1)
  • 字节数组
    byte[]:REG_BINARY

1.2.3 注册表项的默认值

每个项都允许有一个默认值,它的以空字符串("")作为关键字的简单字符串(注意,不是扩展字符串),如果你设置了它就存在(可以遍历所有的数据,会发现""),没设置值的话它就不存在(遍历数据的时候不会看到"")

二、c#读写注册表

基于上面对注册表的分析,我们需要对注册表进行读写操作,主要应用RegistryKey对象,下面是我封装的注册表操作的帮助类,200多行,包含的判断、读取、写入等操作:

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
/* 注册表知识点:
 * 1. 注册表有5大根节点,所有的配置都在这5个下面,所以我们读写的path里都以5大根节点字符串开头(HKEY_LOCAL_MACHINE\\SOFTWARE\\FileZilla 3)
 * 2. 注册表中有项和值,项就像是文件夹、而值就像是一个Dictinary<string,byte[]/int32/int64/string/string[]>
 * 3. 注册表中值的类型
 *      字符串
 *          简单字符串:REG_SZ
 *          多行字符串:REG_MULTI_SZ,获取的是字符串数组,不能解析%windir%等变量
 *          扩展字符串:REG_EXPAND_SZ,简单字符串上增加解析%windir%等变量的功能
 *      数字(正整数)
 *          int32:REG_DWORD,双子节 0 - 4294967295(2^32-1)
 *          int64:REG_QWORD,四个字节 0 - (Math.Pow(2,64)-1)
 *      字节数组
 *          byte[]:REG_BINARY
 * 4. 注册表项的默认值
 *      每个项都允许有一个默认值,它的以空字符串("")作为关键字的简单字符串(注意,不是扩展字符串),如果你设置了它就存在(可以遍历所有的数据,会发现""),没设置值的话它就不存在(遍历数据的时候不会看到"")
 * 
 */

namespace ConsoleApp24
{

    public class RegistryUtil
    {
        #region 内部使用
        private static Dictionary<string, RegistryHive> roots = new Dictionary<string, RegistryHive>()
        {
            {"HKEY_CLASSES_ROOT",RegistryHive.ClassesRoot},
            {"HKEY_CURRENT_USER",RegistryHive.CurrentUser},
            {"HKEY_LOCAL_MACHINE",RegistryHive.LocalMachine},
            {"HKEY_USERS",RegistryHive.Users},
            {"HKEY_CURRENT_CONFIG",RegistryHive.CurrentConfig}
        };
        private RegistryKey GetRoot(string path)
        {
            if (string.IsNullOrWhiteSpace(path)) return null;
            path = path.Trim('\\', '/');
            foreach (var i in roots)
            {
                if (path.StartsWith(i.Key))
                {
                    return RegistryKey.OpenBaseKey(i.Value,
                                           Environment.Is64BitOperatingSystem
                                               ? RegistryView.Registry64
                                               : RegistryView.Registry32);
                }
            }
            return null;
        }
        private static ValueTuple<string, RegistryKey> PrunePath(string path)
        {
            path = path.Trim('\\', '/').Replace('/', '\\');
            RegistryKey baseKey = null;
            foreach (var i in roots)
            {
                if (path.StartsWith(i.Key))
                {
                    baseKey = RegistryKey.OpenBaseKey(i.Value,
                                           Environment.Is64BitOperatingSystem
                                               ? RegistryView.Registry64
                                               : RegistryView.Registry32);
                    path = path.Substring(i.Key.Length).Trim('\\');
                    break;
                }
            }
            if (baseKey == null)
            {
                baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
                                           Environment.Is64BitOperatingSystem
                                               ? RegistryView.Registry64
                                               : RegistryView.Registry32);
            }
            return new ValueTuple<string, RegistryKey>(path, baseKey);
        }
        #endregion

        #region 判断、列出数据值的关键字、删除项或数据值
        /// <summary>
        /// 判断注册表项或值是否存在
        /// </summary>
        /// <param name="path">项路径</param>
        /// <param name="keyname">值的名称</param>
        /// <returns></returns>
        public static bool Exists(string path, string keyname = null)
        {
            var res = PrunePath(path);
            var root = res.Item2;
            path = res.Item1;
            RegistryKey key = root.OpenSubKey(path);
            if (key == null) return false;
            if (keyname == null) return true;
            return key.GetValueNames().ToList().Contains(keyname);
        }

        /// <summary>
        /// 返回注册项下的所有数据值名称,如果不存在这个项就返回null
        /// </summary>
        /// <param name="path">注册项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <returns></returns>
        public static List<string> ListDataKeys(string path)
        {
            var res = PrunePath(path);
            var root = res.Item2;
            path = res.Item1;
            RegistryKey key = root.OpenSubKey(path);
            if (key == null) return null;
            return key.GetValueNames().ToList();
        }

        /// <summary>
        /// 删除指定的项(包括子项和数据值)
        /// </summary>
        /// <param name="path">注册项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        public static void DeletePath(string path)
        {
            if (Exists(path))
            {

                ValueTuple<string, RegistryKey> res = PrunePath(path);
                path = res.Item1;
                RegistryKey root = res.Item2;
                root.DeleteSubKeyTree(path);
            }
        }

        /// <summary>
        /// 删除指定项下的指定数据值
        /// </summary>
        /// <param name="path">注册项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param keyname="keyname">注册项下的数据值关键字,如:teststring</param>
        public static void DeleteValue(string path, string keyname)
        {
            if (Exists(path, keyname))
            {

                ValueTuple<string, RegistryKey> res = PrunePath(path);
                path = res.Item1;
                RegistryKey root = res.Item2;
                RegistryKey key = root.OpenSubKey(path, true);
                key.DeleteValue(keyname);
            }
        }
        #endregion

        #region 读取注册表的值
        private static object GetValue(string path, string keyname = "")
        {
            var res = PrunePath(path);
            var root = res.Item2;
            path = res.Item1;
            RegistryKey key = root.OpenSubKey(path);
            if (key == null) return null;
            var obj = key.GetValue(keyname);
            return obj;
        }

        /// <summary>
        /// 读取注册项下的字符串数据(REG_SZ和REG_EXPAND_SZ),如果keyname为空就是读取默认值
        /// </summary>
        /// <param name="path">项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据值名称,如:string_a</param>
        /// <returns></returns>
        public static string GetString(string path, string keyname = "")
        {
            var obj = GetValue(path, keyname);
            if (obj == null) return null;
            return obj as string;
        }

        /// <summary>
        /// 读取注册项下的字节数据(REG_BINARY)
        /// </summary>
        /// <param name="path">项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据值名称,如:binary_123456789</param>
        /// <returns></returns>
        public static byte[] GetByteArray(string path, string keyname)
        {
            var obj = GetValue(path, keyname);
            if (obj == null) return null;
            return obj as byte[];
        }

        /// <summary>
        /// 读取注册项下的字节数据(REG_DWORD)
        /// </summary>
        /// <param name="path">项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据值名称,如:dword</param>
        /// <returns></returns>
        public static Int32? GetInt32(string path, string keyname)
        {
            var obj = GetValue(path, keyname);
            if (obj == null) return null;
            return (Int32)obj;
        }

        /// <summary>
        /// 读取注册项下的字节数据(REG_QWORD)
        /// </summary>
        /// <param name="path">项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据值名称,如:qword</param>
        /// <returns></returns>
        public static Int64? GetInt64(string path, string keyname)
        {
            var obj = GetValue(path, keyname);
            if (obj == null) return null;
            return (Int64)obj;
        }

        /// <summary>
        /// 综合GetInt32和GetInt64方法,可以取出REG_DWORD和REG_QWORD类型的数据
        /// </summary>
        /// <param name="path">项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据值名称,如:testint</param>
        /// <returns></returns>
        public static int? GetInt(string path, string keyname)
        {
            var obj = GetValue(path, keyname);
            if (obj == null) return null;
            if (obj is Int32) return (int)obj;
            if (obj is Int64) return (int)(long)obj;
            return null;
        }

        /// <summary>
        /// 读取注册项下的字节数据(REG_MULTI_SZ)
        /// </summary>
        /// <param name="path">项路径,如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据值名称,如:string_multi</param>
        /// <returns></returns>
        public static string[] GetStringArray(string path, string keyname)
        {
            var obj = GetValue(path, keyname);
            if (obj == null) return null;
            return obj as string[];
        }
        #endregion

        #region 设置注册项的数据值

        private static void SetValue(string path, string keyname, object value, RegistryValueKind dataKind)
        {
            var res = PrunePath(path);
            var root = res.Item2;
            path = res.Item1;
            RegistryKey key = root.CreateSubKey(path, true);
            key.SetValue(keyname, value, dataKind);
        }
        /// <summary>
        /// 设置注册项的默认值,注意:如果指定的path不存在则会新建
        /// </summary>
        /// <param name="path">注册项路径,比如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="value">字符串,类型为REG_SZ</param>
        public static void SetDefault(string path, string value)
        {
            SetValue(path, "", value, RegistryValueKind.String);
        }

        /// <summary>
        /// 给指定注册项设置键值对(REG_SZ),注意:如果指定的path不存在则会新建
        /// </summary>
        /// <param name="path">注册项路径,比如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据的名称</param>
        /// <param name="value">数据值</param>
        public static void SetString(string path, string keyname, string value = "")
        {
            if (string.IsNullOrWhiteSpace(keyname)) throw new Exception("必须指定数据值的关键字,如果想设置【(默认)】,那么调用SetDefault(string path,string value)方法");
            SetValue(path, keyname, value, RegistryValueKind.String);
        }

        /// <summary>
        /// 给指定注册项设置键值对(REG_EXPAND_SZ),注意:如果指定的path不存在则会新建
        /// </summary>
        /// <param name="path">注册项路径,比如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据的名称</param>
        /// <param name="value">数据值,如:xiao%windir%ming</param>
        public static void SetStringExpand(string path, string keyname, string value = "")
        {
            if (string.IsNullOrWhiteSpace(keyname)) throw new Exception("必须指定数据值的关键字,如果想设置【(默认)】,那么调用SetDefault(string path,string value)方法");
            SetValue(path, keyname, value, RegistryValueKind.ExpandString);
        }

        /// <summary>
        /// 给指定注册项设置键值对(REG_MULTI_SZ),注意:如果指定的path不存在则会新建
        /// </summary>
        /// <param name="path">注册项路径,比如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据的名称</param>
        /// <param name="value">数据值,如:new string[2] { "xiaoming", "xi" }</param>
        public static void SetStringArray(string path, string keyname, string[] value)
        {
            if (string.IsNullOrWhiteSpace(keyname)) throw new Exception("必须指定数据值的关键字,如果想设置【(默认)】,那么调用SetDefault(string path,string value)方法");
            if (value == null) throw new Exception("必须指定一个数组!");
            SetValue(path, keyname, value, RegistryValueKind.MultiString);
        }

        /// <summary>
        /// 给指定注册项设置键值对(REG_DWORD),注意:如果指定的path不存在则会新建
        /// </summary>
        /// <param name="path">注册项路径,比如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据的名称</param>
        /// <param name="value">数据值,如:456</param>
        public static void SetInt32(string path, string keyname, Int32 value)
        {
            if (string.IsNullOrWhiteSpace(keyname)) throw new Exception("必须指定数据值的关键字,如果想设置【(默认)】,那么调用SetDefault(string path,string value)方法");
            SetValue(path, keyname, value, RegistryValueKind.DWord);
        }

        /// <summary>
        /// 给指定注册项设置键值对(REG_QWORD),注意:如果指定的path不存在则会新建
        /// </summary>
        /// <param name="path">注册项路径,比如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据的名称</param>
        /// <param name="value">数据值,如:789</param>
        public static void SetInt64(string path, string keyname, Int64 value)
        {
            if (string.IsNullOrWhiteSpace(keyname)) throw new Exception("必须指定数据值的关键字,如果想设置【(默认)】,那么调用SetDefault(string path,string value)方法");
            SetValue(path, keyname, value, RegistryValueKind.QWord);
        }

        /// <summary>
        /// 综合SetInt32和SetInt64,存储的是RED_DWORD类型,注意:如果指定的path不存在则会新建
        /// </summary>
        /// <param name="path">注册项路径,比如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据的名称</param>
        /// <param name="value">数据值,如:789</param>
        public static void SetInt(string path, string keyname, int value)
        {
            if (string.IsNullOrWhiteSpace(keyname)) throw new Exception("必须指定数据值的关键字,如果想设置【(默认)】,那么调用SetDefault(string path,string value)方法");
            SetValue(path, keyname, value, RegistryValueKind.DWord);
        }

        /// <summary>
        /// 给指定注册项设置键值对(REG_BINARY),注意:如果指定的path不存在则会新建
        /// </summary>
        /// <param name="path">注册项路径,比如:HKEY_CURRENT_CONFIG\test\test1</param>
        /// <param name="keyname">数据的名称</param>
        /// <param name="value">数据值,如:new byte[2] { 0x20, 0x45 }</param>
        public static void SetByteArray(string path, string keyname, byte[] value)
        {
            if (string.IsNullOrWhiteSpace(keyname)) throw new Exception("必须指定数据值的关键字,如果想设置【(默认)】,那么调用SetDefault(string path,string value)方法");
            SetValue(path, keyname, value, RegistryValueKind.Binary);
        }
        #endregion
    }
}
REGENTRY.CHM [Windows 2000 Registry Reference] [免费版] Windows 2000 Registry Reference REGENTRY.CHM 技术参考说明 Windows 2000 注册表技术参考可以帮助你了解Windows 2000 注册表的内容。它包括了对于注册表中一些很有用的子树(subtrees),主键(keys),子键(subkeys)和记录(entries)的说明。 技术参考内容提要 Windows 2000 注册表技术参考的内容包括: ●Windows 2000 Professional和Windows 2000 Server注册表的部分内容。 ●由系统添加的子键和记录。 ●由用户添加的子键和记录。 ●Windows 2000包含的可选服务的子键和记录,如软硬件驱动,网络服务。但是,不包括某些运行Windows的计算机上的其他应用程序的子键和记录,如Microsoft Word。 ●修改方法,不直接编辑注册表而修改注册表值的推荐步骤。包括管理工具,Windows用户界面,以及应用程序接口的部分。 技术参考的范围 本技术参考没有列出注册表中的所有内容。主要是对管理员需要做修改的,和只能通过编辑注册表来修改的记录进行说明。 注册表的绝大部分是由靠系统代码设置并维护的选项组成,供系统内部使用。手动改变这些选项的值可能会在系统和应用程序中产生出非预期的、相互矛盾的、和无法解释的指令。可能会降低系统的性能,隐藏重要文件的位置,使你的Windows licensing agreement失效。在你还没完全了解其含义的时候,不要尝试改变注册表中记录的值。 技术参考和你的注册表 本文中提到的一些记录不一定会在每一台运行 Windows 2000的计算机的注册表中出现。你的注册表依据你所使用的Windows的版本,装载的软硬件和你为系统所配置的服务而有所变化。很多子键和记录只有在你用注册表编辑器或者程序直接将它们添加进注册表之后才有效。 如果你不能找到一个注册表的元素,它可能是因为它不包括在此参考。Windows 2000注册表技术参考没有描述整个注册表。某些注册表内容是特定于您的注册表。其他是Windows内部代码的一部分,对用户是没有意义的。许多条目只储存值,您必须在Windows中设置。这主要参考文献条目,用户可能需要改变使用Windows界面或Windows提供的管理工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackletter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值