要访问注册表,可以使用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();