C# Registry SetValue throws UnauthorizedAccessException
Asked Answered
F

7

11

Before you try to answer this with, "Do a quick Google search." I'd like to point out that I have already. Here is the situation, I have the following method that attempts to modify a registry key value. The problem I'm getting is that when executed, it throws an UnauthorizedAccessException even though I've opened the key as writeable. I'm running Visual Studio as administrator and even tried to make a small .exe with a manifest file forcing it to run as admin that will execute the code with no luck. The key already exists, it doesn't try to go into the CreateKey method. Here is the block of code.

Path = "S-1-5-21-1644491937-1078145449-682003330-5490\Software\Microsoft\Windows\CurrentVersion\Policies\System"
Key = "DisableTaskMgr"
NewValue = 1

public OperationResult ModifyKey()
    {
        OperationResult result = new OperationResult();

        if (!Path.IsNullOrEmptyTrim())
        {
            if (!Key.IsNullOrEmptyTrim())
            {
                try
                {
                    var key = Microsoft.Win32.Registry.Users.OpenSubKey(Path, true);

                    if (key != null)
                    {
                        key.SetValue(Key, NewValue);

                        key.Close();
                    }
                    else
                    {
                        result = CreateKey();
                    }
                }
                catch (Exception ex)
                {
                    result.SetFail("Error accessing registry", ex);
                }
            }
            else
            {
                result.SetFail("Registry key was null");
            }
        }
        else
        {
            result.SetFail("Registry path was null");
        }

        return result;
    }

Do I have to manually walk down the registry tree setting each OpenSubKey call to writeable? I tried this as well, still threw the same error...

Folkway answered 1/8, 2012 at 21:56 Comment(9)
Please confirm that you can modify the key in question running regular regedit.Aerology
Yes, I can modify the key at will using regedit. I do have admin rights and like I said in my post, I've tried creating a simple .exe with a manifest to force running as administrator.Folkway
You may also want to test under this with different user account or on another machine.Dipterous
I did attempt to test this code on my Windows XP virtual machine as well, same issue. On the XP box, the User ID was obviously different, it pulls the user ID of the currently logged in user. I've also tried modifying the HKEY_CURRENT_USER key in the same spot thinking that it could be an issue with the User, same error.Folkway
I tried a simplified version of this code on my Windows 7 machine (I didn't have the System\DisableTaskMgr key-value so I had to create it), and it worked...Mabuse
I'm glad it worked on someone's machine, I'm at a complete loss as to why it won't work for me. I'm going to try and reboot and see if that helps... I'm not sure what else to try.Folkway
Also, what version of .NET are you using? My test was on .NET 4.Mabuse
Could you please post the full exception details (including call stack), as returned by its ToString() method?Scurrilous
"System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.\r\n at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)\r\n at Microsoft.Win32.RegistryKey.SetValue(String name, Object value, RegistryValueKind valueKind)\r\n at Microsoft.Win32.RegistryKey.SetValue(String name, Object value)\r\n at somenamespace.RegistryItem.ModifyKey() in C:\\Dev\\RegistryItem.cs:line 76"Folkway
F
3

As a last ditch effort to figure out what was going on, I created a simple service to test this code that will run as the local system account. It's the highest privileges I could think of to try and run the code with. Running the code with these permissions worked.

Special thanks go out to 0_____0 and Charleh for pointing out the anti-virus as well. I checked the logs and it turns out it was trying to quarantine my changes. I guess even it won't stop the System user from making these changes though.

Special thanks go out to Sorceri as well for helping me research this so much.

In conclusion, if you're having intermittent, extremely odd behavior, check your virus scanner and permissions.

Folkway answered 2/8, 2012 at 16:24 Comment(0)
P
19

in the var for your key

var key = Microsoft.Win32.Registry.Users.OpenSubKey(Path, true);

change to

var key = Microsoft.Win32.Registry.Users.OpenSubKey(Path, RegistryKeyPermissionCheck.ReadWriteSubTree);  
Phago answered 1/8, 2012 at 22:21 Comment(5)
I actually did try that as well, it gave me the same error, so I reverted my code. Thanks for the suggestion though.Folkway
The exception is thrown at SetValue.Folkway
Have you tried that code on another key? Also why the use of an implicit variable with var, why not use RegistryKeyPhago
There is no particular reason for the var rather than naming it explicitly. As for the code on another key, see my response to your post here: linkFolkway
This one worked for me. I have a machine with UAC disabled, without setting ReadWriteSubTree it would always raise access denied exceptionNakashima
S
5

Have you tried setting the accessrule and permissions?

 string user = Environment.UserDomainName + "\\" + Environment.UserName;
 RegistryAccessRule rule = new RegistryAccessRule(user,
        RegistryRights.FullControl,
        AccessControlType.Allow);        
 RegistrySecurity security = new RegistrySecurity();
 security.AddAccessRule(rule);
 var key = Microsoft.Win32.Registry.Users.OpenSubKey(subKeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl);
 key.SetAccessControl(security);
Sosthenna answered 1/8, 2012 at 22:35 Comment(4)
I didn't see an overload for OpenSubKey that accepts RegistrySecurity, I did try this though: var key = Microsoft.Win32.Registry.Users.OpenSubKey(Path, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl); same error.Folkway
Ah, you're correct, I've edited my answer, but I don't know if it will do anything.Sosthenna
Sorry, I can't replicate it, maybe try disabling your antivirus software; I've seen problems where the AV will prevent access without any pop-ups. It could block you from modifying certain keys. That's the only thing I can think of, AV stopping it.Sosthenna
Yep - AV, where I work the support guys have this rule... it goes ' Always check McAfee FIRST'! The number of times people have spent hours looking into something and dismissed the AV because it didn't seem like it could be the issue..!Apheliotropic
M
3

One possible issue that I see with your code is that the Path variable is being set to a string that doesn't escape the \ characters. How about something like:

Path = @"S-1-5-21-1644491937-1078145449-682003330-5490\Software\Microsoft\Windows\CurrentVersion\Policies\System";
Mabuse answered 1/8, 2012 at 22:6 Comment(10)
The Path that I posted is actually a property on the class, the string is properly escaped when it's set. I just quickly pasted the value for reference on what I'm attempting to access.Folkway
@Middas, have you tried using CreateSubKey rather than OpenSubKey? It opens it for writing if it exists, and creates it otherwise.Mabuse
@Middas, can you try breaking on the SetValue line, and verify the exact value of key.Name and the exact value of Key at that line?Mabuse
That's a good suggestion, it could save me doing a separate step in creating it. Unfortunately, it gives me the same error.Folkway
key.Name "HKEY_USERS\\S-1-5-21-1644491937-1078145449-682003330-5490\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System" Key "DisableTaskMgr"Folkway
@Phago Good call! If I change the path to "S-1-5-21-1644491937-1078145449-682003330-5490\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer" and modify a key there, it works fine. I checked the permissions on the System registry key, the user in question has read and write permissions. Any reason why it would not be allowing it?Folkway
at this point I would check the access rights to the key. I know you stated you can edit the key with regedit but what is being returned when you access it through code. using System.Security.AccessControl; RegistryKey key= Microsoft.Win32.Registry.Users.OpenSubKey(Path, RegistryKeyPermissionCheck.ReadWriteSubTree); RegistrySecurity regSec = key.GetAccessControl(); then just check to see what the access is.....Phago
I did as you suggessted, here are the rights returned for the user: RegistryRights = QueryValues | SetValue | CreateSubKey | EnumerateSubKeys | Notify | CreateLink | Delete | ReadPermissions | ChangePermissions | TakeOwnershipFolkway
Have you tried this on another computer with that key? if this is only going to be run on this one computer, maybe recreating they key will resolve the security issue. Not sure as everything looks correct.Phago
If it works on a machine other than mine, I still would want to figure out why it doesn't work on mine. I need to have full trust in my code, not just cross my fingers and hope that any computer this will run on may or may not work as expected... Thank you for your suggestions, I think they have started me down the right path. I'll keep researching and post an answer when I've figured it out.Folkway
F
3

As a last ditch effort to figure out what was going on, I created a simple service to test this code that will run as the local system account. It's the highest privileges I could think of to try and run the code with. Running the code with these permissions worked.

Special thanks go out to 0_____0 and Charleh for pointing out the anti-virus as well. I checked the logs and it turns out it was trying to quarantine my changes. I guess even it won't stop the System user from making these changes though.

Special thanks go out to Sorceri as well for helping me research this so much.

In conclusion, if you're having intermittent, extremely odd behavior, check your virus scanner and permissions.

Folkway answered 2/8, 2012 at 16:24 Comment(0)
H
1

I ran into the same problem recently. So I tried a few things and instead of calling key.SetValue(Key, NewValue) simply calling create function solved my problem. That is;

Microsoft.Win32.RegistryKey key1 = Microsoft.Win32.Registry.Users.CreateSubKey(Path);
key1.SetValue(Key, NewValue);

CreateSubKey call doesn't delete the current entry but provided with the ability to write without exception. I hope that helps.

Humankind answered 12/11, 2019 at 17:4 Comment(0)
C
-2

Only set grants to dword. You must to open Registry and at the last folder path, rigth click over it and set Grants, and select All Aplications and check Total Control. I hope to help you.

Candiot answered 10/3, 2016 at 17:7 Comment(0)
H
-2

just Registry.SetValue(sub_key, key, value);

Example:

Registry.SetValue(
            @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
            "MyApp",
            Application.ExecutablePath);
Holeandcorner answered 6/10, 2017 at 3:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.