C# 如何检查是否允许用户读取/写入特定的注册表项?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1188723/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I check whether a user is allowed to read / write a particular registry key?
提问by HalliHax
Does anybody know how I can programmatically check (using C#) whether my program will be able to read / write a particular registry key (specifically: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run")?
有谁知道我如何以编程方式检查(使用 C#)我的程序是否能够读取/写入特定的注册表项(特别是:“SOFTWARE\Microsoft\Windows\CurrentVersion\Run”)?
I am asking because my program has the option to enable or disable the 'run at startup' behaviour. I want to disable this option if the current user is not allowed to make changes to the registry. Is this key always allowed to be written by the current user, or is there the possibility that it has been locked down? If the latter, how do I check this?
我问是因为我的程序可以选择启用或禁用“启动时运行”行为。如果不允许当前用户对注册表进行更改,我想禁用此选项。此密钥是否始终允许由当前用户写入,或者是否有可能已被锁定?如果是后者,我该如何检查?
I have seen several conflicting ways of checking registry permissions - but basically I can't find a way to check a specific key before I try to read it. I would rather perform the check before accessing the key than trying to access it and receive an exception.
我已经看到了几种相互冲突的检查注册表权限的方法 - 但基本上我无法在尝试阅读特定键之前找到检查它的方法。我宁愿在访问密钥之前执行检查,也不愿尝试访问它并收到异常。
Any help is much appreciated.
任何帮助深表感谢。
Tom
汤姆
采纳答案by Wolfwyrd
The RegistryPermissionclass governs the security permissions around reg keys. To check if you may have write access to a permission you use it in the following manner:
该RegistryPermission的类管理各地雷吉·基斯的安全权限。要检查您是否可以对某个权限进行写访问,请按以下方式使用它:
RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
You would then use the "Demand" method in a try/catch and return on failure (the raising of a security exception). On success you'd carry on and perform your update. Although this isn't quite what you want, a check on permissions before access, it is the accepted way of ensuring you have the permissions you need before you operate on the keys. In a fully structured manner this would equate to:
然后,您将在 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
EDIT:Thinking on what I mentioned in the comment, here are extension methods to the RegistryPermission class for permission checks:
编辑:考虑到我在评论中提到的内容,以下是 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;
}
}
}
回答by Adam Rosenfield
I'm not sure how to it with C#, but with Win32, you would use RegGetKeySecurity()
. Maybe there's a C# wrapper? Otherwise, use P/Invoke.
我不确定如何使用 C#,但使用 Win32,您将使用RegGetKeySecurity()
. 也许有一个 C# 包装器?否则,使用 P/Invoke。
回答by Joel Coehoorn
One thing you should know about permissions is that they are volatile. That means you could do your security check on the registry key, attempt to add your value only if the check passes, and then still failwith an insufficient access exception because the permissions changed in between when you made the check and when you acted on the results. This is possible even if they are consecutive statements in your program.
关于权限,您应该了解的一件事是它们是volatile。这意味着您可以对注册表项进行安全检查,仅当检查通过时才尝试添加您的值,然后仍然会因访问异常不足而失败,因为在您进行检查和执行操作之间权限发生了变化结果。即使它们是程序中的连续语句,这也是可能的。
Granted security permissions tend to be relatively stable, but the chance still exists. This means that you musthave code to handle the security exception, and if you have to do that anyway there's not really any point in making the check in the first place. Instead, put your time into making your exception handler a little bit better.
授予的安全权限往往相对稳定,但机会仍然存在。这意味着您必须拥有处理安全异常的代码,如果您无论如何都必须这样做,那么首先进行检查就没有任何意义。相反,把你的时间花在让你的异常处理程序更好一点上。
That said, "boo" to any app that wants to run something at start-up. YAGNI.
也就是说,对于任何想要在启动时运行某些东西的应用程序来说,“嘘”。亚格尼。
回答by i_am_jorf
I think you best bet is to just try to add your value to the key, and handle failure gracefully by informing the user they didn't have enough permissions to do that.
我认为你最好的办法是尝试将你的值添加到密钥中,并通过通知用户他们没有足够的权限来优雅地处理失败。
If you're writing some sort of administrative tool that is designed to always be run by an administrator, you should indicate that in the manifest. That way your app will elevate at startup (via UAC prompt).
如果您正在编写某种旨在始终由管理员运行的管理工具,您应该在manifest 中指明。这样你的应用就会在启动时提升(通过 UAC 提示)。
回答by peterchen
Just try to open the registry key with WRITE permissions.
只需尝试使用 WRITE 权限打开注册表项即可。
That said, what others have said is right: There is no way to tell if an operation is going to succeed unless you try it. Maybe someon deleted the Run key. Maybe the registry will exceed allocated memory. Maybe the disk failed.
话虽如此,其他人的说法是正确的:除非您尝试,否则无法判断手术是否会成功。也许有人删除了运行键。也许注册表会超出分配的内存。可能是磁盘坏了。
回答by Armin Sadeghi
Simplest option is to try and openthe key with write access and see if you get it. Remember to closethe key afterwards.
最简单的选择是尝试打开具有写入权限的密钥,然后查看是否获得它。之后记得关闭钥匙。
bool fWriteAccess;
try {
Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).Close();
fWriteAccess = True;
} catch (SecurityException) {
fWriteAccess = False;
}