有谁知道我怎样才能以编程方式检查(使用C#)我的程序是否能够读/写特定的registry项(具体为:“SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run”)?
我在问,因为我的程序可以select启用或禁用“在启动时运行”的行为。 如果当前用户不允许对registry进行更改,我想禁用此选项。 这个键是否总是被当前用户写入,还是有被locking的可能? 如果是后者,我该如何检查?
我已经看到了几个冲突的方式来检查registry权限 – 但基本上我找不到一种方法来检查一个特定的密钥,然后再尝试阅读它。 我宁愿在访问密钥之前执行检查,而不是尝试访问它并收到exception。
任何帮助深表感谢。
汤姆
RegistryPermission类管理注册表项的安全权限。 要检查您是否有写权限的权限,请按以下方式使用它:
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; } } }
有一点你应该知道的权限是,他们是不稳定的 。 这意味着您可以在注册表项上进行安全性检查,只有在检查通过后才尝试添加值,然后仍然因为访问权限不足而失败 ,因为在执行检查时以及在执行操作时结果。 即使它们是程序中的连续语句,也是可以的。
授予的安全权限往往相对稳定,但机会依然存在。 这意味着你必须有代码来处理安全异常,如果你必须这样做的话,首先做检查并没有什么意义。 相反,把你的时间放在让你的异常处理程序好一点点。
这就是说,“嘘”任何应用程序,想在启动时运行的东西。 YAGNI。
我认为你最好的办法就是试着把你的价值添加到关键中,并通过告知用户他们没有足够的权限去处理失败。
如果您正在编写某种旨在始终由管理员运行的管理工具,则应在清单中指明该工具。 这样你的应用程序将在启动时提升(通过UAC提示)。
最简单的选择是尝试打开具有写权限的密钥,看看是否得到它。 记得在之后关闭钥匙。
bool fWriteAccess; try { Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).Close(); fWriteAccess = True; } catch (SecurityException) { fWriteAccess = False; }
我不知道如何与C#,但与Win32,你会使用RegGetKeySecurity()
。 也许有一个C#包装? 否则,使用P / Invoke。
试试用WRITE权限打开注册表项。
也就是说,其他人所说的是对的:除非你尝试一下,否则无法判断一个操作是否会成功。 也许有人删除了运行键。 也许注册表将超过分配的内存。 也许磁盘失败。