项目场景:
最近一个项目需要用到注册表。在用代码创建注册表子项时,抛出“对注册表项。。。访问被拒绝”的异常。问题描述:
调用RegistryHelper.CreateSubKey 的 var _subKey = m_registryKey.CreateSubKey("SOFTWARE\\" + subKeyString);这句时抛出异常
RegistryHelper注册表帮助类
using Microsoft.Win32;
using System;
using System.Diagnostics;
namespace LchHelper
{
/// <summary>
/// 注册表操作
/// </summary>
public class RegistryHelper
{
//================== construct function ===================
#region construct function 注册表操作
/// <summary>
/// 注册表操作
/// </summary>
public RegistryHelper()
{
}
#endregion
//=================== private fields ======================
#region fields(fields)
private static RegistryKey m_registryKey = Registry.LocalMachine;
#endregion
//==================== public method ======================
/* SunKey */
#region CreateSubKey 创建注册表项
/// <summary>
/// 创建注册表项
/// </summary>
/// <returns></returns>
public static bool CreateSubKey(string subKeyString = "LCHTest")
{
bool _result;
try
{
//注册表是否存在
if (IsRegeditItemExist(subKeyString))
{
return true;
}
var _subKey = m_registryKey.CreateSubKey("SOFTWARE\\" + subKeyString);//抛出异常
_result = _subKey != null ? true : false;
}
catch (Exception ex)
{
Debug.WriteLine($"CreateSubKey{subKeyString}异常:{ex.Message}");
_result = false;
}
return _result;
}
#endregion
#region DeleteSubKey 删除注册表项
/// <summary>
/// 删除注册表项
/// </summary>
/// <returns></returns>
public static bool DeleteSubKey(string subKeyString = "LCHTest")
{
bool _result;
try
{
m_registryKey.DeleteSubKey("SOFTWARE\\" + subKeyString, true);
m_registryKey.Close();
_result = true;
}
catch (Exception ex)
{
Debug.WriteLine($"CreateSubKey{subKeyString}异常:{ex.Message}");
_result = false;
}
return _result;
}
#endregion
/* Value */
#region SetValue 键值的创建与修改[无则创建,有则修改]
/// <summary>
/// 键值的创建与修改[无则创建,有则修改]
/// </summary>
/// <returns></returns>
public static bool SetValue(string name, string value, string subKeyString = "LCHTest")
{
try
{
if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(subKeyString))
{
return false;
}
if (!CreateSubKey())
{
return false;
}
var _subKey = m_registryKey.OpenSubKey("SOFTWARE\\" + subKeyString, true);
_subKey.SetValue(name, value);
m_registryKey.Close();
return true;
}
catch (Exception ex)
{
Debug.WriteLine($"SetValue:{name}:{value}:{subKeyString}异常:{ex.Message}");
return false;
}
}
#endregion
#region GetValue 获取键对应的值
/// <summary>
/// 获取键对应的值
/// </summary>
/// <returns></returns>
public static string GetValue(string name, string subKeyString = "LCHTest")
{
try
{
if (!IsRegeditKeyExit(name, subKeyString))
{
return "";
}
var _subKey = m_registryKey.OpenSubKey("SOFTWARE\\" + subKeyString);
string value = _subKey.GetValue(name).ToString();
_subKey.Close();
return value;
}
catch (Exception ex)
{
Debug.WriteLine($"GetValue:{name}:{subKeyString}异常:{ex.Message}");
return "";
}
}
#endregion
#region DeleteValue 删除键值
/// <summary>
/// 删除键值
/// </summary>
/// <returns></returns>
public static bool DeleteValue(string name, string subKeyString = "LCHTest")
{
try
{
var _subKey = m_registryKey.OpenSubKey("SOFTWARE\\" + subKeyString, true);
_subKey.DeleteValue(name);
_subKey.Close();
return true;
}
catch (Exception ex)
{
Debug.WriteLine($"DeleteValue:{name}:{subKeyString}异常:{ex.Message}");
return false;
}
}
#endregion
//==================== private method =====================
#region IsRegeditItemExist 注册表项是否存在
/// <summary>
/// 注册表项是否存在
/// </summary>
/// <returns></returns>
private static bool IsRegeditItemExist(string subKeyString)
{
var _software = m_registryKey.OpenSubKey("SOFTWARE");
var _subkeyNames = _software.GetSubKeyNames();
foreach (string keyName in _subkeyNames)
{
if (keyName == subKeyString)
{
m_registryKey.Close();
return true;
}
}
m_registryKey.Close();
return false;
}
#endregion
#region IsRegeditKeyExit 键是否存在
/// <summary>
/// 键是否存在
/// </summary>
/// <returns></returns>
private static bool IsRegeditKeyExit(string name, string subKeyString = "LCHTest")
{
if (!IsRegeditItemExist(subKeyString))
{
return false;
}
var _subKey = m_registryKey.OpenSubKey("SOFTWARE\\" + subKeyString);
var _subkeyNames = _subKey.GetValueNames();
foreach (string keyName in _subkeyNames)
{
if (keyName == name)
{
m_registryKey.Close();
return true;
}
}
m_registryKey.Close();
return false;
}
#endregion
}
}
调用代码
RegistryHelper.CreateSubKey();
RegistryHelper.SetValue("lch", "just test");
原因分析:
根据提示信息,有很大可能是操作注册表权限不够导致的。当前系统的登录用户为管理员。当以管理员身份运行 vs,再加载项目时就没有抛出异常。以管理员身份运行 vs
正常执行
注册表(win+r,regedit)
HKEY_LOCAL_MACHINE\SOFTWARE可以找到新建的LCHTest(没找到就先刷新一下)
解决方案:
综上,问题产生愿意是没有管理员权限(没有操作注册表权限)。 因此要确保程序在运行中有管理员权限,否则就无法操作注册表。确保程序在运行中有管理员权限,可参考
Cosmic_Spy 的 C#程序以管理员权限运行https://www.cnblogs.com/Interkey/p/RunAsAdmin.html
方法一:通过 System.Diagnostics.Process.Start() 方式启动:
由于通过System.Diagnostics.Process.Start() 方式外部调用启动,所以无法加断点调试
方法二:通过添加应用程序清单文件:
可具体参考 kucoffee12 的 C#获取管理员权限 https://blog.csdn.net/kucoffee12/article/details/100176821
如果在VS中 启动调试 的话,就会提示 此任务要求应用程序具有提升的权限
方法三:直接修改程序文件的属性