注册表项是注册表中的基本组织单位,好比是Windows 资源管理器中的文件 夹。 每个具体的注册表项都可以有子项,就像文件夹下可以有子文件夹一样。只要用户具有相应的权限,且注册表项不是基项或基项的下一级项,就可以删除该注册表 项。每个注册表项也可带有与其相关联的多个值(一个值就好比是一个文件),它们用于存储信息,例如,有关计算机上安装的应用程序的信息。每个值存储特定的 信息,可按需要对其进行检索或更新。例如,可以为您的公司创建一个RegistryKey (在项HKEY_LOCAL_MACHINE\Software 下),然后为您的公司创建的每个应用程序创建一个子项。每个子项保存特定于该应用程序的信息,如颜色设置、屏幕位置和大小或者可识别的文件扩展名。
HKEY_CLASSES_ROOT 该主键包含了文件的扩展名和应用程序的关联信息以及Window Shell 和OLE 用于储存注册表的信息。该主键下的子键决定了在WINDOWS 中如何显示该类文件以及他们的图标,该主键是从HKEY_LCCAL_MACHINE\SOFTWARE\Classes 映射过来的。
HKEY_CURRENT_USER 该主键包含了如用户窗口信息,桌面设置等当前用户的信息。
HKEY_LOCAL_MACHINE 主键包含了计算机软件 和硬件的安装和配置信息,该信息可供所有用户使用
HKEY_USERS 该主键记录了当前用户的设置信息,每次用户登入系统 时,就会在该主键下生成一个与用户登入名一样的子键,该子键保存了当前用户的桌面设置、背景位图、快捷键,字体等信息。一般应用程序不直接访问改主键,而是通过主键HKEY_CURRENT_USER 进行访问。
HKEY_CURRENT_CONFIG 该主键保存了计算机当前硬件的配置信息,这些配置可以根据当前所连接的网络类型或硬件驱动软件安装的改变而改变。
C# 也支持对注册表的编辑,.NET 框架在Microsoft.Win32 名字空间中提供了两个类来操作注册表:Registry 和RegistryKey 。这两个类都是密封类不允许被继承。下面我们分别来介绍这两个类。
Registry 类提供了7 个公共的静态域,分别代表7 个基本主键(其中两个在XP 系统中没有,在这就不介绍了)分别是:Registry.ClassesRoot ,Registry.CurrentUser ,Registry.LocalMachine ,Registry.Users ,Registry.CurrentConfig 。它们分别对应哪几个键我想各位一看就会知道吧。
RegistryKey 类中提供了对注册表操作的方法 。 要注意的是操作注册表必须符合系统权限,否则将会抛出错误。
下面我们就来几个操作注册表常用的几个方法
创建子键的方法原型为:
public RegistryKey CreateSubKey(string sunbkey);
参数sunbkey 表示要创建的子键的名称或路径名。创建成功返回被创建的子键,否则返回null 。
打开子键的方法原型为:
public RegistryKey OpenSubKey(string name);
public RegistryKey OpenSubKey(string name,bool writable);
参数name 表示要打开的子键名或其路径名,参数writable 表示被打开的子键是否允许被修改,第一个方法打开的子键是只读的。Microsoft.Win32 类还为我们提供了另一个方法,用于打开远程计算机上的注册表,方法原型为:
public static RegistryKey OpenRemoteBaseKey(RegistryHive hKey,string machineName);
删除子键的方法原型为
public void DeleteKey(string subkey);
该方法用于删除指定的主键。如果要删除的子键还包含主键则删除失败,并返回一个异常,如果要彻底删除该子键极其目录下的子键可以用方法DeleteSubKeyTree ,该方法原型如下:
public void DeleteKeyTree(string subkey);
读取键值的方法原型如下:
public object GetValue(string name);
public object GetValue(string name,object defaultValue);
参数name 表示键的名称,返回类型是一个object 类型,如果指定的键不存在则返回null 。如果失败又不希望返回的值是null 则可以指定参数defaultValue ,指定了参数则在读取失败的情况下返回该参数指定的值。
设置键值的方法原型如下:
public object SetValue(string name,object value);
程序中读取主键、子键和键值所使用到的方法:
程序中为了读取指定主键下面的子键和子键中拥有的键值,主要使用了RegistryKey 类中的四个方法:OpenSubKey ,GetSubKeyNames ,GetValueNames ,GetValue 。具体的用法和意思如下:
OpenSubKey ( string name ) 方法主要是打开指定的子键。
GetSubKeyNames ( ) 方法是获得主键下面的所有子键的名称,它的返回值是一个字符串数组。
GetValueNames ( ) 方法是获得当前子键中的所有的键名称,它的返回值也是一个字符串数组。
GetValue ( string name ) 方法是指定键的键值。
程序中具体的使用语句如下:
RegistryKey hklm = Registry.LocalMachine ;
// 打开"SYSTEM" 子键 RegistryKey software = hklm.OpenSubKey ( "SYSTEM" ) ;
// 打开"001" 子键 RegistryKey no1 = software.OpenSubKey ( "001" ) ;
// 打开"002" 子键 RegistryKey no2 = no1.OpenSubKey ( "002" ) ;
其中listBox1 是程序中定义了的列表名称。
II 如何用列表形式显示注册信息:
由于GetSubKeyNames ( ) 方法和GetValueNames ( ) 方法的返回值是字符串数组,所以在程序中是通过foreach 语句实现遍历这些字符串数组的。并且在遍历的时候,就通过列表形式显示出来,程序中具体实现语句如下:
foreach ( string site in no2.GetSubKeyNames ( ) )
// 开始遍历由子键名称组成的字符串数组
{
listBox1.Items.Add ( site ) ;
// 在列表中加入子键名称
RegistryKey sitekey = no2.OpenSubKey ( site ) ;
// 打开此子键
foreach ( string sValName in sitekey.GetValueNames ( ) )
// 开始遍历由指定子键拥有的键值名称组成的字符串数组
{
listBox1.Items.Add ( "" + sValName + ": " + sitekey.GetValue ( sValName ) ) ;
// 在列表中加入键名称和对应的键值
}
}
在 RegistryKey 类中有一个 OpenSubKey() 方法,可以用于打开子键,要注意它是有重载的,共有两种方法,分别为 OpenSubKey(string name) 和 OpenSubKey(string name,bool writable) 。 如果使用第一种方法打开子键,将只能读而不能写,这等同于第二种方法中将 writable 置为 false 。只有使用第二种方法并将 writable 置为 true 才可以对子键进行些操作。否则会引发 UnauthorizedException 。
以下从‘ 读’‘ 写’‘ 删除’‘ 判断’ 四个事例实现对注册表的简单操作
1. 读取指定名称的注册表的值
private string GetRegistData(string name)
{
string registData;
RegistryKey hkml = Registry.LocalMachine;
RegistryKey software = hkml.OpenSubKey("SOFTWARE",true);
RegistryKey aimdir = software.OpenSubKey("XXX",true);
registData = aimdir.GetValue(name).ToString();
return registData;
}
以上是读取的注册表中HKEY_LOCAL_MACHINE\SOFTWARE 目录下的XXX 目录中名称为name 的注册表值;
2. 向注册表中写数据
private void WTRegedit(string name,string tovalue)
{
RegistryKey hklm = Registry.LocalMachine;
RegistryKey software = hklm.OpenSubKey("SOFTWARE",true);
RegistryKey aimdir = software.CreateSubKey("XXX");
aimdir.SetValue(name,tovalue);
}
以上是在注册表中HKEY_LOCAL_MACHINE\SOFTWARE 目录下新建XXX 目录并在此目录下创建名称为name 值为tovalue 的注册表项;
3. 删除注册表中指定的注册表项
private void DeleteRegist(string name)
{
string[] aimnames;
RegistryKey hkml = Registry.LocalMachine;
RegistryKey software = hkml.OpenSubKey("SOFTWARE",true);
RegistryKey aimdir = software.OpenSubKey("XXX",true);
aimnames = aimdir.GetSubKeyNames();
foreach(string aimKey in aimnames)
{
if(aimKey == name)
aimdir.DeleteSubKeyTree(name);
}
}
以上是在注册表中HKEY_LOCAL_MACHINE\SOFTWARE 目录下XXX 目录中删除名称为name 注册表项;
4. 判断指定注册表项是否存在
private bool IsRegeditExit(string name)
{
bool _exit = false;
string[] subkeyNames;
RegistryKey hkml = Registry.LocalMachine;
RegistryKey software = hkml.OpenSubKey("SOFTWARE",true);
RegistryKey aimdir = software.OpenSubKey("XXX",true);
subkeyNames = aimdir.GetSubKeyNames();
foreach(string keyName in subkeyNames)
{
if(keyName == name)
{
_exit = true;
return _exit;
}
}
return _exit;
}
以上是在注册表中HKEY_LOCAL_MACHINE\SOFTWARE 目录下XXX 目录中判断名称为name 注册表项是否存在,这一方法在删除注册表时已经存在,在新建一注册表项时也应有相应判断
自己写的代码关键是思路要清晰
RegistryKey self=Registry .LocalMachine .OpenSubKey ("software" ,true ).CreateSubKey ("self" );
RegistryKey self1=self .CreateSubKey("self1" );
self1.SetValue("name1" ,"changlina" );
self1.SetValue("name2" ,"changlili" );
self1.SetValue("name3" ,"dufan" );
RegistryKey self2 = self.CreateSubKey("self2" );
self2.SetValue("name1" ,"gejing" );
self2.SetValue("name2" ,"huoting" );
self2.SetValue("name3" ,"guilin" );
//setvalue 的第二个参数是object 类型的,string ,int 等类型都是从object 类型继承来的,所以都能用。key2.SetValue("1", 12); 这个是为了测试当第二个参数是int 型时候结果是怎么样的,这里结果是12
RegistryKey self3 = self.CreateSubKey("self3" );
self3.SetValue("name1" ,"liuyingying" );
self3.SetValue("name2" ,"liangsijia" );
self3.SetValue("name3" ,"limin" );
// 上述在software 下定义了一个子键self ,在self 下面又定义了三个子键soft1 ,soft2 ,soft3 ,关键在于理解这四个都是registrykey 类型的,但是在self1 ,self2 ,self3 下赋值并不是registrykey 的类型,所以是直接调用的函数的;
foreach (string aain self.GetSubKeyNames())
{
Response.Write("self 下的子键名字是" +aa+"<br>" );
foreach (string ssin self.OpenSubKey(aa).GetValueNames())//getvaluename 是取值的名字的函数
{
Response.Write(" 子键中键值的名字是:" + ss +" 子键中键值的值是" + self.OpenSubKey (aa).GetValue(ss) +"<br>" );
}
}
删除注册表时候用到的函数 DeleteSubKeyTree DeleteSubKey DeleteValue
deletesubkey 这个函数的时候会把子键下的所有的键值一起都删了
DeleteValue 是把键值的名字和值一起给删除了,并不是只删除了值
protected void Button2_Click(object sender,EventArgs e)
{
RegistryKey del =Registry .LocalMachine.OpenSubKey("software" ,true );
del.OpenSubKey("self" ,true ).DeleteSubKeyTree ("self1" );
Response .Write (" 一次性删除self1 下的所有了<br>" );
//del.OpenSubKey("self", true).OpenSubKey("self2", true).DeleteSubKey("name1");
//Response.Write(" 删除了self2 的subkey name1<br>"); 这两行是错误的 应为name1 不是子键了,所以不能用delsubkey 来操作了
del.OpenSubKey("self" ,true ).OpenSubKey("self2" ,true ).DeleteValue("name2" );// 其实是把name2 名字和值一起给删除了,并不是只删除了值
Response.Write(" 删除了self2 的子键name2 的值<br>" );
Response.Write(" 查看注册表,应该在software 下还剩下self 下的self2 的没有name2 ,name1 和name3 和self3 下的所有的值<br>" );
del.OpenSubKey("self" ,true ).DeleteSubKey("self2" );//self2 下有三个键值,看看用删除子键的函数是不是把键值一起删除了;
Response.Write(" 查看self2 下面是不是把所有的键值都删了,用的是deletesubkey 看是不是把子键下所有的键值一起都删了?" );
// 结果是当用deletesubkey 这个函数的时候会把子键下的所有的键值一起都删了
del.OpenSubKey("self" ,true ).DeleteSubKey("self3" );
}