目录
注册表是一个庞大的数据库系统,它记录了用户安装在计算机上的软件、硬件信息和每一个程序的相互关系。注册表中存放着很多参数,直接控制着整个系统的启动、硬件驱动程序的装载以及应用程序的运行。
由于Windows 10系统本身的安全性问题,使用C#操作注册表时,可能会提示无法操作相应的注册表项,这时只需要为提示的注册表项添加everyone用户的读写权限即可。
一、注册表基础
Windows注册表包含Windows安装、用户喜好以及已安装软件和设备的所有配置信息的核心存储库。
1.Registry 和 RegistryKey 类
NET Framework提供了访问注册表的类,比较常用的是Registry和RegistryKey类,这两个类都在Microsoft.Win32命名空间中。
(1)Registry类
Registry类不能被实例化,它的作用只是实例化RegistryKey类,以便开始在注册表中浏览。Registry类是通过静态属性来提供这些实例的,这些属性共有7个:
|-----------------|------------------------------------------------------------|
| 属 性 | 说 明 |
| ClassesRoot | 定义文档的类型(或类)以及与那些类型关联的属性。该字段读取Windows注册表基项HKEY_CLASSES_ROOT |
| CurrentConfig | 包含有关非用户特定的硬件的配置信息。该字段读取Windows注册表基项HKEY_CURRENT_CONFIG |
| CurrentUser | 包含有关当前用户首选项的信息。该字段读取Windows注册表基项HKEY_CURRENT_USER |
| DynData | 包含动态注册表数据。该字段读取Windows注册表基项HKEY_DYN_DATA |
| LocalMachine | 包含本地计算机的配置数据。该字段读取Windows注册表基项HKEY_LOCAL_MACHINE |
| PerformanceData | 包含软件组件的性能信息。该字段读取Windows注册表基项HKEY_PERFORMANCE_DATA |
| Users | 包含有关默认用户配置的信息。该字段读取Windows注册表基项HKEY_USERS |
Registry类主要用于存储有关用户首选项的信息、存储本地计算机的配置信息、存储有关类型和类及其属性的信息、存储有关默认用户配置的信息、存储软件组件的性能信息、存储非用户特定的硬件信息、存储动态数据。
(2)RegistryKey类
RegistryKey实例表示一个注册表项,这个类的方法可以浏览子键、创建新键、读取或修改键中的值。也就是说,该类可以完成对注册表项的所有操作。除了设置键的安全级别之外,RegistryKey类可以用于完成对注册表的所有操作。
RegistryKey类的常用属性及说明:
|-------------|-------------|
| 属 性 | 说 明 |
| Name | 检索项的名称 |
| SubKeyCount | 检索当前项的子项数目 |
| ValueCount | 检索项中值的计数 |
RegistryKey类的常用方法及说明
|------------------|----------------------------|
| 方法 | 说 明 |
| Close | 关闭键 |
| CreateSubkey | 创建给定名称的子键(如果该子键已经存在,就打开它) |
| DeleteSubkey | 删除指定的子键 |
| DeleteSubkeyTree | 彻底删除子键及其所有的子键 |
| DeleteValue | 从键中刑除一个指定的值 |
| GetSubkeyNames | 返回包含子键名称的字符串数组 |
| GetValue | 返回指定的值 |
| GetValueNames | 返回一个包含所有键值名称的字符申数组 |
| OpenSubKey | 返回表示给定子键的 RegistryKey 实例引用 |
| SetValue | 设置指定 |
二、在 C# 中操作注册表
主要包括读取注册表中的信息、删除注册表中的信息以及创建和删除注册表信息。
1.读取注册表中的信息
读取注册表中的信息主要是通过RegistryKey类中的OpenSubKey()方法、GetSubKeyNames()方法和GetValueNames()方法实现的。
(1)OpenSubKey()方法
OpenSubKey()方法用于检索指定的子项。
cs
public RegistryKey OpenSubKey(string name)
☑ name:要以只读方式打开的子项的名称或路径。
☑ 返回值:请求的子项。如果操作失败,则为空引用。
如果要打开的项不存在,OpenSubKey()方法将返回null引用,而不是引发异常。
(2)GetSubKeyNames()方法
GetSubKeyNames()方法用于检索包含所有子项名称的字符串数组。
cs
public string[]GetSubKeyNames()
返回值:包含当前项的子项名称的字符串数组。
如果当前项已被删除,或是用户没有读取该项的权限,将触发异常。
cs
// 通过GetSubKeyNames()方法检索
// HKEY_LOCAL_MACHINE\SOFTWARE子键下包含的
// 所有子项名称的字符串数组
using Microsoft.Win32;
namespace _01
{
public partial class Form1 : Form
{
private RichTextBox? richTextBox1;
public Form1()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object? sender, EventArgs e)
{
//
// richTextBox1
//
richTextBox1 = new RichTextBox
{
Dock = DockStyle.Fill,
Location = new Point(0, 0),
Name = "richTextBox1",
Size = new Size(284, 241),
TabIndex = 0,
Text = ""
};
RegistryKey regkey = Registry.LocalMachine;
RegistryKey? sys = regkey.OpenSubKey(@"SOFTWARE");
foreach (string str in sys!.GetSubKeyNames())
{
richTextBox1.Text += str + "\n";
}
//
// Form1
//
AutoScaleDimensions = new SizeF(6F, 12F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(284, 241);
Controls.Add(richTextBox1);
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "Form1";
}
}
}
(3)GetValueNames()方法
GetValueNames()方法用于检索包含与此项关联的所有值名称的字符串数组。
cs
public string[]GetValueNames()
返回值:包含当前项的值名称的字符串数组。
如果没有找到此项的值名称,则返回一个空数组;如果在注册表项设置了一个具有默认值的名称为空字符串的项,则GetValueNames()方法返回的数组中包含该空字符串。
cs
// 读取HKEY_LOCAL_MACHINE\SOFTWARE子键下的项目信息
// 利用对象的OpenSubKey()方法打开指定的键
using Microsoft.Win32;
namespace _02
{
public partial class Form1 : Form
{
private ListBox? listBox1;
public Form1()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object? sender, EventArgs e)
{
listBox1 = new ListBox
{
Dock = DockStyle.Fill,
FormattingEnabled = true,
ItemHeight = 12,
Location = new Point(0, 0),
Name = "listBox1",
Size = new Size(294, 271),
TabIndex = 0
};
listBox1.Items.Clear();
var regkey = Registry.LocalMachine;
RegistryKey? sys = regkey.OpenSubKey(@"SOFTWARE");
foreach (string str in sys!.GetSubKeyNames())
{
listBox1.Items.Add("子项名:" + str);
RegistryKey? sikey = sys.OpenSubKey(str); //打开子键
foreach (string sVName in sikey!.GetValueNames())
{
listBox1.Items.Add(sVName + sikey.GetValue(sVName));
}
}
//
// Form1
//
AutoScaleDimensions = new SizeF(6F, 12F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(294, 271);
Controls.Add(listBox1);
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "Form1";
}
}
}
2.创建和修改注册表信息
(1)创建注册表信息
通过RegistryKey类的CreateSubKey()方法和SetValue()方法可以创建注册表信息,下面介绍这两种方法。
- CreateSubKey()方法
主要用于创建一个新子项或打开一个现有子项以进行写访问。
cs
public RegistryKey CreateSubKey (string subkey)
☑ subkey:要创建或打开的子项的名称或路径。
☑ 返回值:RegistryKey对象,表示新建的子项或空引用。如果为subkey指定了零长度字符串,则返回当前的RegistryKey对象。
- SetValue()方法
主要用于设置注册表项中的名称/值对的值。
cs
public void SetValue (string name,Object value)
☑ name:要存储的值的名称。
☑ value:要存储的数据。
SetValue()方法用于从非托管代码中访问托管类,不应从托管代码调用。
cs
// 通过RegistryKey类的CreateSubKey()方法和SetValue()方法创建一个子键
using Microsoft.Win32;
namespace _03
{
public partial class Form1 : Form
{
private Button? button1;
public Form1()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object? sender, EventArgs e)
{
//
// button1
//
button1 = new Button
{
Location = new Point(12, 12),
Name = "button1",
Size = new Size(75, 23),
TabIndex = 0,
Text = "创建子键",
UseVisualStyleBackColor = true
};
button1.Click += new EventHandler(Button1_Click);
//
// Form1
//
AutoScaleDimensions = new SizeF(6F, 12F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 211);
Controls.Add(button1);
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "创建子键";
}
/// <summary>
/// 在主键HKEY_LOCAL_MACHINE的HARDWARE键下创建一个名为MR的子键,
/// 然后在这个子键下再创建一个名为测试的子键,
/// 在测试子键下创建一个名为value、数据值是1234的键值
/// </summary>
private void Button1_Click(object? sender, EventArgs e)
{
try
{
RegistryKey? hklm = Registry.LocalMachine;
RegistryKey? software = hklm.OpenSubKey("HARDWARE", true);
RegistryKey? main1 = software!.CreateSubKey("MR");
RegistryKey? ddd = main1.CreateSubKey("测试");
ddd.SetValue("value", "1234");
MessageBox.Show("创建成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
(2)修改注册表信息
由于注册表中的信息十分重要,所以一般不要对其进行写的操作。也可能是这个原因,在.Net Framework中并没有提供修改注册表键的方法。而只是提供了一个危害性相对较小的SetValue()方法,通过这个方法,可以修改键值。在使用SetValue()方法时,如果它检测到指定的键值不存在,就会创建一个新的键值。
cs
// 将主键HKEY_LOCAL_MACHINE\HARDWARE\MR\测试
// 下名为value的键值的数据值修改为abcd
using Microsoft.Win32;
namespace _04
{
public partial class Form1 : Form
{
private Button? button1;
public Form1()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object? sender, EventArgs e)
{
//
// button1
//
button1 = new Button
{
Location = new Point(197, 12),
Name = "button1",
Size = new Size(75, 23),
TabIndex = 0,
Text = "修改",
UseVisualStyleBackColor = true
};
button1.Click += new EventHandler(Button1_Click);
//
// Form1
//
AutoScaleDimensions = new SizeF(6F, 12F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(284, 111);
Controls.Add(button1);
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "Form1";
}
private void Button1_Click(object? sender, EventArgs e)
{
try
{
RegistryKey? hklm = Registry.LocalMachine;
RegistryKey? software = hklm?.OpenSubKey("HARDWARE", true);
RegistryKey? dddw = software?.OpenSubKey("MR", true);
RegistryKey? regkey = dddw?.OpenSubKey("测试", true);
regkey?.SetValue("value", "abcd");
MessageBox.Show("修改成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
3.删除注册表中的信息
删除注册表中的信息主要通过RegistryKey类中的DeleteSubKey()方法、DeleteSubKeyTree()方法和DeleteValue()方法来实现。
(1)DeleteSubKey()方法
DeleteSubKey()方法用于删除不包含任何子键的子键。 语法如下:
cs
publie void DeleteSubKey (string subkey,bool throwOnMissingSubKey)
☑ subkey:要删除的子项的名称。
☑ throwOnMissingSubKey:如果值为true,在程序调用时,删除的子键不存在,则产生一个错误信息;如果值为false,在程序调用时,删除的子键不存在,也不产生错误信息,程序依然正确运行。
如果删除的项有子级子项,将触发异常。必须将子项删除后,才能删除该项。
cs
// 通过RegistryKey类的DeleteSubKey()方法删除
// HKEY_LOCAL_MACHINE\HARDWARE\MR键下的测试子键
using Microsoft.Win32;
namespace _05
{
public partial class Form1 : Form
{
private Button? button1;
public Form1()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object? sender, EventArgs e)
{
//
// button1
//
button1 = new Button
{
Location = new Point(118, 46),
Name = "button1",
Size = new Size(75, 23),
TabIndex = 0,
Text = "删除",
UseVisualStyleBackColor = true
};
button1.Click += new EventHandler(Button1_Click);
//
// Form1
//
AutoScaleDimensions = new SizeF(6F, 12F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(331, 99);
Controls.Add(button1);
Name = "Form1";
Text = "Form1";
}
/// <summary>
/// 打开"SOFTWARE"子键
/// 打开MR子键
/// 删除名称为测试的子键
/// </summary>
private void Button1_Click(object? sender, EventArgs e)
{
try
{
RegistryKey? hklm = Registry.LocalMachine;
RegistryKey? software = hklm?.OpenSubKey("HARDWARE", true);
RegistryKey? no1 = software?.OpenSubKey("MR", true);
no1?.DeleteSubKey("测试", false);
MessageBox.Show("删除成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
(2)DeleteSubKeyTree方法
DeleteSubKeyTree()方法用于彻底删除指定的子键目录,包括删除该子键以及该子键以下的全部子键。由于此方法的破坏性非常强,所以在使用时要特别谨慎。语法如下:
cs
public void DeleteSubKeyTree(sting subkey)
subkey:要彻底删除的子键名称。
当删除的项为null时,则触发异常。
cs
// 通过DeleteSubKeyTree()方法将彻底删除
// HKEY_LOCAL_MACHINE\HARDWARE\MR键下的子键
using Microsoft.Win32;
namespace _06
{
public partial class Form1 : Form
{
private Button? button1;
public Form1()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object? sender, EventArgs e)
{
//
// button1
//
button1 = new Button
{
Location = new Point(151, 12),
Name = "button1",
Size = new Size(121, 23),
TabIndex = 0,
Text = "彻底删除子键",
UseVisualStyleBackColor = true
};
button1.Click += new EventHandler(Button1_Click);
//
// Form1
//
AutoScaleDimensions = new SizeF(6F, 12F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(284, 111);
Controls.Add(button1);
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "Form1";
}
/// <summary>
/// 打开"SOFTWARE"子键
/// 打开MR子键
/// 删除名称为测试的子键
/// </summary>
private void Button1_Click(object? sender, EventArgs e)
{
try
{
RegistryKey? hklm = Registry.LocalMachine;
//hklm.DeleteSubKey("aaa", false);
RegistryKey? software = hklm.OpenSubKey("HARDWARE", true);
RegistryKey? no1 = software?.OpenSubKey("MR", true);
no1!.DeleteSubKeyTree("测试");
MessageBox.Show("删除成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
(3)DeleteValue()方法
DeleteValue()方法主要用于删除指定的键值。语法如下:
cs
publie void DeleteValue(string name)
name:要删除的值的名称。
如果在找不到指定值的情况下使用该值,又不想引发异常,可以使用DeleteValue(string name,bool throwOnMissingValue)重载方法。如果throwOnMissingValue参数为true时,将不引发异常。
cs
// 通过DeleteValue方法删除
// HKEY_LOCAL_MACHINE\HARDWARE\MR\测试键下的名称为value的键值
using Microsoft.Win32;
namespace _07
{
public partial class Form1 : Form
{
private Button? button1;
public Form1()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object? sender, EventArgs e)
{
//
// button1
//
button1 = new Button
{
Location = new Point(132, 12),
Name = "button1",
Size = new Size(75, 23),
TabIndex = 0,
Text = "删除键值",
UseVisualStyleBackColor = true
};
button1.Click += new EventHandler(Button1_Click);
//
// Form1
//
AutoScaleDimensions = new SizeF(6F, 12F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(219, 196);
Controls.Add(button1);
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "Form1";
}
/// <summary>
/// 打开"SOFTWARE"子键
/// 打开MR子键,打开测试子键
/// 删除名称为"value"的键值
/// </summary>
private void Button1_Click(object? sender, EventArgs e)
{
try
{
RegistryKey? hklm = Registry.LocalMachine;
RegistryKey? software = hklm?.OpenSubKey("HARDWARE", true);
RegistryKey? no1 = software?.OpenSubKey("MR", true);
RegistryKey? no2 = no1?.OpenSubKey("测试", true);
no2?.DeleteValue("value");
MessageBox.Show("删除键值成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}