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

Middas
  • 1,862
  • 1
  • 29
  • 44
  • 1
    Please confirm that you can modify the key in question running regular regedit. – Alexei Levenkov Aug 01 '12 at 22:00
  • 1
    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. – Middas Aug 01 '12 at 22:10
  • You may also want to test under this with different user account or on another machine. – Chris Walter Aug 01 '12 at 22:12
  • 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. – Middas Aug 01 '12 at 22:15
  • 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... – Eric Aug 01 '12 at 22:21
  • 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. – Middas Aug 01 '12 at 22:24
  • Also, what version of .NET are you using? My test was on .NET 4. – Eric Aug 01 '12 at 22:35
  • Could you please post the full exception details (including call stack), as returned by its ToString() method? – Nicole Calinoiu Aug 01 '12 at 23:24
  • `"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"` – Middas Aug 01 '12 at 23:28

7 Answers7

18

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);  
Sorceri
  • 466
  • 2
  • 4
  • I actually did try that as well, it gave me the same error, so I reverted my code. Thanks for the suggestion though. – Middas Aug 01 '12 at 22:22
  • The exception is thrown at SetValue. – Middas Aug 01 '12 at 22:53
  • Have you tried that code on another key? Also why the use of an implicit variable with var, why not use RegistryKey – Sorceri Aug 01 '12 at 23:17
  • 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: [link](http://stackoverflow.com/questions/11768172/c-sharp-registry-setvalue-throws-unauthorizedaccessexception/11768284#comment15628852_11768284) – Middas Aug 01 '12 at 23:35
  • This one worked for me. I have a machine with UAC disabled, without setting ReadWriteSubTree it would always raise access denied exception – daisy Nov 08 '19 at 02:17
4

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);
MiMFa
  • 981
  • 11
  • 14
0_______0
  • 547
  • 3
  • 11
  • 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. – Middas Aug 01 '12 at 22:40
  • Ah, you're correct, I've edited my answer, but I don't know if it will do anything. – 0_______0 Aug 01 '12 at 22:52
  • 3
    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. – 0_______0 Aug 01 '12 at 23:17
  • 2
    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..! – Charleh Aug 02 '12 at 16:27
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";
Eric
  • 5,842
  • 7
  • 42
  • 71
  • 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. – Middas Aug 01 '12 at 22:08
  • 1
    @Middas, have you tried using `CreateSubKey` rather than `OpenSubKey`? It opens it for writing if it exists, and creates it otherwise. – Eric Aug 01 '12 at 22:27
  • @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? – Eric Aug 01 '12 at 22:30
  • That's a good suggestion, it could save me doing a separate step in creating it. Unfortunately, it gives me the same error. – Middas Aug 01 '12 at 22:33
  • key.Name "HKEY_USERS\\S-1-5-21-1644491937-1078145449-682003330-5490\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System" Key "DisableTaskMgr" – Middas Aug 01 '12 at 22:36
  • @Sorceri **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? – Middas Aug 01 '12 at 23:25
  • 1
    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..... – Sorceri Aug 01 '12 at 23:40
  • I did as you suggessted, here are the rights returned for the user: `RegistryRights = QueryValues | SetValue | CreateSubKey | EnumerateSubKeys | Notify | CreateLink | Delete | ReadPermissions | ChangePermissions | TakeOwnership` – Middas Aug 01 '12 at 23:56
  • 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. – Sorceri Aug 02 '12 at 15:28
  • 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. – Middas Aug 02 '12 at 16:04
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.

Middas
  • 1,862
  • 1
  • 29
  • 44
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.

fatih
  • 183
  • 1
  • 9
-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.

-2

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

Example:

Registry.SetValue(
            @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
            "MyApp",
            Application.ExecutablePath);
Grigory
  • 119
  • 1
  • 10