如何检查是否允许用户读/写特定的注册表项?

时间:2009-07-27 15:08:25

标签: c# windows permissions registry

是否有人知道如何以编程方式检查(使用C#)我的程序是否能够读取/写入特定的注册表项(具体为:“SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run”)?

我问,因为我的程序可以选择启用或禁用“启动时运行”行为。如果不允许当前用户对注册表进行更改,我想禁用此选项。该密钥是否始终允许由当前用户写入,或者是否可能已被锁定?如果是后者,我该如何检查?

我已经看到了几种检查注册表权限的冲突方式 - 但基本上我在尝试阅读之前找不到检查特定密钥的方法。我希望在访问密钥之前执行检查,而不是尝试访问它并接收异常。

非常感谢任何帮助。

汤姆

6 个答案:

答案 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键。也许注册表将超过分配的内存。也许磁盘失败了。

相关问题