简体   繁体   English

RegistryKey CreateSubKey 上的 C# UnauthorizedAccessException

[英]C# UnauthorizedAccessException on RegistryKey CreateSubKey

I get an UnauthorizedAccessException any time I try to call CreateSubKey in my code.每当我尝试在代码中调用CreateSubKey 时,都会收到UnauthorizedAccessException 异常

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.我在 MSDN Social 上找到了一个帖子,其中有人遇到了类似的问题>> HERE << ,但是那里的解决方案(使用重载的 OpenSubKey 方法)只为我返回了一个 NULL RegistryKey

This is for a Windows Mobile 5 device emulator.这是用于 Windows Mobile 5 设备模拟器。

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!谢谢!

截屏

All three of these work fine for me on the WinMo 6 Emulator.所有这三个在 WinMo 6 模拟器上对我来说都很好。

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"))
    {
    }
}

I found when creating a RegistryKey instance via Registry.CurrentUser.OpenSubKey that it was read-only.我在通过Registry.CurrentUser.OpenSubKey创建RegistryKey实例时发现它是只读的。 So I could call GetValue but when I came to try to call SetValue I got the UnauthorizedAccessException .所以我可以调用GetValue但是当我尝试调用SetValue我得到了UnauthorizedAccessException The trick is to call Registry.CurrentUser.OpenSubKey setting the writable parameter to true, then calls to SetValue were successful.诀窍是调用Registry.CurrentUser.OpenSubKey将可写参数设置为 true,然后调用SetValue成功。

So instead of:所以而不是:

key2 = key.OpenSubKey(subKey);

use:采用:

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

the same probably applies to the call to CreateSubKey .这可能同样适用于对CreateSubKey的调用。

The original question was asked in the context of Windows Mobile.最初的问题是在 Windows Mobile 的上下文中提出的。 I've not used Windows Mobile (not sure anyone does these days), but I expect the writeable parameter will be there.我没有使用过 Windows Mobile(现在不确定是否有人使用过),但我希望可写参数会在那里。

To create a key in LocalMachine during installation do something like this:要在安装期间在 LocalMachine 中创建密钥,请执行以下操作:

[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.希望这会帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM