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 =
};
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();
该类实现比较完善,首先使用单例模式,再加上应用程序域的退出保存策略。这样可以保存该类可以在程序退出的时候将值保存到注册表
#region summary
// ------------------------------------------------------------------------------------------------
// <copyright file="ApplicationInfo.cs" company="bda">
// 用户:mokeyish
// 日期:2016/10/20
// 时间:16:52
// </copyright>
// ------------------------------------------------------------------------------------------------
#endregion using System;
using Microsoft.Win32; namespace RegistryHelp
{
/// <summary>
/// 应用程序信息
/// </summary>
[RegistryRoot(Name = "RegistryHelp")]
public class ApplicationInfo:IRegistry
{
[RegistryMember(Name = "Path")]
private string _path; [RegistryMember(Name = "Server")]
private readonly string _server; [RegistryMember(Name = "Descirption")]
private string _descirption; private bool _isChanged; /// <summary>
/// 获取应用程序信息单例
/// </summary>
public static readonly ApplicationInfo Instance = new ApplicationInfo(); private ApplicationInfo()
{
this._path = AppDomain.CurrentDomain.BaseDirectory;
this._server = string.Empty;
AppDomain.CurrentDomain.ProcessExit += this.CurrentDomain_ProcessExit;
this._descirption = "注册表描述";
this._isChanged = !this.Read();
this._isChanged = !this.Save();
} private void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
this.Save();
} /// <summary>
/// 应用程序目录
/// </summary>
public string Path
{
get { return this._path; }
set
{
if (this._path==value)return;
this._isChanged = true;
this._path = value;
}
} /// <summary>
/// 服务器地址
/// </summary>
public string Server => this._server; /// <summary>
/// 描述
/// </summary>
public string Descirption
{
get { return this._descirption; }
set
{
if (this._descirption == value) return;
this._isChanged = true;
this._descirption = value;
}
} private bool Read()
{
RegistryKey registry = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem
? RegistryView.Registry64
: RegistryView.Registry32);
using (registry)
{
RegistryKey baseKey = registry.OpenSubKey("SOFTWARE");
using (baseKey) return this.Read(baseKey);
}
} private bool Save()
{
if (!this._isChanged) return false;
RegistryKey registry = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem
? RegistryView.Registry64
: RegistryView.Registry32);
using (registry)
{
RegistryKey baseKey = registry.CreateSubKey("SOFTWARE");
using (baseKey) return this.Save(baseKey);
}
}
}
}
已封装完善的对象类
#region summary // ------------------------------------------------------------------------------------------------
// <copyright file="IRegistry.cs" company="bda">
// 用户:mokeyish
// 日期:2016/10/15
// 时间:13:26
// </copyright>
// ------------------------------------------------------------------------------------------------ #endregion using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Win32; namespace RegistryHelp
{
/// <summary>
/// 可用于注册表快捷保存读取的接口
/// </summary>
public interface IRegistry
{
} /// <summary>
/// RegistryExitensionMethods
/// </summary>
public static class RegistryExitensionMethods
{
private static readonly Type IgnoreAttribute = typeof(RegistryIgnoreAttribute);
private static readonly Type MemberAttribute = typeof(RegistryMemberAttribute);
private static readonly Type RegistryInterface = typeof(IRegistry); /// <summary>
/// 读取注册表
/// </summary>
/// <param name="rootKey"></param>
/// <param name="registry"></param>
/// <param name="name"></param>
/// <exception cref="ArgumentNullException">registry is null</exception>
/// <exception cref="Exception">Member type is same with class type.</exception>
public static bool Read(this RegistryKey rootKey, IRegistry registry, string name = null)
{
if (registry == null) throw new ArgumentNullException(nameof(registry)); rootKey = rootKey?.OpenSubKey(name ?? registry.GetRegistryRootName()); if (rootKey == null) return false; bool flag = true;
using (rootKey)
{
Tuple<PropertyInfo[], FieldInfo[]> members = registry.GetMembers(); if (members.Item1.Length + members.Item2.Length == ) return false; foreach (PropertyInfo property in members.Item1)
{
string registryName = property.GetRegistryName();
object value;
if (RegistryInterface.IsAssignableFrom(property.PropertyType))
{
if (property.PropertyType == registry.GetType())
{
throw new Exception("Member type is same with Class type.");
} object oldvalue = property.GetValue(registry, null);
value = oldvalue ?? Activator.CreateInstance(property.PropertyType);
if (!rootKey.Read((IRegistry) value, registryName)) value = null;
}
else
{
value = rootKey.GetValue(registryName);
} if (value != null)
{
property.SetValue(registry, ChangeType(value, property.PropertyType), null);
}
else
{
flag = false;
}
} foreach (FieldInfo fieldInfo in members.Item2)
{
string registryName = fieldInfo.GetRegistryName();
object value;
if (RegistryInterface.IsAssignableFrom(fieldInfo.FieldType))
{
if (fieldInfo.FieldType == registry.GetType())
{
throw new Exception("Member type is same with Class type.");
} value = fieldInfo.GetValue(registry) ?? Activator.CreateInstance(fieldInfo.FieldType);
rootKey.Read((IRegistry) value, registryName);
}
else
{
value = rootKey.GetValue(registryName);
} if (value != null)
{
fieldInfo.SetValue(registry, ChangeType(value, fieldInfo.FieldType));
}
else
{
flag = false;
}
}
}
return flag;
} /// <summary>
/// 保存到注册表
/// </summary>
/// <param name="rootKey"></param>
/// <param name="registry"></param>
/// <param name="name"></param>
/// <exception cref="ArgumentNullException">registry is null</exception>
/// <exception cref="Exception">Member type is same with Class type.</exception>
public static bool Save(this RegistryKey rootKey, IRegistry registry, string name = null)
{
if (registry == null) throw new ArgumentNullException(nameof(registry)); rootKey = rootKey?.CreateSubKey(name ?? registry.GetRegistryRootName()); if (rootKey == null) return false; using (rootKey)
{
Tuple<PropertyInfo[], FieldInfo[]> members = registry.GetMembers(); if (members.Item1.Length + members.Item2.Length == ) return false; foreach (PropertyInfo property in members.Item1)
{
string registryName = property.GetRegistryName();
object value = property.GetValue(registry, null);
if (RegistryInterface.IsAssignableFrom(property.PropertyType))
{
if (property.PropertyType == registry.GetType())
{
throw new Exception("Member type is same with Class type.");
} if (value != null) rootKey.Save((IRegistry) value, registryName);
}
else
{
value = ChangeType(value, TypeCode.String);
if (value != null) rootKey.SetValue(registryName, value, RegistryValueKind.String);
} } foreach (FieldInfo fieldInfo in members.Item2)
{
string registryName = fieldInfo.GetRegistryName();
object value = fieldInfo.GetValue(registry);
if (RegistryInterface.IsAssignableFrom(fieldInfo.FieldType))
{
if (fieldInfo.FieldType == registry.GetType())
{
throw new Exception("Member type is same with Class type.");
} if (value != null) rootKey.Save((IRegistry) value, registryName);
}
else
{
value = ChangeType(value, TypeCode.String);
if (value != null) rootKey.SetValue(registryName, value, RegistryValueKind.String);
}
}
}
return true;
} /// <summary>
/// 读取注册表
/// </summary>
/// <param name="registry"></param>
/// <param name="rootKey"></param>
/// <param name="name"></param>
/// <exception cref="ArgumentNullException">registry is null</exception>
/// <exception cref="Exception">Member type is same with class type.</exception>
public static bool Read(this IRegistry registry, RegistryKey rootKey, string name = null)
{
return rootKey.Read(registry, name);
} /// <summary>
/// 保存到注册表
/// </summary>
/// <param name="registry"></param>
/// <param name="rootKey"></param>
/// <param name="name"></param>
/// <exception cref="ArgumentNullException">registry is null</exception>
/// <exception cref="Exception">Member type is same with class type.</exception>
public static bool Save(this IRegistry registry, RegistryKey rootKey, string name = null)
{
return rootKey.Save(registry, name);
} private static object ChangeType(object value, Type conversionType)
{
try
{
if (conversionType == RegistryInterface)
{
return value;
} if (conversionType == typeof(Guid))
{
return new Guid((string) value);
} if (conversionType.IsEnum)
{
return Enum.Parse(conversionType, (string) value);
} return Convert.ChangeType(value, conversionType); }
catch (Exception)
{
return null;
}
} private static object ChangeType(object value, TypeCode typeCode)
{
try
{ if (value is IConvertible) return Convert.ChangeType(value, typeCode);
return value.ToString();
}
catch (Exception)
{
return null;
}
} private static bool IsDefinedRegistryAttribute(this MemberInfo memberInfo)
{
return memberInfo.IsDefined(IgnoreAttribute, false) || memberInfo.IsDefined(MemberAttribute, false);
} private static string GetRegistryRootName(this IRegistry registry)
{
Type rootType = registry.GetType();
return rootType.IsDefined(typeof(RegistryRootAttribute), false)
? rootType.GetCustomAttribute<RegistryRootAttribute>().Name
: rootType.Name;
} private static string GetRegistryName(this MemberInfo memberInfo)
{
return memberInfo.IsDefined(MemberAttribute, false)
? memberInfo.GetCustomAttribute<RegistryMemberAttribute>().Name
: memberInfo.Name;
} private static Tuple<PropertyInfo[], FieldInfo[]> GetMembers(this IRegistry registry)
{
if (registry == null) throw new ArgumentNullException(nameof(registry));
Type t = registry.GetType(); IList<MemberInfo> lst =
t.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static |
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField |
BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty).ToList(); bool isDefinedAttribute = lst.Any(i => i.IsDefinedRegistryAttribute());
if (isDefinedAttribute)
{
lst = lst.Where(i => i.IsDefinedRegistryAttribute()).ToList();
}
return isDefinedAttribute
? new Tuple<PropertyInfo[], FieldInfo[]>(lst.OfType<PropertyInfo>().ToArray(),
lst.OfType<FieldInfo>().ToArray())
: new Tuple<PropertyInfo[], FieldInfo[]>(t.GetProperties(), t.GetFields());
} /// <summary>
/// The get custom attribute.
/// </summary>
/// <param name="element">
/// The element.
/// </param>
/// <typeparam name="T">Attribute type
/// </typeparam>
/// <returns>
/// The custom attribute
/// </returns>
private static T GetCustomAttribute<T>(this MemberInfo element) where T : Attribute
{
return (T)Attribute.GetCustomAttribute(element, typeof(T));
}
} /// <summary>
/// RegistryRootAttribute:用于描述注册表对象类
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class RegistryRootAttribute : Attribute
{
/// <summary>
/// Name
/// </summary>
public string Name { get; set; } /// <summary>
/// Value
/// </summary>
public string Value { get; set; }
} /// <summary>
/// RegistryIgnoreAttribute:忽略注册表成员,使用了该特性,将忽略未定义RegistryMemberAttribute的成员
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class RegistryIgnoreAttribute : Attribute { } /// <summary>
/// RegistryMemberAttribute:用于描述注册表成员,使用了该特性,将忽略未定义RegistryMemberAttribute的成员
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class RegistryMemberAttribute : Attribute
{
/// <summary>
/// Name
/// </summary>
public string Name { get; set; }
}
}
注册表对象映射实现类
c#注册表对象映射的更多相关文章
- MyBitis(iBitis)系列随笔之二:类型别名(typeAliases)与表-对象映射(ORM)
类型别名(typeAliases): 作用:通过一个简单的别名来表示一个冗长的类型,这样可以降低复杂度. 类型别名标签typeAliases中可以包含多个typeAlias,如下 < ...
- 10#Windows注册表的那些事儿
引言 用了多年的Windows系统,其实并没有对Windows系统进行过深入的了解,也正是由于Windows系统不用深入了解就可以简单上手所以才有这么多人去使用.笔者是做软件开发的,使用的基本都是Wi ...
- asp.net中通过注册表来检测是否安装Office(迅雷/QQ是否已安装)
原文 asp.net中通过注册表来检测是否安装Office(迅雷/QQ是否已安装) 检测Office是否安装以及获取安装 路径 及安装版本 代码如下 复制代码 #region 检测Office是否 ...
- Delphi的注册表操作
转帖:Delphi的注册表操作 2009-12-21 11:12:52 分类: Delphi的注册表操作 32位Delphi程序中可利用TRegistry对象来存取注册表文件中的信息. 一.创 ...
- 贴一份用delphi修改注册表改网卡MAC地址的代码
//提示:此代码需要use Registry, Common; function WriteMAC(model:integer):integer; var reg:TRegistry; begin r ...
- 【API】注册表编程基础-RegCreateKeyEx、RegSetValueEx
1.环境: 操作系统:Windows 10 x64 编译器:VS2015 2.关键函数 LONG WINAPI RegCreateKeyEx( _In_ HKEY hKey, _In_ LPCTSTR ...
- Win 通过修改注册表把CapsLock映射为Rshift
成品: REGEDIT4 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] "Scancod ...
- ArcGIS AddIN开发之COM对象写入注册表
做一个交互式绘制文字的工具,希望这次设置的Symbol,下次打开ArcMap时自动调用这个Symbol,并支持对其进行修改. 解决方法是将这个Symbol写入注册表中,每次自动读取上一次设置的Symb ...
- 通过修改注册表将右alt键映射为application键
通过修改注册表将右alt键映射为application键的方法有许多键盘没有APPLICATION(上下文菜单)键,本文将教您如何把右ALT键映射为apps键.1.映射请将以下注册表信息用记事本保存为 ...
随机推荐
- mysql 线上not in查询中的一个坑
今天早上开发又过来说,怎么有个语句一直没有查询出结果,数据是有的呀,并发来了如下的sql(为了方法说明,表名及查询均做了修改): select * from t2 where t2.course no ...
- 扩展KMP --- HDU 3613 Best Reward
Best Reward Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权 ...
- HTML5 语义元素
返回目录 http://hovertree.com/h/bjaf/html5zixueji.htm 一个语义元素能够清楚的描述其意义给浏览器和开发者.无语义 元素实例: <div> 和 & ...
- python之import机制
1. 标准 import Python 中所有加载到内存的模块都放在 sys.modules .当 import 一个模块时首先会在这个列表中查找是否已经加载了此模块,如果加载了则只是将 ...
- H5调用Android播放视频
webView.loadUrl("http://10.0.2.2:8080/assets/RealNetJSCallJavaActivity.htm"); js调用的Java文件中 ...
- spring mvc各种常见类型参数绑定方式以及json字符串绑定对象
在使用spring mvc作为框架的时候,为了规范,我们通常希望客户端的请求参数符合规范直接通过DTO的方式从客户端提交到服务端,以便保持规范的一致性,除了很简单的情况使用RequestParam映射 ...
- linux多线程-互斥&条件变量与同步
多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...
- [Architecture Pattern] Repository实作查询功能
[Architecture Pattern] Repository实作查询功能 范例下载 范例程序代码:点此下载 问题情景 在系统的BLL与DAL之间,加入Repository Pattern的设计, ...
- ASP.NET MVC another entity of the same type already has the same primary key value
ASP.NET MVC项目 Repository层中,Update.Delete总是失败 another entity of the same type already has the same pr ...
- 关于ol有序裂变和ul无序列表前面的列表项标记的位置
使用列表项标记的时候发现其对齐方式竟然从内容开始,于是发现了这个属性可以解决: list-style-position inside 列表项目标记放置在文本以内,且环绕文本根据标记对齐. outsid ...