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="ApplicationInfo.cs" company="bda"> 4 // 用户:mokeyish 5 // 日期:2016/10/20 6 // 时间:16:52 7 // </copyright> 8 // ------------------------------------------------------------------------------------------------ 9 #endregion 10 11 using System; 12 using Microsoft.Win32; 13 14 namespace RegistryHelp 15 { 16 /// <summary> 17 /// 应用程序信息 18 /// </summary> 19 [RegistryRoot(Name = "RegistryHelp")] 20 public class ApplicationInfo:IRegistry 21 { 22 [RegistryMember(Name = "Path")] 23 private string _path; 24 25 [RegistryMember(Name = "Server")] 26 private readonly string _server; 27 28 [RegistryMember(Name = "Descirption")] 29 private string _descirption; 30 31 private bool _isChanged; 32 33 /// <summary> 34 /// 获取应用程序信息单例 35 /// </summary> 36 public static readonly ApplicationInfo Instance = new ApplicationInfo(); 37 38 private ApplicationInfo() 39 { 40 this._path = AppDomain.CurrentDomain.BaseDirectory; 41 this._server = string.Empty; 42 AppDomain.CurrentDomain.ProcessExit += this.CurrentDomain_ProcessExit; 43 this._descirption = "注册表描述"; 44 this._isChanged = !this.Read(); 45 this._isChanged = !this.Save(); 46 } 47 48 private void CurrentDomain_ProcessExit(object sender, EventArgs e) 49 { 50 this.Save(); 51 } 52 53 /// <summary> 54 /// 应用程序目录 55 /// </summary> 56 public string Path 57 { 58 get { return this._path; } 59 set 60 { 61 if (this._path==value)return; 62 this._isChanged = true; 63 this._path = value; 64 } 65 } 66 67 68 /// <summary> 69 /// 服务器地址 70 /// </summary> 71 public string Server => this._server; 72 73 /// <summary> 74 /// 描述 75 /// </summary> 76 public string Descirption 77 { 78 get { return this._descirption; } 79 set 80 { 81 if (this._descirption == value) return; 82 this._isChanged = true; 83 this._descirption = value; 84 } 85 } 86 87 private bool Read() 88 { 89 RegistryKey registry = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem 90 ? RegistryView.Registry64 91 : RegistryView.Registry32); 92 using (registry) 93 { 94 RegistryKey baseKey = registry.OpenSubKey("SOFTWARE"); 95 using (baseKey) return this.Read(baseKey); 96 } 97 } 98 99 private bool Save() 100 { 101 if (!this._isChanged) return false; 102 RegistryKey registry = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem 103 ? RegistryView.Registry64 104 : RegistryView.Registry32); 105 using (registry) 106 { 107 RegistryKey baseKey = registry.CreateSubKey("SOFTWARE"); 108 using (baseKey) return this.Save(baseKey); 109 } 110 } 111 } 112 }
1 #region summary 2 3 // ------------------------------------------------------------------------------------------------ 4 // <copyright file="IRegistry.cs" company="bda"> 5 // 用户:mokeyish 6 // 日期:2016/10/15 7 // 时间:13:26 8 // </copyright> 9 // ------------------------------------------------------------------------------------------------ 10 11 #endregion 12 13 using System; 14 using System.Collections.Generic; 15 using System.Linq; 16 using System.Reflection; 17 using Microsoft.Win32; 18 19 namespace RegistryHelp 20 { 21 /// <summary> 22 /// 可用于注册表快捷保存读取的接口 23 /// </summary> 24 public interface IRegistry 25 { 26 } 27 28 /// <summary> 29 /// RegistryExitensionMethods 30 /// </summary> 31 public static class RegistryExitensionMethods 32 { 33 private static readonly Type IgnoreAttribute = typeof(RegistryIgnoreAttribute); 34 private static readonly Type MemberAttribute = typeof(RegistryMemberAttribute); 35 private static readonly Type RegistryInterface = typeof(IRegistry); 36 37 /// <summary> 38 /// 读取注册表 39 /// </summary> 40 /// <param name="rootKey"></param> 41 /// <param name="registry"></param> 42 /// <param name="name"></param> 43 /// <exception cref="ArgumentNullException">registry is null</exception> 44 /// <exception cref="Exception">Member type is same with class type.</exception> 45 public static bool Read(this RegistryKey rootKey, IRegistry registry, string name = null) 46 { 47 if (registry == null) throw new ArgumentNullException(nameof(registry)); 48 49 rootKey = rootKey?.OpenSubKey(name ?? registry.GetRegistryRootName()); 50 51 if (rootKey == null) return false; 52 53 bool flag = true; 54 using (rootKey) 55 { 56 Tuple<PropertyInfo[], FieldInfo[]> members = registry.GetMembers(); 57 58 if (members.Item1.Length + members.Item2.Length == 0) return false; 59 60 foreach (PropertyInfo property in members.Item1) 61 { 62 string registryName = property.GetRegistryName(); 63 object value; 64 if (RegistryInterface.IsAssignableFrom(property.PropertyType)) 65 { 66 if (property.PropertyType == registry.GetType()) 67 { 68 throw new Exception("Member type is same with Class type."); 69 } 70 71 object oldvalue = property.GetValue(registry, null); 72 value = oldvalue ?? Activator.CreateInstance(property.PropertyType); 73 if (!rootKey.Read((IRegistry) value, registryName)) value = null; 74 } 75 else 76 { 77 value = rootKey.GetValue(registryName); 78 } 79 80 if (value != null) 81 { 82 property.SetValue(registry, ChangeType(value, property.PropertyType), null); 83 } 84 else 85 { 86 flag = false; 87 } 88 } 89 90 foreach (FieldInfo fieldInfo in members.Item2) 91 { 92 string registryName = fieldInfo.GetRegistryName(); 93 object value; 94 if (RegistryInterface.IsAssignableFrom(fieldInfo.FieldType)) 95 { 96 if (fieldInfo.FieldType == registry.GetType()) 97 { 98 throw new Exception("Member type is same with Class type."); 99 } 100 101 value = fieldInfo.GetValue(registry) ?? Activator.CreateInstance(fieldInfo.FieldType); 102 rootKey.Read((IRegistry) value, registryName); 103 } 104 else 105 { 106 value = rootKey.GetValue(registryName); 107 } 108 109 if (value != null) 110 { 111 fieldInfo.SetValue(registry, ChangeType(value, fieldInfo.FieldType)); 112 } 113 else 114 { 115 flag = false; 116 } 117 } 118 } 119 return flag; 120 } 121 122 /// <summary> 123 /// 保存到注册表 124 /// </summary> 125 /// <param name="rootKey"></param> 126 /// <param name="registry"></param> 127 /// <param name="name"></param> 128 /// <exception cref="ArgumentNullException">registry is null</exception> 129 /// <exception cref="Exception">Member type is same with Class type.</exception> 130 public static bool Save(this RegistryKey rootKey, IRegistry registry, string name = null) 131 { 132 if (registry == null) throw new ArgumentNullException(nameof(registry)); 133 134 rootKey = rootKey?.CreateSubKey(name ?? registry.GetRegistryRootName()); 135 136 if (rootKey == null) return false; 137 138 using (rootKey) 139 { 140 Tuple<PropertyInfo[], FieldInfo[]> members = registry.GetMembers(); 141 142 if (members.Item1.Length + members.Item2.Length == 0) return false; 143 144 foreach (PropertyInfo property in members.Item1) 145 { 146 string registryName = property.GetRegistryName(); 147 object value = property.GetValue(registry, null); 148 if (RegistryInterface.IsAssignableFrom(property.PropertyType)) 149 { 150 if (property.PropertyType == registry.GetType()) 151 { 152 throw new Exception("Member type is same with Class type."); 153 } 154 155 if (value != null) rootKey.Save((IRegistry) value, registryName); 156 } 157 else 158 { 159 value = ChangeType(value, TypeCode.String); 160 if (value != null) rootKey.SetValue(registryName, value, RegistryValueKind.String); 161 } 162 163 } 164 165 foreach (FieldInfo fieldInfo in members.Item2) 166 { 167 string registryName = fieldInfo.GetRegistryName(); 168 object value = fieldInfo.GetValue(registry); 169 if (RegistryInterface.IsAssignableFrom(fieldInfo.FieldType)) 170 { 171 if (fieldInfo.FieldType == registry.GetType()) 172 { 173 throw new Exception("Member type is same with Class type."); 174 } 175 176 if (value != null) rootKey.Save((IRegistry) value, registryName); 177 } 178 else 179 { 180 value = ChangeType(value, TypeCode.String); 181 if (value != null) rootKey.SetValue(registryName, value, RegistryValueKind.String); 182 } 183 } 184 } 185 return true; 186 } 187 188 /// <summary> 189 /// 读取注册表 190 /// </summary> 191 /// <param name="registry"></param> 192 /// <param name="rootKey"></param> 193 /// <param name="name"></param> 194 /// <exception cref="ArgumentNullException">registry is null</exception> 195 /// <exception cref="Exception">Member type is same with class type.</exception> 196 public static bool Read(this IRegistry registry, RegistryKey rootKey, string name = null) 197 { 198 return rootKey.Read(registry, name); 199 } 200 201 /// <summary> 202 /// 保存到注册表 203 /// </summary> 204 /// <param name="registry"></param> 205 /// <param name="rootKey"></param> 206 /// <param name="name"></param> 207 /// <exception cref="ArgumentNullException">registry is null</exception> 208 /// <exception cref="Exception">Member type is same with class type.</exception> 209 public static bool Save(this IRegistry registry, RegistryKey rootKey, string name = null) 210 { 211 return rootKey.Save(registry, name); 212 } 213 214 private static object ChangeType(object value, Type conversionType) 215 { 216 try 217 { 218 if (conversionType == RegistryInterface) 219 { 220 return value; 221 } 222 223 if (conversionType == typeof(Guid)) 224 { 225 return new Guid((string) value); 226 } 227 228 if (conversionType.IsEnum) 229 { 230 return Enum.Parse(conversionType, (string) value); 231 } 232 233 return Convert.ChangeType(value, conversionType); 234 235 } 236 catch (Exception) 237 { 238 return null; 239 } 240 } 241 242 private static object ChangeType(object value, TypeCode typeCode) 243 { 244 try 245 { 246 247 if (value is IConvertible) return Convert.ChangeType(value, typeCode); 248 return value.ToString(); 249 } 250 catch (Exception) 251 { 252 return null; 253 } 254 } 255 256 private static bool IsDefinedRegistryAttribute(this MemberInfo memberInfo) 257 { 258 return memberInfo.IsDefined(IgnoreAttribute, false) || memberInfo.IsDefined(MemberAttribute, false); 259 } 260 261 private static string GetRegistryRootName(this IRegistry registry) 262 { 263 Type rootType = registry.GetType(); 264 return rootType.IsDefined(typeof(RegistryRootAttribute), false) 265 ? rootType.GetCustomAttribute<RegistryRootAttribute>().Name 266 : rootType.Name; 267 } 268 269 private static string GetRegistryName(this MemberInfo memberInfo) 270 { 271 return memberInfo.IsDefined(MemberAttribute, false) 272 ? memberInfo.GetCustomAttribute<RegistryMemberAttribute>().Name 273 : memberInfo.Name; 274 } 275 276 private static Tuple<PropertyInfo[], FieldInfo[]> GetMembers(this IRegistry registry) 277 { 278 if (registry == null) throw new ArgumentNullException(nameof(registry)); 279 Type t = registry.GetType(); 280 281 IList<MemberInfo> lst = 282 t.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | 283 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | 284 BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty).ToList(); 285 286 287 bool isDefinedAttribute = lst.Any(i => i.IsDefinedRegistryAttribute()); 288 if (isDefinedAttribute) 289 { 290 lst = lst.Where(i => i.IsDefinedRegistryAttribute()).ToList(); 291 } 292 return isDefinedAttribute 293 ? new Tuple<PropertyInfo[], FieldInfo[]>(lst.OfType<PropertyInfo>().ToArray(), 294 lst.OfType<FieldInfo>().ToArray()) 295 : new Tuple<PropertyInfo[], FieldInfo[]>(t.GetProperties(), t.GetFields()); 296 } 297 298 /// <summary> 299 /// The get custom attribute. 300 /// </summary> 301 /// <param name="element"> 302 /// The element. 303 /// </param> 304 /// <typeparam name="T">Attribute type 305 /// </typeparam> 306 /// <returns> 307 /// The custom attribute 308 /// </returns> 309 private static T GetCustomAttribute<T>(this MemberInfo element) where T : Attribute 310 { 311 return (T)Attribute.GetCustomAttribute(element, typeof(T)); 312 } 313 } 314 315 /// <summary> 316 /// RegistryRootAttribute:用于描述注册表对象类 317 /// </summary> 318 [AttributeUsage(AttributeTargets.Class)] 319 public class RegistryRootAttribute : Attribute 320 { 321 /// <summary> 322 /// Name 323 /// </summary> 324 public string Name { get; set; } 325 326 /// <summary> 327 /// Value 328 /// </summary> 329 public string Value { get; set; } 330 } 331 332 /// <summary> 333 /// RegistryIgnoreAttribute:忽略注册表成员,使用了该特性,将忽略未定义RegistryMemberAttribute的成员 334 /// </summary> 335 [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] 336 public class RegistryIgnoreAttribute : Attribute { } 337 338 /// <summary> 339 /// RegistryMemberAttribute:用于描述注册表成员,使用了该特性,将忽略未定义RegistryMemberAttribute的成员 340 /// </summary> 341 [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] 342 public class RegistryMemberAttribute : Attribute 343 { 344 /// <summary> 345 /// Name 346 /// </summary> 347 public string Name { get; set; } 348 } 349 }