是否有人知道如何以编程方式检查(使用C#)我的程序是否能够读取/写入特定的注册表项(具体为:“SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run”)?
我问,因为我的程序可以选择启用或禁用“启动时运行”行为。如果不允许当前用户对注册表进行更改,我想禁用此选项。该密钥是否始终允许由当前用户写入,或者是否可能已被锁定?如果是后者,我该如何检查?
我已经看到了几种检查注册表权限的冲突方式 - 但基本上我在尝试阅读之前找不到检查特定密钥的方法。我希望在访问密钥之前执行检查,而不是尝试访问它并接收异常。
非常感谢任何帮助。
汤姆
答案 0 :(得分:16)
RegistryPermission类管理reg密钥周围的安全权限。要检查您是否具有对权限的写入权限,请按以下方式使用它:
RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
然后,您将在try / catch中使用“Demand”方法,并在失败时返回(引发安全性异常)。成功后,您将继续并执行更新。虽然这不是您想要的,但在访问之前检查权限,这是确保您在操作密钥之前拥有所需权限的可接受方式。以完全结构化的方式,这相当于:
try
{
RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
perm1.Demand();
}
catch (System.Security.SecurityException ex)
{
return;
}
//Do your reg updates here
编辑:考虑我在评论中提到的内容,这里是RegistryPermission类的扩展方法,用于权限检查:
using System.Security.Permissions;
using System.Security;
public static class RegistryExtensions
{
public static bool HavePermissionsOnKey(this RegistryPermission reg, RegistryPermissionAccess accessLevel, string key)
{
try
{
RegistryPermission r = new RegistryPermission(accessLevel, key);
r.Demand();
return true;
}
catch (SecurityException)
{
return false;
}
}
public static bool CanWriteKey(this RegistryPermission reg, string key)
{
try
{
RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Write, key);
r.Demand();
return true;
}
catch (SecurityException)
{
return false;
}
}
public static bool CanReadKey(this RegistryPermission reg, string key)
{
try
{
RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Read, key);
r.Demand();
return true;
}
catch (SecurityException)
{
return false;
}
}
}
答案 1 :(得分:7)
您应该了解权限的一件事是它们是 volatile 。这意味着您可以对注册表项进行安全检查,仅在检查通过时尝试添加您的值,然后仍然失败且访问权限异常不足,因为权限在您创建之间发生了变化检查以及何时对结果采取行动。即使它们是程序中的连续语句,也可以这样做。
授予的安全权限往往相对稳定,但机会仍然存在。这意味着您必须拥有处理安全例外的代码,如果您必须这样做,那么首先进行检查并没有任何意义。相反,花点时间让你的异常处理程序更好一些。
对任何想要在初创公司运行的应用程序说“嘘”。 YAGNI。
答案 2 :(得分:5)
我认为最好的办法就是尝试将您的价值添加到密钥中,并通过告知用户他们没有足够的权限来妥善处理故障。
如果您正在编写某种旨在始终由管理员运行的管理工具,则应在manifest中指明。这样你的应用程序将在启动时提升(通过UAC提示)。
答案 3 :(得分:1)
最简单的选择是尝试open具有写访问权限的密钥,看看是否得到它。之后请记住close密钥。
bool fWriteAccess;
try {
Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).Close();
fWriteAccess = True;
} catch (SecurityException) {
fWriteAccess = False;
}
答案 4 :(得分:0)
我不确定如何使用C#,但使用Win32,您将使用RegGetKeySecurity()
。也许有一个C#包装器?否则,请使用P / Invoke。
答案 5 :(得分:0)
尝试使用WRITE权限打开注册表项。
那说,别人说的是对的:除非你尝试,否则无法判断一项手术是否会成功。也许有人删除了Run键。也许注册表将超过分配的内存。也许磁盘失败了。