代码之家  ›  专栏  ›  技术社区  ›  Simon Randy Burden

在.NET中是否有一种更容易创建注册表易失性子项的方法?

  •  3
  • Simon Randy Burden  · 技术社区  · 16 年前

    到目前为止,我有下面这张照片

    http://www.danielmoth.com/Blog/volatile-registrykey.aspx

    public static class RegistryHelper
    {
        public static RegistryKey CreateVolatileSubKey(RegistryKey rk, string subkey, RegistryKeyPermissionCheck permissionCheck)
        {
            var rk2 = rk.GetType();
            const BindingFlags bfStatic = BindingFlags.NonPublic | BindingFlags.Static;
            const BindingFlags bfInstance = BindingFlags.NonPublic | BindingFlags.Instance;
            rk2.GetMethod("ValidateKeyName", bfStatic).Invoke(null, new object[] { subkey });
            rk2.GetMethod("ValidateKeyMode", bfStatic).Invoke(null, new object[] { permissionCheck });
            rk2.GetMethod("EnsureWriteable", bfInstance).Invoke(rk, null);
    
            subkey = (string)rk2.GetMethod("FixupName", bfStatic).Invoke(null, new object[] { subkey });
            if (!(bool)rk2.GetField("remoteKey", bfInstance).GetValue(rk))
            {
                var key = (RegistryKey)rk2.GetMethod("InternalOpenSubKey", bfInstance, null, new[] { typeof(string), typeof(bool) }, null).Invoke(rk, new object[] { subkey, permissionCheck != RegistryKeyPermissionCheck.ReadSubTree });
                if (key != null)
                {
                    rk2.GetMethod("CheckSubKeyWritePermission", bfInstance).Invoke(rk, new object[] { subkey });
                    rk2.GetMethod("CheckSubTreePermission", bfInstance).Invoke(rk, new object[] { subkey, permissionCheck });
                    rk2.GetField("checkMode", bfInstance).SetValue(key, permissionCheck);
                    return key;
                }
            }
            rk2.GetMethod("CheckSubKeyCreatePermission", bfInstance).Invoke(rk, new object[] { subkey });
    
            int lpdwDisposition;
            IntPtr hkResult;
    
            var srh = Type.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");
            var temp = rk2.GetField("hkey", bfInstance).GetValue(rk);
            var rkhkey = (SafeHandleZeroOrMinusOneIsInvalid)temp;
    
            var getregistrykeyaccess = (int)rk2.GetMethod("GetRegistryKeyAccess", bfStatic, null, new[] { typeof(bool) }, null).Invoke(null, new object[] { permissionCheck != RegistryKeyPermissionCheck.ReadSubTree });
            var errorCode = RegCreateKeyEx(rkhkey, subkey, 0, null, 1, getregistrykeyaccess, IntPtr.Zero, out hkResult, out lpdwDisposition);
            var keyNameField = rk2.GetField("keyName", bfInstance);
            var rkkeyName = (string)keyNameField.GetValue(rk);
    
            if (errorCode == 0 && hkResult.ToInt32() > 0)
            {
                var rkremoteKey = (bool)rk2.GetField("remoteKey", bfInstance).GetValue(rk);
                var hkResult2 = srh.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(IntPtr), typeof(bool) }, null).Invoke(new object[] { hkResult, true });
                var key2 = (RegistryKey)rk2.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { hkResult2.GetType(), typeof(bool), typeof(bool), typeof(bool), typeof(bool) }, null).Invoke(new[] { hkResult2, permissionCheck != RegistryKeyPermissionCheck.ReadSubTree, false, rkremoteKey, false });
                rk2.GetMethod("CheckSubTreePermission", bfInstance).Invoke(rk, new object[] { subkey, permissionCheck });
                rk2.GetField("checkMode", bfInstance).SetValue(key2, permissionCheck);
                if (subkey.Length == 0)
                {
                    keyNameField.SetValue(key2, rkkeyName);
                }
                else
                {
                    keyNameField.SetValue(key2, rkkeyName + @"\" + subkey);
                }
                key2.Close();
                return rk.OpenSubKey(subkey, true);
            }
            if (errorCode != 0)
                rk2.GetMethod("Win32Error", bfInstance).Invoke(rk, new object[] { errorCode, rkkeyName + @"\" + subkey });
            return null;
        }
    
        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        private static extern int RegCreateKeyEx(SafeHandleZeroOrMinusOneIsInvalid hKey, string lpSubKey, int reserved, string lpClass, int dwOptions, int samDesigner, IntPtr lpSecurityAttributes, out IntPtr hkResult, out int lpdwDisposition);
    }
    

    它起作用,但相当难看。有更好的方法吗?

    1 回复  |  直到 16 年前
        1
  •  3
  •   Matt Ellis    16 年前

    如果使用.NET 4,则可以利用 RegistryOptions 枚举以使用普通.NET API创建易失性密钥。