C#操作注册表(通俗易懂、详尽)
一、白话注册表
要访问注册表,可以使用Microsoft.Win32命名空间中的两个类Registry 和RegistryKey。RegistryKey实例表示一个注册表项,这个类的方法可以浏览子键、创建新键、读取或修改键中的值。换言之,该类可以完成对注册表项进行的所有操作(除了设置键的安全级别之外)。RegistryKey类可以用于完成对注册表的所有操作。Registry是不能实例化的一个类。它的作用只是提供表示顶级键的RegistryKey实例(不同的巢),以便开始在注册表中浏览。Registry是通过静态属性来提供这些实例的,这些属性共有7个,分别是ClassesRoot、CurrentConfig、CurrentUser、DynData、LocalMachine、PerformanceData和 Users。用户可以很快猜出它们分别与哪个巢相对应。
例如,要获得一个表示HKLM键的RegistryKey实例,可以编写下面的代码:
RegistryKey hklm = Registry.LocalMachine;
获得RegistryKey对象引用的过程,视为打开一个键。
用户可能会认为,因为注册表的层次结构类似于文件系统,所以RegistryKey的方法类似于DirectoryInfo的方法,但实际上并非如此。访问注册表的方式通常不同于使用文件和文件夹的方式,RegistryKey执行的方法可以反映这种不同。
最明显的区别是如何在注册表的给定位置上打开一个注册表项。Registry类没有用户可以使用的公共构造函数,也没有任何可以直接通过键的名称来访问键的方法。但可以在相关的巢中从上至下浏览该键。如果要实例化一个RegistryKey对象,惟一的方式是从Registry的静态属性开始,向下浏览。例如,要读取HKLM/Software/Microsoft键中的一些数据,可以使用下面的代码获得它的一个引用:
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftware = hklm.OpenSubKey(“Software”);
RegistryKey hkMicrosoft = hkSoftware.OpenSubKey(“Microsoft”);
以这种方式访问注册表项是只读访问。如果要写入该键(包括写入其值,或创建和删除其子键),就需要使用OpenSubKey的另一个重写方法,该方法的第二个参数是bool类型,表示是否要对该键进行读写访问。例如,如果要修改Microsoft键(并假定用户是一个系统管理员,有修改该键的许可),就应编写如下代码:
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftware = hklm.OpenSubKey(“Software”);
RegistryKey hkMicrosoft = hkSoftware.OpenSubKey(“Microsoft”, true);
因为这个键包含Microsoft应用程序使用的信息,在大多数情况下,就不应修改这个特定键。
如果这个键已经存在,就应调用OpenSubKey()方法。如果这个键不存在,就返回一个空引用。如果要创建一个键,就应使用CreateSubKey()方法(该方法会通过返回的引用,自动提供该键的读写访问):
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftware = hklm.OpenSubKey(“Software”);
RegistryKey hkMine = hkSoftware.CreateSubKey(“MyOwnSoftware”);
CreateSubKey()工作的方式非常有趣:如果键不存在,它就创建这个键。但如果键已经存在,它就会返回一个表示该键的RegistryKey实例。这个方法采用这样的工作方式,其原因是用户总是可以使用这个键。注册表包含长期数据,例如Windows和各种应用程序的配置信息。因此用户并不需要经常显式地创建键。
更常见的是,应用程序需要确保某些数据在注册表中是存在的。换言之,如果这些数据不存在,就要创建相关的键,但如果它们存在,就不需要做任何事。CreateSubKey()就可以完成这项任务。与FileInfo.Open()的情况不同,CreateSubKey()不会删除任何数据。如果要删除注册表项,就需要显式调用RegistryKey.Delete()方法,因此注册表对于Windows是非常重要的。如果删除了一些重要的键,就会中断Windows的执行,此时就需要调试C#注册表调用了。
定位了要读取或修改的注册表项后,就可以使用SetValue() 或 GetValue()方法设置或获取该键中的值。这两个方法的参数都是一个字符串,其中字符串给出了值的名称,SetValue()还需要一个包含值的信息的对象引用。这个参数定义为对象引用,实际上可以是任何一个类的引用。SetValue()根据所提供的类的类型,确定把值设置为REG_SZ、REG_DWORD,还是 REG_BINARY。例如:
RegistryKey hkMine = HkSoftware.CreateSubKey(“MyOwnSoftware”);
hkMine.SetValue(“MyStringValue”, “Hello World”);
hkMine.SetValue(“MyIntValue”, 20);
这段代码设置键包含两个值:MyStringValue的类型是REG_SZ,而MyIntValue的类型是REG_DWORD,这里只考虑这两种类型,在后面的示例中会使用它们。
RegistryKey.GetValue()的工作方式也是这样。它返回一个对象引用,如果该方法检测到值的类型为REG_SZ,就返回一个字符串引用,如果值的类型为REG_DWORD,就返回一个int型值。
string stringValue = (string)hkMine.GetValue(“MyStringValue”);
int intValue = (int)hkMine.GetValue(“MyIntValue”);
最后,完成了读取或修改数据后,应关闭该键:
hkMine.Close();
二、注册表详解
一.注册表巢
Registry Hive 注册表巢,在注册表中,最上面的节点HKEY_CLASSES_ROOT(HKCR) 包含系统文件类型的细节,以及应用程序可以打开的文件类型,它还包含所有COM组件的注册信息。HKEY_CURRENT_USER(HKCU) 包含用户目前登陆的机器的用户配置,包括桌面设置、环境变量、网络和打印机连接和其他定义用户操作环境的变量。HKEY_LOCAL_MACHINE(HKLM) 是一个很大的巢,其中包含所有安装到机器上的软件和硬件的信息。HKEY_USERS(HKUSR) 包含所有用户的用户配置。HKEY_CURRENT_CONFIG(HKCF) 包含机器上硬件的信息。
二.注册表类及常用属性和函数
using Microsoft.Win32;
这个命名空间包含了注册表相关的类。Registry类、RegistryKey类。
1、Registry类封装了注册表的七个基本主键:
Registry.ClassesRoot 对应于HKEY_CLASSES_ROOT主键
Registry.CurrentUser 对应于HKEY_CURRENT_USER主键
Registry.LocalMachine 对应于 HKEY_LOCAL_MACHINE主键
Registry.User 应于 HKEY_USER主键
Registry.CurrentConfig 对应于HEKY_CURRENT_CONFIG主键
Registry.DynDa 对应于HKEY_DYN_DATA主键
Registry.PerformanceData 对应于HKEY_PERFORMANCE_DATA主键
2、RegistryKey类封装了对注册表的基本操作。包括读、写、删等操作的常用函数:
函数 | 说明 |
---|---|
Close | 关闭该项,如果该项的内容已修改,则将该项刷新到磁盘。 |
CreateSubKey(String) | 创建一个新子项或打开一个现有子项以进行写访问。 |
CreateSubKey(String, RegistryKeyPermissionCheck) | 使用指定的权限检查选项创建一个新子项或打开一个现有子项以进行写访问。 |
CreateSubKey(String, RegistryKeyPermissionCheck, RegistryOptions) | 使用指定的权限检查和注册表选项,创建或打开一个用于写访问的子项。 |
CreateSubKey(String, RegistryKeyPermissionCheck, RegistrySecurity) | 使用指定的权限检查选项和注册表安全性创建一个新子项或打开一个现有子项以进行写访问。 |
CreateSubKey(String, RegistryKeyPermissionCheck, RegistryOptions, RegistrySecurity) | 使用指定的权限检查选项、注册表选项和注册表安全性,创建或打开一个用于写访问的子项。 |
DeleteSubKey(String) | 删除指定的子项。 |
DeleteSubKey(String, Boolean) | 删除指定的子项,并指定在找不到该子项时是否引发异常。 |
DeleteSubKeyTree(String) | 递归删除子项和任何子级子项。 |
DeleteSubKeyTree(String, Boolean) | 以递归方式删除指定的子项和任何子级子项,并指定在找不到子项时是否引发异常。 |
DeleteValue(String) | 从此项中删除指定值。 |
DeleteValue(String, Boolean) | 从此项中删除指定的值,并指定在找不到该值时是否引发异常。 |
Dispose | 释放由 RegistryKey 类的当前实例占用的所有资源。 |
Flush | 将指定的打开注册表项的全部特性写到注册表中。 |
FromHandle(SafeRegistryHandle) | 根据指定的句柄创建注册表项。 |
FromHandle(SafeRegistryHandle, RegistryView) | 利用指定的句柄和注册表视图设置创建注册表项。 |
GetAccessControl() | 返回当前注册表项的访问控制安全性。 |
GetAccessControl(AccessControlSections) | 返回当前注册表项的访问控制安全性的指定部分。 |
GetSubKeyNames | 检索包含所有子项名称的字符串数组。 |
GetValue(String) | 检索与指定名称关联的值。 如果注册表中不存在名称/值对,则返回 null。 |
GetValue(String, Object) | 检索与指定名称关联的值。 如果未找到名称,则返回您提供的默认值。 |
GetValue(String, Object, RegistryValueOptions) | 检索与指定的名称和检索选项关联的值。 如果未找到名称,则返回您提供的默认值。 |
GetValueKind | 检索与指定名称关联的值的注册表数据类型。 |
GetValueNames | 检索包含与此项关联的所有值名称的字符串数组。 |
OpenBaseKey | 打开一个新的 RegistryKey,它使用指定的视图在本地计算机上表示请求的项。 |
OpenRemoteBaseKey(RegistryHive, String) | 打开一个新的 RegistryKey,它表示远程计算机上的请求的项。 |
OpenRemoteBaseKey(RegistryHive, String, RegistryView) | 打开一个新的注册表项,它使用指定的视图在远程计算机上表示请求的项。 |
OpenSubKey(String) | 以只读方式检索子项。 |
OpenSubKey(String, RegistryKeyPermissionCheck) | 检索指定的子项以进行读取或读/写访问。 |
OpenSubKey(String, Boolean) | 检索指定的子项,并指定是否将写访问权限应用于该项。 |
OpenSubKey(String, RegistryKeyPermissionCheck, RegistryRights) | 检索指定的子项以进行读取或读/写访问,请求指定的访问权限。 |
SetAccessControl | 向现有注册表项应用 Windows 访问控制安全性。 |
SetValue(String, Object) | 设置指定的名称/值对。 |
SetValue(String, Object, RegistryValueKind) | 使用指定的注册表数据类型设置注册表项中的名称/值对的值。 |
ToString 检索此项的字符串表示形式。 | (重写 Object.ToString()。) |
3、注册表中的“键值数据项”的类型
在注册表中,“键值项数据”可分为下面三种类型。
数据类型 | 说明 |
---|---|
REG_BINARY | 在注册表中,二进制是没有长度限制的,可以是任意个字节的长度。在注册表编辑器中,二进制数据以十六进制的方式显示出来 |
REG_DWORD | DWORD值是一个32位(4个字节,即双字)长度的数值。在注册表编辑器中,你将会发现系统以十六进制的方式显示DWORD值,在编辑DWORD数值时,可以选择用二进制、十进制或是十六进制的方式进行输入 |
REG_SZ | 在注册表中,字符串值一般用来表示文件的描述、硬件的标识等。通常它由字母和数字组成。 |
通过键值名、键值就可以组成一种键值项数据,这就相当于Win.ini、System.ini文件中小节下的设置行。其实,使用注册表编辑器将这些键值项数据导出后,其形式与.ini文件中的设置完全一样。
2,打开
//使用OpenSubKey()打开项,获得RegistryKey对象,当路径不存在时,为Null。第二个参数为true,表示可写,可读,可删;省略时只能读。
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE\test",true);
hklm.Close();
hkSoftWare.Close();
3,删除
//主要用到了DeleteSubKey(),删除test项
RegistryKey hklm = Registry.LocalMachine;
hklm.DeleteSubKey(@"SOFTWARE\test", true); //为true时,删除的注册表不存在时抛出异常;当为false时不抛出异常。
hklm.Close();
四、注册表键值的创建、打开和删除
1,创建
//主要用到了SetValue(),表示在test下创建名称为Name,值为RegistryTest的键值。第三个参数表示键值类型,省略时,默认为字符串
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE\test",true);
hkSoftWare.SetValue("Name", "RegistryTest", RegistryValueKind.String);
hklm.Close();
hkSoftWare.Close();
2,打开
//主要用到了GetValue(),获得名称为"Name"的键值
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE\test", true);
string sValue = hkSoftWare.GetValue("Name").ToString();
hklm.Close();
hkSoftWare.Close();
3,删除
//主要用到了DeleteValue(),表示删除名称为"Name"的键值,第二个参数表示是否抛出异常
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE\test", true);
hkSoftWare.DeleteValue("Name", true);
hklm.Close();
hkSoftWare.Close();
五、判断注册表项、注册表键值是否存在
//判断注册表项是否存在private bool IsRegistryKeyExist(string sKeyName){string[] sKeyNameColl;RegistryKey hklm = Registry.LocalMachine;RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE");sKeyNameColl = hkSoftWare.GetSubKeyNames(); //获取SOFTWARE下所有的子项foreach (string sName in sKeyNameColl){if (sName == sKeyName){hklm.Close();hkSoftWare.Close();return true;}}hklm.Close();hkSoftWare.Close();return false;}//判断键值是否存在private bool IsRegistryValueNameExist(string sValueName){string[] sValueNameColl;RegistryKey hklm = Registry.LocalMachine;RegistryKey hkTest = hklm.OpenSubKey(@"SOFTWARE\test");sValueNameColl = hkTest.GetValueNames(); //获取test下所有键值的名称foreach (string sName in sValueNameColl){if (sName == sValueName){hklm.Close();hkTest.Close();return true;}}hklm.Close();hkTest.Close();return false;}
六、程序自启动程序
//开启程序自启动string path = Application.ExecutablePath;RegistryKey rk = Registry.LocalMachine;RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");rk2.SetValue("JcShutdown", path);rk2.Close();rk.Close();//关闭程序自启动string path = Application.ExecutablePath;RegistryKey rk = Registry.LocalMachine;RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");rk2.DeleteValue("JcShutdown", false);rk2.Close();rk.Close();
C#操作注册表(通俗易懂、详尽)相关推荐
- C#操作注册表全攻略
相信每个人对注册表并不陌生,在运行里面输入"regedit"就可以打开注册表编辑器了.这东西对Windows系统来说可是比较重要的,也是病毒常常会光顾的地方,比如病毒和恶意软件常常 ...
- .NET操作注册表的封装类
我写的一个在.NET下操作注册表的类. using System; using Microsoft.Win32; using System.Collections; namespace iUNS { ...
- 在Delphi程序中操作注册表
32位Delphi程序中可利用TRegistry对象来存取注册表文件中的信息. 一.创建和释放TRegistry对象 1.创建TRegistry对象.为了操作注册表,要创建一个TRegistry对象: ...
- WinForm创建系统托盘以及操作注册表
创建系统托盘菜单 1,创建一个contextMenu(cmnMain)菜单 2,添加一个NotifyIcon组件,设置ContextMenu属性为cmnMain 3,相应窗体改变事件(最小化等) pr ...
- Win64 驱动内核编程-6.内核里操作注册表
内核里操作注册表 RING0 操作注册表和 RING3 的区别也不大,同样是"获得句柄->执行操作->关闭句柄"的模式,同样也只能使用内核 API 不能使用 WIN32 ...
- Win 驱动编程 - 内核里操作注册表
一 概述 RING0 操作注册表和 RING3 的区别也不大,同样是"获得句柄->执行操作->关闭句柄"的模式,同样也只能使用内核 API 不能使用 WIN32API. ...
- 删除python的注册表_Python操作注册表详细步骤介绍
Python操作注册表步骤之1.打开注册表 对注册表进行操作前,必须打开注册表.在Python中,可以使用以下两个函数:RegOpenKey和RegOpenKeyEx.其函数原型分别如下所示. Reg ...
- Atitit.操作注册表 树形数据库 注册表的历史 java版本类库总结
Atitit.操作注册表 树形数据库 注册表的历史 java版本类库总结 1. 注册表是树形数据库 1 2. 注册表的由来 1 3. Java 操作注册表 2 3.1. 使用Preferences ...
- C++ 读取windows服务列表 与操作注册表
读取服务列表 https://www.cnblogs.com/Leo-Forest/archive/2013/05/03/3056569.html 操作注册表 https://blog.csdn.ne ...
- Python模块——_winreg操作注册表
From: http://blog.sina.com.cn/s/blog_4b5039210100gmsb.html 用python操作修改windows注册表,显然要比用C或者C++简单. 主要参考 ...
最新文章
- 在B站如何不动一根手指,就可以养成6级大佬?大四学生发明养号神器,看完你也会...
- 2.12.ECMAScript--运算符
- SAP ABAP实用技巧介绍系列之 ABAP XSLT match keyword
- 【UOJ#33】【UR #2】树上GCD(长链剖分/根号分类讨论)
- Aswing入门教程 1.6 颜色和填充
- Java技术回顾之JNDI--命名和目录服务基本概念
- laravel 分词搜索匹配度_搜索引擎工作原理
- callbackcallback()到底有什么涵义?
- java重绘table_java – 与JTable交互,使用新行快速更新
- android学习笔记---57_采用方向传感器实现指南针,android设备传感器介绍,以及使用方法
- java war包是什么_War包是什么??
- sdk环境变量配置win10_sdk环境变量配置好检查
- 「行业化、产业化、专业化」,解析中科曙光眼中的大数据现状和未来
- Opencascade TopoDS_Shape Orientation
- c语言自定义函数返回值的作用,C语言自定义函数
- 技术小卡系列之Eclipse 窗口说明
- 私域流量公众号+小程序+企业微信+视频号+积分组合营销
- 4款小众实用的手机APP,全是安卓手机的黑科技软件!
- [KDD 2022]ROLAND Graph Learning Framework for Dynamic Graphs
- “Terra事件”再迎新进展 加密逃犯否认躲避当局,却下落不明?