必须以管理员权限运行才能写入HKEY_LOCAL_MACHINE;OpenSubKey需显式指定writable:true;注意WOW64重定向及值类型匹配,否则静默失败或读取异常。
Microsoft.Win32.Registry 读写本地注册表必须以管理员权限运行Windows 对 HKEY_LOCAL_MACHINE(尤其是 SOFTWARE、SYSTEM)有严格写入限制。即使代码语法正确,RegistryKey.SetValue() 也会静默失败或抛出 UnauthorizedAccessException。这不是 .NET 的 bug,而是 UAC 机制在起作用。
实操建议:
app.manifest 中设置 requestedExecutionLevel level="requireAdministrator"
HKEY_CURRENT_USER)通常无需提权Registry.LocalMachine 或 Registry.CurrentUser 静态实例更安全RegistryKey.OpenSubKey() 默认是只读,写入前必须显式指定 writable: true
这是最常被忽略的参数陷阱。以下代码看似合理,实则写入会失败:
var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\MyApp");
key.SetValue("Version", "1.2.3"); // 抛出 NotSupportedException正确写法:
var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\MyApp", writable: true);
if (key != null)
{
key.SetValue("Version", "1.2.3");
key.Close();
}注意点:
OpenSubKey(path, writable: false) 是默认行为,不可省略 writable: true
OpenSubKey() 返回 null;需用 CreateSubKey() 创建CreateSubKey() 自动具备写权限,但返回值仍需判空(可能因权限/路径非法失败)RegistryValueKind.String,误设会导致读取异常注册表值有多种类型:String、DWord、QWord、Binary、ExpandString 等。C# 默认用 SetValue(name, value) 写入时类型为 String,但若目标程序期望的是 DWord(比如开关配置),就会读错。
示例:写入布尔开关应使用 DWord 类型

key.SetValue("EnableLogging", 1, RegistryValueKind.DWord); // 正确
key.SetValue("EnableLogging", "1"); // 错误:存成字符串,其他程序可能无法识别读取时也需匹配类型:
key.GetValue("EnableLogging") 返回 object,需手动转型key.GetValueKind("EnableLogging") 可检查实际存储类型DWord 值,用 (int)key.GetValue("name") 更安全,避免装箱异常在 64 位 Windows 上,32 位 .NET 应用(如 AnyCPU + Prefer 32-bit)调用 Registry.LocalMachine 时,SOFTWARE 下的键会被自动映射到 SOFTWARE\WOW6432Node。这意味着你写入的位置和 64 位程序看到的位置不同。
解决方式取决于需求:
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)
Environment.Is64BitOperatingSystem 判断,再选视图示例(强制访问原生 64 位视图):
using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64); using var key = baseKey.OpenSubKey(@"SOFTWARE\MyApp", writable: true);
这个细节在部署服务或跨架构调试时极易踩坑——你以为写进去了,其实写到了镜像节点里。