c#注册表对象映射

Posted mokeyish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#注册表对象映射相关的知识,希望对你有一定的参考价值。

用于快捷保存与读取注册表,为对应的对象

示例

        [RegistryRoot(Name = "superAcxxxxx")]
        public class Abc : IRegistry
        {
            public string Name { get; set; }

            public int Age { get; set; }
        }

保存

            Abc a = new Abc
            {
                Name = "mokeyish",
                Age = 100
            };
            RegistryKey register = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem
                ? RegistryView.Registry64
                : RegistryView.Registry32);

            RegistryKey writeKey=register.CreateSubKey("SOFTWARE");
            if (writeKey != null)
            {
                a.Save(writeKey);
                writeKey.Dispose();
            }
            register.Dispose();

 

读取

            Abc a=new Abc();
            RegistryKey register = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem
                ? RegistryView.Registry64
                : RegistryView.Registry32);

            RegistryKey writeKey=register.OpenSubKey("SOFTWARE");
            if (writeKey != null)
            {
                a.Read(writeKey);

                writeKey.Dispose();
            }
            register.Dispose();

 

 

技术分享
  1 #region summary
  2 //   ------------------------------------------------------------------------------------------------
  3 //   <copyright file="IRegistry.cs" company="personal">
  4 //     用户:mokeyish
  5 //     日期:2016/10/15
  6 //     时间:13:26
  7 //   </copyright>
  8 //   ------------------------------------------------------------------------------------------------
  9 #endregion
 10 
 11 namespace RegistryHelp 
 12 {
 13     using System;
 14     using System.Collections.Generic;
 15     using System.Linq;
 16     using System.Reflection;
 17     using Microsoft.Win32;
 18 
 19     /// <summary>
 20     /// 可用于注册表快捷保存读取的接口
 21     /// </summary>
 22     public interface IRegistry { }
 23 
 24     /// <summary>
 25     /// RegistryExitensionMethods
 26     /// </summary>
 27     public static class RegistryExitensionMethods
 28     {
 29         private static readonly Type IgnoreAttribute = typeof(RegistryIgnoreAttribute);
 30         private static readonly Type MemberAttribute = typeof(RegistryMemberAttribute);
 31         private static readonly Type RegistryInterface = typeof(IRegistry);
 32 
 33         /// <summary>
 34         /// 读取注册表
 35         /// </summary>
 36         /// <param name="rootKey"></param>
 37         /// <param name="registry"></param>
 38         /// <param name="name"></param>
 39         /// <exception cref="ArgumentNullException">registry is null</exception>
 40         /// <exception cref="Exception">Member type is same with Class type.</exception>
 41         public static bool Read(this RegistryKey rootKey, IRegistry registry, string name = null)
 42         {
 43             if (registry == null) throw new ArgumentNullException(nameof(registry));
 44 
 45             rootKey = rootKey.OpenSubKey(name ?? registry.GetRegistryRootName());
 46 
 47             if (rootKey == null) return false;
 48             
 49             using (rootKey)
 50             {
 51                 Tuple<PropertyInfo[], FieldInfo[]> members = registry.GetMembers();
 52 
 53                 if (members.Item1.Length + members.Item2.Length == 0) return false;
 54 
 55                 foreach (PropertyInfo property in members.Item1)
 56                 {
 57                     string registryName = property.GetRegistryName();
 58                     object value;
 59                     if (RegistryInterface.IsAssignableFrom(property.PropertyType))
 60                     {
 61                         if (property.PropertyType == registry.GetType())
 62                         {
 63                             throw new Exception("Member type is same with Class type.");
 64                         }
 65 
 66                         object oldvalue = property.GetValue(registry, null);
 67                         value = oldvalue ?? Activator.CreateInstance(property.PropertyType);
 68                         if (!rootKey.Read((IRegistry) value, registryName)) value = null;
 69                     }
 70                     else
 71                     {
 72                         value = rootKey.GetValue(registryName);
 73                     }
 74 
 75                     if (value != null) property.SetValue(registry, ChangeType(value, property.PropertyType), null);
 76                 }
 77 
 78                 foreach (FieldInfo fieldInfo in members.Item2)
 79                 {
 80                     string registryName = fieldInfo.GetRegistryName();
 81                     object value;
 82                     if (RegistryInterface.IsAssignableFrom(fieldInfo.FieldType))
 83                     {
 84                         if (fieldInfo.FieldType == registry.GetType())
 85                         {
 86                             throw new Exception("Member type is same with Class type.");
 87                         }
 88 
 89                         value = fieldInfo.GetValue(registry) ?? Activator.CreateInstance(fieldInfo.FieldType);
 90                         rootKey.Read((IRegistry) value, registryName);
 91                     }
 92                     else
 93                     {
 94                         value = rootKey.GetValue(registryName);
 95                     }
 96 
 97                     if (value != null) fieldInfo.SetValue(registry, ChangeType(value, fieldInfo.FieldType));
 98                 }
 99             }
100 
101             return true;
102         }
103 
104         /// <summary>
105         /// 保存到注册表
106         /// </summary>
107         /// <param name="rootKey"></param>
108         /// <param name="registry"></param>
109         /// <param name="name"></param>
110         /// <exception cref="ArgumentNullException">registry is null</exception>
111         /// <exception cref="Exception">Member type is same with Class type.</exception>
112         public static bool Save(this RegistryKey rootKey, IRegistry registry, string name = null)
113         {
114             if (registry == null) throw new ArgumentNullException(nameof(registry));
115 
116             rootKey = rootKey.CreateSubKey(name ?? registry.GetRegistryRootName());
117 
118             if (rootKey == null) return false;
119 
120             using (rootKey)
121             {
122                 Tuple<PropertyInfo[], FieldInfo[]> members = registry.GetMembers();
123 
124                 if (members.Item1.Length + members.Item2.Length == 0) return false;
125 
126                 foreach (PropertyInfo property in members.Item1)
127                 {
128                     string registryName = property.GetRegistryName();
129                     object value = property.GetValue(registry, null);
130                     if (RegistryInterface.IsAssignableFrom(property.PropertyType))
131                     {
132                         if (property.PropertyType == registry.GetType())
133                         {
134                             throw new Exception("Member type is same with Class type.");
135                         }
136 
137                         if (value != null) rootKey.Save((IRegistry) value, registryName);
138                     }
139                     else
140                     {
141                         value = ChangeType(value, TypeCode.String);
142                         if (value != null) rootKey.SetValue(registryName, value, RegistryValueKind.String);
143                     }
144 
145                 }
146 
147                 foreach (FieldInfo fieldInfo in members.Item2)
148                 {
149                     string registryName = fieldInfo.GetRegistryName();
150                     object value = fieldInfo.GetValue(registry);
151                     if (RegistryInterface.IsAssignableFrom(fieldInfo.FieldType))
152                     {
153                         if (fieldInfo.FieldType == registry.GetType())
154                         {
155                             throw new Exception("Member type is same with Class type.");
156                         }
157 
158                         if (value != null) rootKey.Save((IRegistry)value, registryName);
159                     }
160                     else
161                     {
162                         value = ChangeType(value, TypeCode.String);
163                         if (value != null) rootKey.SetValue(registryName, value, RegistryValueKind.String);
164                     }
165                 }
166             }
167             return true;
168         }
169 
170         /// <summary>
171         /// 读取注册表
172         /// </summary>
173         /// <param name="registry"></param>
174         /// <param name="rootKey"></param>
175         /// <param name="name"></param>
176         /// <exception cref="ArgumentNullException">registry is null</exception>
177         /// <exception cref="Exception">Member type is same with Class type.</exception>
178         public static bool Read(this IRegistry registry, RegistryKey rootKey, string name = null)
179         {
180             return rootKey.Read(registry, name);
181         }
182 
183         /// <summary>
184         /// 保存到注册表
185         /// </summary>
186         /// <param name="registry"></param>
187         /// <param name="rootKey"></param>
188         /// <param name="name"></param>
189         /// <exception cref="ArgumentNullException">registry is null</exception>
190         /// <exception cref="Exception">Member type is same with Class type.</exception>
191         public static bool Save(this IRegistry registry, RegistryKey rootKey, string name = null)
192         {
193             return rootKey.Save(registry, name);
194         }
195 
196         private static object ChangeType(object value, Type conversionType)
197         {
198             if (conversionType == RegistryInterface)
199             {
200                 return value;
201             }
202 
203             if (conversionType == typeof(Guid))
204             {
205                 return new Guid((string)value);
206             }
207             
208             return Convert.ChangeType(value, conversionType);
209         }
210 
211         private static object ChangeType(object value, TypeCode typeCode)
212         {
213             if (value is IConvertible) return Convert.ChangeType(value, typeCode);
214             return value.ToString();
215         }
216 
217         private static bool IsDefinedRegistryAttribute(this MemberInfo memberInfo)
218         {
219             return memberInfo.IsDefined(IgnoreAttribute, false) || memberInfo.IsDefined(MemberAttribute, false);
220         }
221 
222         private static string GetRegistryRootName(this IRegistry registry)
223         {
224             Type rootType = registry.GetType();
225             return rootType.IsDefined(typeof(RegistryRootAttribute), false)
226                 ? rootType.GetCustomAttribute<RegistryRootAttribute>().Name
227                 : rootType.Name;
228         }
229 
230         private static string GetRegistryName(this MemberInfo memberInfo)
231         {
232             return memberInfo.IsDefined(MemberAttribute, false)
233                 ? memberInfo.GetCustomAttribute<RegistryMemberAttribute>().Name
234                 : memberInfo.Name;
235         }
236 
237         private static Tuple<PropertyInfo[], FieldInfo[]> GetMembers(this IRegistry registry)
238         {
239             if (registry == null) throw new ArgumentNullException(nameof(registry));
240             Type t = registry.GetType();
241 
242             IList<MemberInfo> lst =
243                 t.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static |
244                              BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField |
245                              BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty).ToList();
246 
247 
248             bool isDefinedAttribute = lst.Any(i => i.IsDefinedRegistryAttribute());
249 
250             return isDefinedAttribute
251                 ? new Tuple<PropertyInfo[], FieldInfo[]>(lst.OfType<PropertyInfo>().ToArray(),
252                     lst.OfType<FieldInfo>().ToArray())
253                 : new Tuple<PropertyInfo[], FieldInfo[]>(t.GetProperties(), t.GetFields());
254         }
255     }
256     
257     /// <summary>
258     /// RegistryRootAttribute:用于描述注册表对象类
259     /// </summary>
260     [AttributeUsage(AttributeTargets.Class)]
261     public class RegistryRootAttribute : Attribute
262     {
263         /// <summary>
264         /// Name
265         /// </summary>
266         public string Name { get; set; }
267 
268         /// <summary>
269         /// Value
270         /// </summary>
271         public string Value { get; set; }
272     }
273     
274     /// <summary>
275     /// RegistryIgnoreAttribute:忽略注册表成员,使用了该特性,将忽略未定义RegistryMemberAttribute的成员
276     /// </summary>
277     [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
278     public class RegistryIgnoreAttribute : Attribute { }
279 
280     /// <summary>
281     /// RegistryMemberAttribute:用于描述注册表成员,使用了该特性,将忽略未定义RegistryMemberAttribute的成员
282     /// </summary>
283     [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
284     public class RegistryMemberAttribute : Attribute
285     {
286         /// <summary>
287         /// Name
288         /// </summary>
289         public string Name { get; set; }
290     }
291 }
注册表对象映射

 

以上是关于c#注册表对象映射的主要内容,如果未能解决你的问题,请参考以下文章

如何将 XML 映射到 C# 对象

将mysql查询中项目的嵌套列表属性映射到c#对象

使用映射库将嵌套对象映射到 C# 中的自定义对象

C# 最有用的(自定义)代码片段是啥? [关闭]

c#代码片段快速构建代码

此 Canon SDK C++ 代码片段的等效 C# 代码是啥?