How do I check whether a user is allowed to read / write a particular registry key?

前端 未结 6 548
清歌不尽
清歌不尽 2020-12-31 08:14

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\

相关标签:
6条回答
  • 2020-12-31 08:58

    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).

    0 讨论(0)
  • 2020-12-31 09:03

    The RegistryPermission class 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 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
    {
        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:

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-31 09:06

    Just try to open the registry key with WRITE permissions.

    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.

    0 讨论(0)
  • 2020-12-31 09:07

    Simplest option is to try and open the key with write access and see if you get it. Remember to close the key afterwards.

    bool fWriteAccess;
    try {
        Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).Close();
        fWriteAccess = True;
    } catch (SecurityException) {
        fWriteAccess = False;
    }
    
    0 讨论(0)
  • 2020-12-31 09:08

    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 fail with 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.

    Granted security permissions tend to be relatively stable, but the chance still exists. This means that you must have 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.

    0 讨论(0)
  • 2020-12-31 09:16

    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.

    0 讨论(0)
提交回复
热议问题