C# UnauthorizedAccessException on RegistryKey CreateSubKey

4.3k Views Asked by At

I get an UnauthorizedAccessException any time I try to call CreateSubKey in my code.

const string regKeyPath = @"Software\Apps\jp2code.net\FTMaint";

private void BuildRegistry() {
  string[] split = regKeyPath.Split('\\');
  keyMaker(Registry.LocalMachine, split, 0);
}

private static void keyMaker(RegistryKey key, string[] path, int index) {
  string keyValue = path[index++];
  RegistryKey key2;
  if (!String.IsNullOrEmpty(keyValue)) {
    string subKey = null;
    string[] subKeyNames = key.GetSubKeyNames();
    foreach (var item in subKeyNames) {
      if (keyValue == item) {
        subKey = item;
      }
    }
    if (String.IsNullOrEmpty(subKey)) {
      key2 = key.CreateSubKey(keyValue);
    } else {
      key2 = key.OpenSubKey(subKey);
    }
    //key2 = key.OpenSubKey(keyValue, String.IsNullOrEmpty(subKey));
  } else {
    key2 = key;
  }
  if (index < path.Length) {
    try {
      keyMaker(key2, path, index + 1);
    } finally {
      key2.Close();
    }
  }
}

I found a post where someone was having a similar problem >> HERE << on MSDN Social, but the solution there (to use the overloaded OpenSubKey method) only returned a NULL RegistryKey for me.

This is for a Windows Mobile 5 device emulator.

Can anyone see what I'm doing wrong?

The error is thrown the first time the code reaches a key that does not exist and tries to create it.

Thanks!

screen shot

3

There are 3 best solutions below

2
ctacke On BEST ANSWER

All three of these work fine for me on the WinMo 6 Emulator.

Create a root key:

using (var swKey = Registry.LocalMachine.CreateSubKey("foo"))
{
    using (var subkey = swKey.CreateSubKey("OpenNETCF"))
    {
    }
}

Create a subkey via path

using (var swKey = Registry.LocalMachine.CreateSubKey("software\\foo"))
{
    using (var subkey = swKey.CreateSubKey("OpenNETCF"))
    {
    }
}

Create a subkey directly:

using (var swKey = Registry.LocalMachine.OpenSubKey("software", true))
{
    using (var subkey = swKey.CreateSubKey("OpenNETCF"))
    {
    }
}
1
Casperah On

To create a key in LocalMachine during installation do something like this:

[RunInstaller(true)]
public class InstallRegistry : Installer
{
    public override void Install(System.Collections.IDictionary stateSaver)
    {
        base.Install(stateSaver);

        using (RegistryKey key = Registry.LocalMachine.CreateSubKey(@"software\..."))
        {
            RegistrySecurity rs = new RegistrySecurity();
            rs.AddAccessRule(new RegistryAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), RegistryRights.FullControl, InheritanceFlags.None, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
            key.SetAccessControl(rs);
        }
    }
    public override void Rollback(System.Collections.IDictionary savedState)
    {
        base.Rollback(savedState);
    }
}

Hope this will help you.

1
Brian Cryer On

I found when creating a RegistryKey instance via Registry.CurrentUser.OpenSubKey that it was read-only. So I could call GetValue but when I came to try to call SetValue I got the UnauthorizedAccessException. The trick is to call Registry.CurrentUser.OpenSubKey setting the writable parameter to true, then calls to SetValue were successful.

So instead of:

key2 = key.OpenSubKey(subKey);

use:

key2 = key.OpenSubKey(subKey, writable: true);

the same probably applies to the call to CreateSubKey.

The original question was asked in the context of Windows Mobile. I've not used Windows Mobile (not sure anyone does these days), but I expect the writeable parameter will be there.