推荐图书
《C# 开发实战1200例》当年就是靠着这本书入门,非常实用【优惠券】
using Microsoft.Win32;
using System;
using System.Security;
public class RegistryHelper
{
// 注册表根键枚举
public enum RegistryRootKey
{
ClassesRoot,
CurrentUser,
LocalMachine,
Users,
CurrentConfig
}
private readonly RegistryKey _rootKey;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="rootKey">要操作的注册表根键</param>
public RegistryHelper(RegistryRootKey rootKey)
{
_rootKey = GetRootKey(rootKey);
}
/// <summary>
/// 将枚举转换为实际的RegistryKey对象
/// </summary>
private RegistryKey GetRootKey(RegistryRootKey rootKey)
{
return rootKey switch
{
RegistryRootKey.ClassesRoot => Registry.ClassesRoot,
RegistryRootKey.CurrentUser => Registry.CurrentUser,
RegistryRootKey.LocalMachine => Registry.LocalMachine,
RegistryRootKey.Users => Registry.Users,
RegistryRootKey.CurrentConfig => Registry.CurrentConfig,
_ => throw new ArgumentException("Invalid root key")
};
}
/// <summary>
/// 读取注册表值
/// </summary>
/// <param name="subKeyPath">子键路径</param>
/// <param name="valueName">值名称</param>
/// <returns>读取到的值,如果不存在返回null</returns>
public object ReadValue(string subKeyPath, string valueName)
{
try
{
using RegistryKey? subKey = _rootKey.OpenSubKey(subKeyPath);
return subKey?.GetValue(valueName);
}
catch (SecurityException ex)
{
throw new SecurityException("访问注册表需要管理员权限", ex);
}
catch (UnauthorizedAccessException ex)
{
throw new UnauthorizedAccessException("无权访问注册表项", ex);
}
}
/// <summary>
/// 写入注册表值
/// </summary>
/// <param name="subKeyPath">子键路径</param>
/// <param name="valueName">值名称</param>
/// <param name="value">要写入的值</param>
/// <param name="valueKind">值的类型</param>
public void WriteValue(string subKeyPath, string valueName, object value, RegistryValueKind valueKind)
{
try
{
using RegistryKey subKey = _rootKey.CreateSubKey(subKeyPath, true);
subKey.SetValue(valueName, value, valueKind);
}
catch (SecurityException ex)
{
throw new SecurityException("写入注册表需要管理员权限", ex);
}
catch (UnauthorizedAccessException ex)
{
throw new UnauthorizedAccessException("无权写入注册表项", ex);
}
}
/// <summary>
/// 删除注册表值
/// </summary>
/// <param name="subKeyPath">子键路径</param>
/// <param name="valueName">要删除的值名称</param>
public void DeleteValue(string subKeyPath, string valueName)
{
try
{
using RegistryKey? subKey = _rootKey.OpenSubKey(subKeyPath, true);
subKey?.DeleteValue(valueName, false);
}
catch (ArgumentException ex)
{
throw new ArgumentException("指定的值不存在", ex);
}
catch (SecurityException ex)
{
throw new SecurityException("删除注册表值需要管理员权限", ex);
}
}
/// <summary>
/// 检查子键是否存在
/// </summary>
public bool SubKeyExists(string subKeyPath)
{
using RegistryKey? subKey = _rootKey.OpenSubKey(subKeyPath);
return subKey != null;
}
/// <summary>
/// 创建子键
/// </summary>
public void CreateSubKey(string subKeyPath)
{
try
{
_rootKey.CreateSubKey(subKeyPath)?.Dispose();
}
catch (SecurityException ex)
{
throw new SecurityException("创建子键需要管理员权限", ex);
}
}
/// <summary>
/// 删除子键(递归删除所有子项)
/// </summary>
public void DeleteSubKey(string subKeyPath)
{
try
{
_rootKey.DeleteSubKeyTree(subKeyPath);
}
catch (SecurityException ex)
{
throw new SecurityException("删除子键需要管理员权限", ex);
}
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
_rootKey.Dispose();
GC.SuppressFinalize(this);
}
}
使用示例:
class Program
{
static void Main()
{
try
{
// 初始化操作CurrentUser下的注册表项
var helper = new RegistryHelper(RegistryHelper.RegistryRootKey.CurrentUser);
const string testSubKey = @"Software\RegistryHelperTest";
const string valueName = "TestValue";
// 创建测试子键
if (!helper.SubKeyExists(testSubKey))
{
helper.CreateSubKey(testSubKey);
}
// 写入测试值
helper.WriteValue(testSubKey, valueName, 12345, RegistryValueKind.DWord);
// 读取测试值
var value = helper.ReadValue(testSubKey, valueName);
Console.WriteLine($"读取到的值: {value}");
// 删除测试值
helper.DeleteValue(testSubKey, valueName);
// 删除测试子键
helper.DeleteSubKey(testSubKey);
}
catch (Exception ex)
{
Console.WriteLine($"操作失败: {ex.Message}");
}
}
}
重要说明:
权限要求:
- 操作
HKEY_LOCAL_MACHINE
需要管理员权限 - 在Visual Studio中运行时需要以管理员身份启动
- 打包程序时需要设置管理员权限清单
- 操作
注册表类型对照:
RegistryValueKind.String // 字符串 RegistryValueKind.DWord // 32位整数 RegistryValueKind.QWord // 64位整数 RegistryValueKind.Binary // 二进制数据 RegistryValueKind.MultiString // 字符串数组
异常处理:
SecurityException
:权限不足UnauthorizedAccessException
:访问被拒绝ArgumentException
:参数错误- 建议在使用时进行try-catch处理
路径规范:
- 使用反斜杠分隔路径,例如:@“Software\MyCompany\MyApp”
- 不要包含根键名称(例如不要写HKEY_CURRENT_USER…)
资源管理:
- 类实现了IDisposable接口
- 长期使用时建议使用using语句
using (var helper = new RegistryHelper(...)) { // 操作代码 }
注意事项:
- 修改注册表可能影响系统稳定性,操作前建议备份注册表
- 生产代码中建议添加更详细的日志记录
- 对于关键系统位置(如系统服务相关项),建议使用Windows API代替直接注册表操作
- 32/64位系统注册表重定向问题需要注意(可通过使用RegistryView枚举处理)