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 }
注冊表對象映射