You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1120 lines
						
					
					
						
							40 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							1120 lines
						
					
					
						
							40 KiB
						
					
					
				
								using Apewer.Models;
							 | 
						|
								using System;
							 | 
						|
								using System.Collections.Generic;
							 | 
						|
								using System.Diagnostics;
							 | 
						|
								using System.IO;
							 | 
						|
								using System.Reflection;
							 | 
						|
								using System.Runtime.CompilerServices;
							 | 
						|
								using System.Text;
							 | 
						|
								using System.Threading;
							 | 
						|
								
							 | 
						|
								namespace Apewer
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								    /// <summary>运行时实用工具。</summary>
							 | 
						|
								    public static class RuntimeUtility
							 | 
						|
								    {
							 | 
						|
								
							 | 
						|
								        /// <summary><see cref="object" /></summary>
							 | 
						|
								        public static Type ObjectType { get; } = typeof(object);
							 | 
						|
								
							 | 
						|
								        /// <summary>使用默认比较器判断相等。</summary>
							 | 
						|
								        public static bool Equals<T>(T a, T b) => EqualityComparer<T>.Default.Equals(a, b);
							 | 
						|
								
							 | 
						|
								        #region 反射操作
							 | 
						|
								
							 | 
						|
								        /// <summary>从外部加载对象。</summary>
							 | 
						|
								        public static object CreateObject(string path, string type, bool ignoreCase)
							 | 
						|
								        {
							 | 
						|
								            try
							 | 
						|
								            {
							 | 
						|
								                var a = Assembly.LoadFrom(path);
							 | 
						|
								                var t = a.GetType(type, false, ignoreCase);
							 | 
						|
								                if (t != null)
							 | 
						|
								                {
							 | 
						|
								                    var result = Activator.CreateInstance(t);
							 | 
						|
								                    return result;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								            catch { }
							 | 
						|
								            return null;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>对每个属性执行动作。</summary>
							 | 
						|
								        public static void ForEachProperties(object instance, Action<Property> action, bool withNonPublic = true, bool withStatic = false)
							 | 
						|
								        {
							 | 
						|
								            if (instance == null || action == null) return;
							 | 
						|
								            var type = instance.GetType();
							 | 
						|
								            if (type == null) return;
							 | 
						|
								
							 | 
						|
								            var properties = new List<PropertyInfo>();
							 | 
						|
								            properties.AddRange(type.GetProperties());
							 | 
						|
								            if (withNonPublic) properties.AddRange(type.GetProperties(BindingFlags.NonPublic));
							 | 
						|
								            foreach (var info in properties)
							 | 
						|
								            {
							 | 
						|
								                var arg = new Property()
							 | 
						|
								                {
							 | 
						|
								                    Instance = instance,
							 | 
						|
								                    Type = type,
							 | 
						|
								                    Information = info,
							 | 
						|
								                    Getter = info.GetGetMethod(),
							 | 
						|
								                    Setter = info.GetSetMethod()
							 | 
						|
								                };
							 | 
						|
								                if (arg.IsStatic && !withStatic) continue;
							 | 
						|
								                action.Invoke(arg);
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region Type
							 | 
						|
								
							 | 
						|
								        /// <summary>判断指定类型可序列化。</summary>
							 | 
						|
								        public static bool CanSerialize(Type type, bool inherit = false)
							 | 
						|
								        {
							 | 
						|
								            if (type == null) return false;
							 | 
						|
								
							 | 
						|
								            var nsas = type.GetCustomAttributes(typeof(NonSerializedAttribute), inherit);
							 | 
						|
								            if (nsas != null && nsas.Length > 0) return false;
							 | 
						|
								
							 | 
						|
								            var sas = type.GetCustomAttributes(typeof(SerializableAttribute), inherit);
							 | 
						|
								            if (sas != null && sas.Length > 0) return true;
							 | 
						|
								
							 | 
						|
								            var tas = type.GetCustomAttributes(typeof(Source.TableAttribute), inherit);
							 | 
						|
								            if (tas != null && tas.Length > 0) return true;
							 | 
						|
								
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取类型的完整名称。</summary>
							 | 
						|
								        public static string FullName(Type type)
							 | 
						|
								        {
							 | 
						|
								            if (type == null) return null;
							 | 
						|
								            var sb = new StringBuilder();
							 | 
						|
								
							 | 
						|
								            var ns = type.Namespace;
							 | 
						|
								            if (!string.IsNullOrEmpty(ns))
							 | 
						|
								            {
							 | 
						|
								                sb.Append(ns);
							 | 
						|
								                sb.Append(".");
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            var name = type.Name;
							 | 
						|
								            var g = name.IndexOf('`');
							 | 
						|
								            if (g > -1) name = name.Substring(0, g);
							 | 
						|
								            sb.Append(name);
							 | 
						|
								
							 | 
						|
								            var gts = type.GetGenericArguments();
							 | 
						|
								            if (gts != null && gts.Length > 0)
							 | 
						|
								            {
							 | 
						|
								                var ts = new List<string>(gts.Length);
							 | 
						|
								                foreach (var gt in gts) ts.Add(FullName(gt));
							 | 
						|
								                sb.Append("<");
							 | 
						|
								                sb.Append(string.Join(",", ts.ToArray()));
							 | 
						|
								                sb.Append(">");
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            return sb.ToString();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>检查类型。</summary>
							 | 
						|
								        public static bool TypeEquals(object instance, Type type)
							 | 
						|
								        {
							 | 
						|
								            if (instance == null) return type == null ? true : false;
							 | 
						|
								            if (instance is PropertyInfo)
							 | 
						|
								            {
							 | 
						|
								                return ((PropertyInfo)instance).PropertyType.Equals(type);
							 | 
						|
								            }
							 | 
						|
								            if (instance is MethodInfo)
							 | 
						|
								            {
							 | 
						|
								                return ((MethodInfo)instance).ReturnType.Equals(type);
							 | 
						|
								            }
							 | 
						|
								            return instance.GetType().Equals(type);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>检查类型。</summary>
							 | 
						|
								        public static bool TypeEquals<T>(object instance) => TypeEquals(instance, typeof(T));
							 | 
						|
								
							 | 
						|
								        /// <summary>获取指定的首个特性,特性不存在时返回 Null 值。</summary>
							 | 
						|
								        public static T GetAttribute<T>(object target) where T : Attribute
							 | 
						|
								        {
							 | 
						|
								            if (target == null) return null;
							 | 
						|
								            try { return GetAttribute<T>(target.GetType()); } catch { return null; }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取指定的首个特性,特性不存在时返回 Null 值。</summary>
							 | 
						|
								        public static T GetAttribute<T>(Type target, bool inherit = false) where T : Attribute
							 | 
						|
								        {
							 | 
						|
								            if (target == null) return null;
							 | 
						|
								            try
							 | 
						|
								            {
							 | 
						|
								                var type = target;
							 | 
						|
								                var attributes = type.GetCustomAttributes(typeof(T), inherit);
							 | 
						|
								                if (attributes.LongLength > 0L)
							 | 
						|
								                {
							 | 
						|
								                    var attribute = attributes[0] as T;
							 | 
						|
								                    return attribute;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								            catch { }
							 | 
						|
								            return null;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取指定的首个特性,特性不存在时返回 Null 值。</summary>
							 | 
						|
								        public static T GetAttribute<T>(PropertyInfo property, bool inherit = false) where T : Attribute
							 | 
						|
								        {
							 | 
						|
								            if (property == null) return null;
							 | 
						|
								            try
							 | 
						|
								            {
							 | 
						|
								                var type = property;
							 | 
						|
								                var attributes = type.GetCustomAttributes(typeof(T), inherit);
							 | 
						|
								                if (attributes.LongLength > 0L)
							 | 
						|
								                {
							 | 
						|
								                    var attribute = attributes[0] as T;
							 | 
						|
								                    return attribute;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								            catch { }
							 | 
						|
								            return null;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取指定的首个特性,特性不存在时返回 Null 值。</summary>
							 | 
						|
								        public static T GetAttribute<T>(MethodInfo methods, bool inherit = false) where T : Attribute
							 | 
						|
								        {
							 | 
						|
								            if (methods == null) return null;
							 | 
						|
								            try
							 | 
						|
								            {
							 | 
						|
								                var type = methods;
							 | 
						|
								                var attributes = type.GetCustomAttributes(typeof(T), inherit);
							 | 
						|
								                if (attributes.LongLength > 0L)
							 | 
						|
								                {
							 | 
						|
								                    var attribute = attributes[0] as T;
							 | 
						|
								                    return attribute;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								            catch { }
							 | 
						|
								            return null;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取一个值,指示该属性是否 static。</summary>
							 | 
						|
								        public static bool IsStatic(PropertyInfo property, bool withNonPublic = false)
							 | 
						|
								        {
							 | 
						|
								            if (property == null) return false;
							 | 
						|
								
							 | 
						|
								            var getter = property.GetGetMethod();
							 | 
						|
								            if (getter != null) return getter.IsStatic;
							 | 
						|
								
							 | 
						|
								            if (withNonPublic)
							 | 
						|
								            {
							 | 
						|
								                getter = property.GetGetMethod(true);
							 | 
						|
								                if (getter != null) return getter.IsStatic;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            var setter = property.GetSetMethod();
							 | 
						|
								            if (setter != null) return setter.IsStatic;
							 | 
						|
								
							 | 
						|
								            if (withNonPublic)
							 | 
						|
								            {
							 | 
						|
								                setter = property.GetSetMethod(true);
							 | 
						|
								                if (setter != null) return setter.IsStatic;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>调用方法。</summary>
							 | 
						|
								        /// <exception cref="ArgumentException"></exception>
							 | 
						|
								        /// <exception cref="InvalidOperationException"></exception>
							 | 
						|
								        /// <exception cref="MethodAccessException"></exception>
							 | 
						|
								        /// <exception cref="NotSupportedException"></exception>
							 | 
						|
								        /// <exception cref="TargetException"></exception>
							 | 
						|
								        /// <exception cref="TargetInvocationException"></exception>
							 | 
						|
								        /// <exception cref="TargetParameterCountException"></exception>
							 | 
						|
								        public static object Invoke(this MethodInfo method, object instance, params object[] parameters)
							 | 
						|
								        {
							 | 
						|
								            if (instance == null || method == null) return null;
							 | 
						|
								
							 | 
						|
								            var pis = method.GetParameters();
							 | 
						|
								            if (pis == null || pis.Length < 1) return method.Invoke(instance, null);
							 | 
						|
								
							 | 
						|
								            if (parameters == null) return method.Invoke(instance, null);
							 | 
						|
								            return method.Invoke(instance, parameters);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>调用泛型对象的 ToString() 方法。</summary>
							 | 
						|
								        public static string ToString<T>(T target)
							 | 
						|
								        {
							 | 
						|
								            var type = typeof(T);
							 | 
						|
								            var methods = type.GetMethods();
							 | 
						|
								            foreach (var method in methods)
							 | 
						|
								            {
							 | 
						|
								                if (method.Name != "ToString") continue;
							 | 
						|
								                if (method.GetParameters().LongLength > 0L) continue;
							 | 
						|
								                var result = (string)method.Invoke(target, null);
							 | 
						|
								                return result;
							 | 
						|
								            }
							 | 
						|
								            return null;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取属性值。</summary>
							 | 
						|
								        /// <exception cref="ArgumentException"></exception>
							 | 
						|
								        /// <exception cref="InvalidOperationException"></exception>
							 | 
						|
								        /// <exception cref="MethodAccessException"></exception>
							 | 
						|
								        /// <exception cref="NotSupportedException"></exception>
							 | 
						|
								        /// <exception cref="TargetException"></exception>
							 | 
						|
								        /// <exception cref="TargetInvocationException"></exception>
							 | 
						|
								        /// <exception cref="TargetParameterCountException"></exception>
							 | 
						|
								        public static T InvokeGet<T>(object instance, PropertyInfo property)
							 | 
						|
								        {
							 | 
						|
								            if (instance == null || property == null || !property.CanRead) return default;
							 | 
						|
								#if NET20 || NET40 || NET461
							 | 
						|
								            var getter = property.GetGetMethod();
							 | 
						|
								            if (getter != null)
							 | 
						|
								            {
							 | 
						|
								                try
							 | 
						|
								                {
							 | 
						|
								                    var value = getter.Invoke(instance, null);
							 | 
						|
								                    if (value != null)
							 | 
						|
								                    {
							 | 
						|
								                        return (T)value;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								                catch { }
							 | 
						|
								            }
							 | 
						|
								            return default;
							 | 
						|
								#else
							 | 
						|
								            var value = property.GetValue(instance);
							 | 
						|
								            try { return (T)value; } catch { return default; }
							 | 
						|
								#endif
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>设置属性值。</summary>
							 | 
						|
								        /// <exception cref="ArgumentException"></exception>
							 | 
						|
								        /// <exception cref="InvalidOperationException"></exception>
							 | 
						|
								        /// <exception cref="MethodAccessException"></exception>
							 | 
						|
								        /// <exception cref="NotSupportedException"></exception>
							 | 
						|
								        /// <exception cref="TargetException"></exception>
							 | 
						|
								        /// <exception cref="TargetInvocationException"></exception>
							 | 
						|
								        /// <exception cref="TargetParameterCountException"></exception>
							 | 
						|
								        public static void InvokeSet<T>(object instance, PropertyInfo property, T value)
							 | 
						|
								        {
							 | 
						|
								            if (instance == null || property == null || !property.CanWrite) return;
							 | 
						|
								#if NET20 || NET40
							 | 
						|
								            var setter = property.GetSetMethod();
							 | 
						|
								            if (setter != null)
							 | 
						|
								            {
							 | 
						|
								                try
							 | 
						|
								                {
							 | 
						|
								                    setter.Invoke(instance, new object[] { value });
							 | 
						|
								                }
							 | 
						|
								                catch { }
							 | 
						|
								            }
							 | 
						|
								#else
							 | 
						|
								            property.SetValue(instance, value);
							 | 
						|
								#endif
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>指示方法是否存在于指定类型中。</summary>
							 | 
						|
								        public static bool ExistIn(MethodInfo method, Type type)
							 | 
						|
								        {
							 | 
						|
								            if (method == null) return false;
							 | 
						|
								            if (type == null) return false;
							 | 
						|
								            return type.Equals(method.DeclaringType.Equals(type));
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>指示方法是否存在于指定类型中。</summary>
							 | 
						|
								        public static bool ExistIn<T>(MethodInfo method)
							 | 
						|
								        {
							 | 
						|
								            if (method == null) return false;
							 | 
						|
								            var type = typeof(T);
							 | 
						|
								            return type.Equals(method.DeclaringType.Equals(type));
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>判断指定类型具有特性。</summary>
							 | 
						|
								        private static bool Contains<T>(object[] attributes) where T : Attribute
							 | 
						|
								        {
							 | 
						|
								            if (attributes == null) return false;
							 | 
						|
								            if (attributes.Length < 1) return false;
							 | 
						|
								            var type = typeof(T);
							 | 
						|
								            foreach (var attribute in attributes)
							 | 
						|
								            {
							 | 
						|
								                if (type.Equals(attribute.GetType())) return true;
							 | 
						|
								            }
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>判断指定类型具有特性。</summary>
							 | 
						|
								        public static bool Contains<T>(ICustomAttributeProvider model, bool inherit = false) where T : Attribute
							 | 
						|
								        {
							 | 
						|
								            if (model == null) return false;
							 | 
						|
								            var attributes = model.GetCustomAttributes(inherit);
							 | 
						|
								            return Contains<T>(attributes);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>判断基类。</summary>
							 | 
						|
								        public static bool IsInherits(Type child, Type @base)
							 | 
						|
								        {
							 | 
						|
								            // 检查参数。
							 | 
						|
								            if (child == null || @base == null) return false;
							 | 
						|
								            if (child == @base) return false;
							 | 
						|
								
							 | 
						|
								            // 检查 interface 类型。
							 | 
						|
								            if (@base.IsInterface) return @base.IsAssignableFrom(child);
							 | 
						|
								
							 | 
						|
								            // 忽略 System.Object。
							 | 
						|
								            var quantum = typeof(object);
							 | 
						|
								            if (@base.Equals(quantum)) return true;
							 | 
						|
								            if (child.Equals(quantum)) return false;
							 | 
						|
								
							 | 
						|
								            // 循环判断基类。
							 | 
						|
								            var current = child;
							 | 
						|
								            while (true)
							 | 
						|
								            {
							 | 
						|
								                var parent = current.BaseType;
							 | 
						|
								                if (parent == null) return false;
							 | 
						|
								                if (parent.Equals(@base)) return true;
							 | 
						|
								                if (parent.Equals(quantum)) break;
							 | 
						|
								                current = parent;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary></summary>
							 | 
						|
								        public static Type[] GetTypes(Assembly assembly, bool onlyExported = false)
							 | 
						|
								        {
							 | 
						|
								            if (assembly == null) return null;
							 | 
						|
								            try
							 | 
						|
								            {
							 | 
						|
								                return onlyExported ? assembly.GetExportedTypes() : assembly.GetTypes();
							 | 
						|
								            }
							 | 
						|
								            catch { }
							 | 
						|
								            return new Type[0];
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>能从外部创建对象实例。</summary>
							 | 
						|
								        public static bool CanNew<T>() => CanNew(typeof(T));
							 | 
						|
								
							 | 
						|
								        /// <summary>能从外部创建对象实例。</summary>
							 | 
						|
								        public static bool CanNew(Type type)
							 | 
						|
								        {
							 | 
						|
								            if (type == null) return false;
							 | 
						|
								            if (!type.IsClass && !type.IsValueType) return false;
							 | 
						|
								            if (type.IsAbstract) return false;
							 | 
						|
								
							 | 
						|
								            var constructors = type.GetConstructors();
							 | 
						|
								            foreach (var i in constructors)
							 | 
						|
								            {
							 | 
						|
								                if (i.IsPublic)
							 | 
						|
								                {
							 | 
						|
								                    var parameters = i.GetParameters();
							 | 
						|
								                    if (parameters.Length < 1)
							 | 
						|
								                    {
							 | 
						|
								                        return true;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取指定类型的默认值。</summary>
							 | 
						|
								        public static object Default(Type type)
							 | 
						|
								        {
							 | 
						|
								            if (type == null || !type.IsValueType) return null;
							 | 
						|
								            return Activator.CreateInstance(type);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>判断指定对象是否为默认值。</summary>
							 | 
						|
								        public static bool IsDefault(object value)
							 | 
						|
								        {
							 | 
						|
								            if (value.IsNull()) return true;
							 | 
						|
								            var type = value.GetType();
							 | 
						|
								            if (type.IsValueType) return value.Equals(Activator.CreateInstance(type));
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>在程序集中枚举派生类型,可自定义检查器。</summary>
							 | 
						|
								        public static Type[] DerivedTypes(Type baseType, Assembly assembly, Func<Type, bool> checker)
							 | 
						|
								        {
							 | 
						|
								            if (baseType == null) return new Type[0];
							 | 
						|
								            if (assembly == null) return new Type[0];
							 | 
						|
								            var types = GetTypes(assembly);
							 | 
						|
								            var list = new List<Type>(types.Length);
							 | 
						|
								            foreach (var type in types)
							 | 
						|
								            {
							 | 
						|
								                if (!IsInherits(type, baseType)) continue;
							 | 
						|
								                if (checker != null && !checker(type)) continue;
							 | 
						|
								                list.Add(type);
							 | 
						|
								            }
							 | 
						|
								            return list.ToArray();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>是匿名类型。</summary>
							 | 
						|
								        /// <exception cref="ArgumentNullException"></exception>
							 | 
						|
								        public static bool IsAnonymousType(Type type)
							 | 
						|
								        {
							 | 
						|
								            if (type == null) throw new ArgumentNullException(nameof(type));
							 | 
						|
								
							 | 
						|
								            // 类型是由编译器生成。
							 | 
						|
								            if (!Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)) return false;
							 | 
						|
								
							 | 
						|
								            // 是泛型。
							 | 
						|
								            if (!type.IsGenericType) return false;
							 | 
						|
								
							 | 
						|
								            // 名称。
							 | 
						|
								            if (!type.Name.StartsWith("<>") || !type.Name.Contains("AnonymousType")) return false;
							 | 
						|
								
							 | 
						|
								            // 私有。
							 | 
						|
								            if (type.IsPublic) return false;
							 | 
						|
								
							 | 
						|
								            return true;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取数组元素的类型。</summary>
							 | 
						|
								        /// <remarks>参数必须是正确的数组类型。</remarks>
							 | 
						|
								        /// <exception cref="ArgumentException"></exception>
							 | 
						|
								        /// <exception cref="ArgumentNullException"></exception>
							 | 
						|
								        public static Type GetTypeOfArrayItem(Type arrayType)
							 | 
						|
								        {
							 | 
						|
								            if (arrayType == null) throw new ArgumentNullException(nameof(arrayType));
							 | 
						|
								            if (!arrayType.BaseType.Equals(typeof(Array))) throw new ArgumentException($"参数 {arrayType} 不是有效的数组类型。");
							 | 
						|
								
							 | 
						|
								            var methods = arrayType.GetMethods();
							 | 
						|
								            foreach (var method in methods)
							 | 
						|
								            {
							 | 
						|
								                if (method.Name.ToLower() != "set") continue;
							 | 
						|
								
							 | 
						|
								                var parameters = method.GetParameters();
							 | 
						|
								                if (parameters.Length != 2) continue;
							 | 
						|
								
							 | 
						|
								                var length = parameters[0].ParameterType;
							 | 
						|
								                if (!length.Equals(typeof(int))) continue;
							 | 
						|
								
							 | 
						|
								                var item = parameters[1].ParameterType;
							 | 
						|
								                return item;
							 | 
						|
								            }
							 | 
						|
								            throw new ArgumentException($"参数 {arrayType} 不是有效的数组类型。");
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>是 Nullable<T> 类型。</summary>
							 | 
						|
								        public static bool IsNullableType(this Type type)
							 | 
						|
								        {
							 | 
						|
								            if (type.IsGenericType && !type.IsGenericTypeDefinition)
							 | 
						|
								            {
							 | 
						|
								                Type genericTypeDefinition = type.GetGenericTypeDefinition();
							 | 
						|
								                if ((object)genericTypeDefinition == typeof(Nullable<>))
							 | 
						|
								                {
							 | 
						|
								                    return true;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>是 Nullable<T> 类型。</summary>
							 | 
						|
								        public static bool IsNullableType(this Type type, out Type genericType)
							 | 
						|
								        {
							 | 
						|
								            if (type.IsGenericType && !type.IsGenericTypeDefinition)
							 | 
						|
								            {
							 | 
						|
								                Type genericTypeDefinition = type.GetGenericTypeDefinition();
							 | 
						|
								                if ((object)genericTypeDefinition == typeof(Nullable<>))
							 | 
						|
								                {
							 | 
						|
								                    genericType = type.GetGenericArguments()[0];
							 | 
						|
								                    return true;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            genericType = null;
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取 Nullable<T> 实例的值。</summary>
							 | 
						|
								        public static object GetNullableValue(object nullable)
							 | 
						|
								        {
							 | 
						|
								            var type = typeof(Nullable<>);
							 | 
						|
								            var property = type.GetProperty("Value");
							 | 
						|
								            var getter = property.GetGetMethod();
							 | 
						|
								            var value = getter.Invoke(nullable, null);
							 | 
						|
								            return value;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region Collect & Dispose
							 | 
						|
								
							 | 
						|
								        /// <summary>控制系统垃圾回收器(一种自动回收未使用内存的服务)。强制对所有代进行即时垃圾回收。</summary>
							 | 
						|
								        public static void Collect() => GC.Collect();
							 | 
						|
								
							 | 
						|
								        /// <summary>执行与释放或重置非托管资源关联的应用程序定义的任务。</summary>
							 | 
						|
								        /// <returns>可能出现的错误信息。</returns>
							 | 
						|
								        public static void Dispose(object instance, bool flush = false)
							 | 
						|
								        {
							 | 
						|
								            if (instance == null) return;
							 | 
						|
								
							 | 
						|
								            var stream = instance as Stream;
							 | 
						|
								            if (stream != null)
							 | 
						|
								            {
							 | 
						|
								                if (flush)
							 | 
						|
								                {
							 | 
						|
								                    try { stream.Flush(); } catch { }
							 | 
						|
								                }
							 | 
						|
								                try { stream.Close(); } catch { }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            var disposable = instance as IDisposable;
							 | 
						|
								            if (disposable != null)
							 | 
						|
								            {
							 | 
						|
								                try
							 | 
						|
								                {
							 | 
						|
								                    disposable.Dispose();
							 | 
						|
								                }
							 | 
						|
								                catch { }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>执行与释放或重置非托管资源关联的应用程序定义的任务。</summary>
							 | 
						|
								        /// <returns>可能出现的错误信息。</returns>
							 | 
						|
								        public static void Dispose<T>(IEnumerable<T> objects, bool flush = false)
							 | 
						|
								        {
							 | 
						|
								            if (objects != null)
							 | 
						|
								            {
							 | 
						|
								                foreach (var i in objects) Dispose(i, flush);
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region Thread
							 | 
						|
								
							 | 
						|
								        /// <summary>停止线程。</summary>
							 | 
						|
								        public static void Abort(Thread thread)
							 | 
						|
								        {
							 | 
						|
								            if (thread == null) return;
							 | 
						|
								            try
							 | 
						|
								            {
							 | 
						|
								                if (thread.IsAlive) thread.Abort();
							 | 
						|
								            }
							 | 
						|
								            catch { }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>阻塞当前线程,时长以毫秒为单位。</summary>
							 | 
						|
								        public static void Sleep(int milliseconds)
							 | 
						|
								        {
							 | 
						|
								            if (milliseconds > 0) Thread.Sleep(milliseconds);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        private static void Invoke(Action action, bool @try = false)
							 | 
						|
								        {
							 | 
						|
								            if (action == null) return;
							 | 
						|
								            if (@try)
							 | 
						|
								            {
							 | 
						|
								                try { action.Invoke(); } catch { }
							 | 
						|
								            }
							 | 
						|
								            else { action.Invoke(); }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>在后台线程中执行,指定 Try 将忽略 Action 抛出的异常。</summary>
							 | 
						|
								        /// <param name="action">要执行的 Action。</param>
							 | 
						|
								        /// <param name="try">忽略 Action 抛出的异常。</param>
							 | 
						|
								        /// <remarks>对返回的 Thread 调用 Abort 可结束线程的执行。</remarks>
							 | 
						|
								        [MethodImpl(MethodImplOptions.NoInlining)]
							 | 
						|
								        public static Thread InBackground(Action action, bool @try = false)
							 | 
						|
								        {
							 | 
						|
								            if (action == null) return null;
							 | 
						|
								            var thread = new Thread(delegate (object v)
							 | 
						|
								            {
							 | 
						|
								                Invoke(() => ((Action)v)(), @try);
							 | 
						|
								            });
							 | 
						|
								            thread.IsBackground = true;
							 | 
						|
								            thread.Start(action);
							 | 
						|
								            return thread;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>在后台线程中执行,指定 Try 将忽略 Action 抛出的异常。</summary>
							 | 
						|
								        /// <param name="delay">延迟的毫秒数。</param>
							 | 
						|
								        /// <param name="action">要执行的 Action。</param>
							 | 
						|
								        /// <param name="try">忽略 Action 抛出的异常。</param>
							 | 
						|
								        /// <remarks>对返回的 Thread 调用 Abort 可结束线程的执行。</remarks>
							 | 
						|
								        [MethodImpl(MethodImplOptions.NoInlining)]
							 | 
						|
								        public static Thread InBackground(int delay, Action action, bool @try = false)
							 | 
						|
								        {
							 | 
						|
								            if (action == null) return null;
							 | 
						|
								            var thread = new Thread(delegate (object v)
							 | 
						|
								            {
							 | 
						|
								                if (delay > 0) Thread.Sleep(delay);
							 | 
						|
								                Invoke(() => ((Action)v)(), @try);
							 | 
						|
								            });
							 | 
						|
								            thread.IsBackground = true;
							 | 
						|
								            thread.Start(action);
							 | 
						|
								            return thread;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>启动线程,在新线程中执行。</summary>
							 | 
						|
								        /// <param name="action">要执行的 Action。</param>
							 | 
						|
								        /// <param name="background">设置线程为后台线程。</param>
							 | 
						|
								        /// <param name="try">忽略 Action 抛出的异常。</param>
							 | 
						|
								        /// <remarks>对返回的 Thread 调用 Abort 可结束线程的执行。</remarks>
							 | 
						|
								        public static Thread StartThread(Action action, bool background = false, bool @try = false)
							 | 
						|
								        {
							 | 
						|
								            if (action == null) return null;
							 | 
						|
								            var thread = new Thread(new ThreadStart(() => Invoke(action, @try)));
							 | 
						|
								            thread.IsBackground = background;
							 | 
						|
								            thread.Start();
							 | 
						|
								            return thread;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>经过指定时间(以毫秒为单位)后,在新线程(后台)中执行。</summary>
							 | 
						|
								        /// <param name="action">要执行的 Action。</param>
							 | 
						|
								        /// <param name="delay">调用 Action 之前延迟的时间量(以毫秒为单位)。</param>
							 | 
						|
								        /// <param name="try">忽略 Action 抛出的异常。</param>
							 | 
						|
								        /// <remarks>对返回的 Timer 调用 Dispose 可终止计时器,阻止调用。</remarks>
							 | 
						|
								        public static Timer Timeout(Action action, int delay, bool @try = false)
							 | 
						|
								        {
							 | 
						|
								            if (action == null) return null;
							 | 
						|
								            return new Timer((x) => Invoke((Action)x, @try), action, delay > 0 ? delay : 0, -1);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>尝试在主线程调用。</summary>
							 | 
						|
								        /// <exception cref="ArgumentNullException" />
							 | 
						|
								        /// <exception cref="InvalidOperationException" />
							 | 
						|
								        public static void OnMainThread(Action action)
							 | 
						|
								        {
							 | 
						|
								            if (action == null) throw new ArgumentNullException(nameof(action));
							 | 
						|
								
							 | 
						|
								            var context = SynchronizationContext.Current;
							 | 
						|
								            if (context == null) throw new InvalidOperationException("未获取到当前线程的同步上下文。");
							 | 
						|
								
							 | 
						|
								            context.Send(state => { action.Invoke(); }, null);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>尝试在主线程调用。</summary>
							 | 
						|
								        /// <exception cref="ArgumentNullException" />
							 | 
						|
								        /// <exception cref="InvalidOperationException" />
							 | 
						|
								        public static TResult OnMainThread<TResult>(Func<TResult> func)
							 | 
						|
								        {
							 | 
						|
								            if (func == null) throw new ArgumentNullException(nameof(func));
							 | 
						|
								
							 | 
						|
								            var context = SynchronizationContext.Current;
							 | 
						|
								            if (context == null) throw new InvalidOperationException("未获取到当前线程的同步上下文。");
							 | 
						|
								
							 | 
						|
								            var result = default(TResult);
							 | 
						|
								            context.Send(state => result = func.Invoke(), null);
							 | 
						|
								            return result;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region Assembly
							 | 
						|
								
							 | 
						|
								        /// <summary>列出当前域中的程序集。</summary>
							 | 
						|
								        public static Assembly[] ListLoadedAssemblies()
							 | 
						|
								        {
							 | 
						|
								            return AppDomain.CurrentDomain.GetAssemblies();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>从指定的程序集加载资源。</summary>
							 | 
						|
								        /// <param name="name">资源的名称。</param>
							 | 
						|
								        /// <param name="assembly">程序集,为 NULL 值时指向 CallingAssembly。</param>
							 | 
						|
								        /// <returns>该资源的流,发生错误时返回 NULL 值。</returns>
							 | 
						|
								        /// <remarks>此方法不引发异常。</remarks>
							 | 
						|
								        public static Stream OpenResource(string name, Assembly assembly = null)
							 | 
						|
								        {
							 | 
						|
								            var stream = null as Stream;
							 | 
						|
								            try
							 | 
						|
								            {
							 | 
						|
								                var asm = assembly ?? Assembly.GetCallingAssembly();
							 | 
						|
								                stream = asm.GetManifestResourceStream(name);
							 | 
						|
								            }
							 | 
						|
								            catch { }
							 | 
						|
								            return null;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>从程序集获取资源,读取到内存流。发生错误时返回 NULL 值,不引发异常。</summary>
							 | 
						|
								        /// <param name="name">资源的名称。</param>
							 | 
						|
								        /// <param name="assembly">程序集,为 NULL 值时指向 CallingAssembly。</param>
							 | 
						|
								        /// <returns>该资源的流,发生错误时返回 NULL 值。</returns>
							 | 
						|
								        /// <remarks>此方法不引发异常。</remarks>
							 | 
						|
								        public static MemoryStream GetResource(string name, Assembly assembly = null)
							 | 
						|
								        {
							 | 
						|
								            var res = OpenResource(name, assembly);
							 | 
						|
								            if (res == null) return null;
							 | 
						|
								
							 | 
						|
								            var memory = new MemoryStream();
							 | 
						|
								            BytesUtility.Read(res, memory);
							 | 
						|
								            res.Dispose();
							 | 
						|
								            return memory;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								#if NETFRAMEWORK
							 | 
						|
								
							 | 
						|
								        /// <summary>将代码生成为程序集。</summary>
							 | 
						|
								        public static Assembly Compile(string code, bool executable = false, bool inMemory = true)
							 | 
						|
								        {
							 | 
						|
								            using (var cdp = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("C#"))
							 | 
						|
								            {
							 | 
						|
								                var cp = new System.CodeDom.Compiler.CompilerParameters();
							 | 
						|
								                cp.ReferencedAssemblies.Add(typeof(void).Assembly.Location);
							 | 
						|
								                cp.GenerateExecutable = false;
							 | 
						|
								                cp.GenerateInMemory = true;
							 | 
						|
								                cp.TempFiles = new System.CodeDom.Compiler.TempFileCollection(System.IO.Path.GetTempPath());
							 | 
						|
								
							 | 
						|
								                var cr = cdp.CompileAssemblyFromSource(cp, code);
							 | 
						|
								                if (cr.Errors.Count > 0) throw new Exception(cr.Errors[0].ErrorText);
							 | 
						|
								
							 | 
						|
								                var assembly = cr.CompiledAssembly;
							 | 
						|
								                return assembly;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region Application
							 | 
						|
								
							 | 
						|
								        private static Class<string> _AppPath = null;
							 | 
						|
								        private static Class<string> _DataPath = null;
							 | 
						|
								        private static Class<bool> _InIIS = null;
							 | 
						|
								
							 | 
						|
								        /// <summary>当前应用程序由 IIS 托管。</summary>
							 | 
						|
								        private static bool InIIS()
							 | 
						|
								        {
							 | 
						|
								            if (_InIIS != null) return _InIIS.Value;
							 | 
						|
								
							 | 
						|
								            var dll = Path.GetFileName(Assembly.GetExecutingAssembly().Location);
							 | 
						|
								            var path1 = StorageUtility.CombinePath(ApplicationPath, dll);
							 | 
						|
								            if (!File.Exists(path1))
							 | 
						|
								            {
							 | 
						|
								                var path2 = StorageUtility.CombinePath(ApplicationPath, "bin", dll);
							 | 
						|
								                if (File.Exists(path2))
							 | 
						|
								                {
							 | 
						|
								                    _InIIS = new Class<bool>(true);
							 | 
						|
								                    return true;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            _InIIS = new Class<bool>(false);
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取当前应用程序所在目录的路径。</summary>
							 | 
						|
								        /// <remarks>
							 | 
						|
								        /// <para>程序示例: D:\App</para>
							 | 
						|
								        /// <para>网站示例: D:\Website</para>
							 | 
						|
								        /// </remarks>
							 | 
						|
								        public static string ApplicationPath
							 | 
						|
								        {
							 | 
						|
								            get
							 | 
						|
								            {
							 | 
						|
								                var temp = _AppPath;
							 | 
						|
								                if (!temp)
							 | 
						|
								                {
							 | 
						|
								                    // AppDomain.CurrentDomain.BaseDirectory
							 | 
						|
								                    // AppDomain.CurrentDomain.SetupInformation.ApplicationBase
							 | 
						|
								                    // return AppDomain.CurrentDomain.BaseDirectory;
							 | 
						|
								#if NETSTD
							 | 
						|
								                    var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
							 | 
						|
								#else
							 | 
						|
								                    var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
							 | 
						|
								#endif
							 | 
						|
								                    path = TextUtility.AssureEnds(path, "\\", false);
							 | 
						|
								                    path = TextUtility.AssureEnds(path, "/", false);
							 | 
						|
								                    temp = new Class<string>(path);
							 | 
						|
								                    _AppPath = temp;
							 | 
						|
								                }
							 | 
						|
								                return temp.Value;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取数据目录的路径。</summary>
							 | 
						|
								        public static string DataPath
							 | 
						|
								        {
							 | 
						|
								            get
							 | 
						|
								            {
							 | 
						|
								                var temp = _DataPath;
							 | 
						|
								                if (!temp)
							 | 
						|
								                {
							 | 
						|
								                    var app = ApplicationPath;
							 | 
						|
								
							 | 
						|
								                    // 网站使用 App_Data 目录。
							 | 
						|
								                    var appData = Path.Combine(app, "app_data");
							 | 
						|
								                    if (Directory.Exists(appData))
							 | 
						|
								                    {
							 | 
						|
								                        temp = new Class<string>(appData);
							 | 
						|
								                    }
							 | 
						|
								                    else if (File.Exists(Path.Combine(app, "web.config")))
							 | 
						|
								                    {
							 | 
						|
								                        StorageUtility.AssureDirectory(appData);
							 | 
						|
								                        temp = new Class<string>(appData);
							 | 
						|
								                    }
							 | 
						|
								                    else
							 | 
						|
								                    {
							 | 
						|
								                        // 获取并创建 Data 目录。
							 | 
						|
								                        var data = Path.Combine(app, "data");
							 | 
						|
								                        if (StorageUtility.AssureDirectory(data)) temp = new Class<string>(data);
							 | 
						|
								                        else temp = new Class<string>(app);
							 | 
						|
								                    }
							 | 
						|
								
							 | 
						|
								                    _DataPath = temp;
							 | 
						|
								                }
							 | 
						|
								                return temp.Value;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>获取可执行文件的路径。</summary>
							 | 
						|
								        /// <remarks>
							 | 
						|
								        /// <para>调用: System.Windows.Forms.Application.ExecutablePath</para>
							 | 
						|
								        /// <para>示例: c:\windows\system32\inetsrv\w3wp.exe</para>
							 | 
						|
								        /// </remarks>
							 | 
						|
								        public static string ExecutablePath
							 | 
						|
								        {
							 | 
						|
								            get
							 | 
						|
								            {
							 | 
						|
								                var entry = Assembly.GetEntryAssembly();
							 | 
						|
								                if (entry == null) return null;
							 | 
						|
								                var escapedCodeBase = entry.EscapedCodeBase;
							 | 
						|
								                var uri = new Uri(escapedCodeBase);
							 | 
						|
								                if (uri.Scheme == "file") return uri.LocalPath + uri.Fragment;
							 | 
						|
								                return uri.ToString();
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>
							 | 
						|
								        /// <para>System.AppDomain.CurrentDomain.BaseDirectory</para>
							 | 
						|
								        /// <para>D:\Website\</para>
							 | 
						|
								        /// </summary>
							 | 
						|
								        private static string CurrentDomainPath
							 | 
						|
								        {
							 | 
						|
								            get { return AppDomain.CurrentDomain.BaseDirectory; }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>
							 | 
						|
								        /// <para>System.IO.Directory.GetCurrentDirectory()</para>
							 | 
						|
								        /// <para>c:\windows\system32\inetsrv</para>
							 | 
						|
								        /// </summary>
							 | 
						|
								        private static string CurrentDirectory
							 | 
						|
								        {
							 | 
						|
								            get { return Directory.GetCurrentDirectory(); } // System.Environment.CurrentDirectory
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>
							 | 
						|
								        /// <para>System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName</para>
							 | 
						|
								        /// <para>c:\windows\system32\inetsrv\w3wp.exe</para>
							 | 
						|
								        /// </summary>
							 | 
						|
								        private static string ProcessMainModule
							 | 
						|
								        {
							 | 
						|
								            get { return Process.GetCurrentProcess().MainModule.FileName; }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>捕获异常。</summary>
							 | 
						|
								        /// <exception cref="ArgumentNullException" />
							 | 
						|
								        public static void CatchException(Action<Exception> callback)
							 | 
						|
								        {
							 | 
						|
								            if (callback == null) throw new ArgumentNullException(nameof(callback));
							 | 
						|
								
							 | 
						|
								            AppDomain.CurrentDomain.UnhandledException += (s, e) => callback(e.ExceptionObject as Exception);
							 | 
						|
								#if !NET20
							 | 
						|
								            System.Threading.Tasks.TaskScheduler.UnobservedTaskException += (s, e) => callback(e.Exception);
							 | 
						|
								#endif
							 | 
						|
								#if NETFRAMEWORK
							 | 
						|
								            System.Windows.Forms.Application.SetUnhandledExceptionMode(System.Windows.Forms.UnhandledExceptionMode.CatchException);
							 | 
						|
								            System.Windows.Forms.Application.ThreadException += (s, e) => callback(e.Exception);
							 | 
						|
								#endif
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region Evaluate
							 | 
						|
								
							 | 
						|
								        /// <summary>评估 Action 的执行时间,单位为毫秒。</summary>
							 | 
						|
								        public static long Evaluate(Action action)
							 | 
						|
								        {
							 | 
						|
								            if (action == null) return 0;
							 | 
						|
								            var stopwatch = new Stopwatch();
							 | 
						|
								            stopwatch.Start();
							 | 
						|
								            action.Invoke();
							 | 
						|
								            stopwatch.Stop();
							 | 
						|
								            return stopwatch.ElapsedMilliseconds;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region Console
							 | 
						|
								
							 | 
						|
								        /// <summary>获取或设置控制台标题。</summary>
							 | 
						|
								        public static string Title
							 | 
						|
								        {
							 | 
						|
								            get { try { return Console.Title; } catch { return null; } }
							 | 
						|
								            set { try { Console.Title = value; } catch { } }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>设置在控制台中按 CTRL + C 时的方法。</summary>
							 | 
						|
								        public static void CtrlCancel(Func<bool> exit)
							 | 
						|
								        {
							 | 
						|
								            const string postfix = " - 按 CTRL + C 可安全退出";
							 | 
						|
								            var title = Title ?? "";
							 | 
						|
								            if (!title.EndsWith(postfix))
							 | 
						|
								            {
							 | 
						|
								                title = title + postfix;
							 | 
						|
								                Title = title;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            if (exit == null) return;
							 | 
						|
								            try { Console.CancelKeyPress += (s, e) => e.Cancel = !exit(); } catch { }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>调用所有公共类,创建构造函数。</summary>
							 | 
						|
								        /// <param name="assembly">要搜索类的程序集,指定为 NULL 时将获取当前程序集。</param>
							 | 
						|
								        /// <param name="catchException">
							 | 
						|
								        /// <para>指定为 TRUE 时将使用 TRY 语句捕获异常;</para>
							 | 
						|
								        /// <para>指定为 FLASE 时发生异常将可能中断执行,可用于调试。</para></param>
							 | 
						|
								        public static void InvokePublicClass(Assembly assembly = null, bool catchException = false)
							 | 
						|
								        {
							 | 
						|
								            const string Title = "Invoing Public Class";
							 | 
						|
								            RuntimeUtility.Title = Title;
							 | 
						|
								
							 | 
						|
								            var before = DateTime.Now;
							 | 
						|
								            Logger.Internals.Info(typeof(RuntimeUtility), "Started Invoke.");
							 | 
						|
								
							 | 
						|
								            var types = GetTypes(assembly ?? Assembly.GetCallingAssembly());
							 | 
						|
								            foreach (var type in types)
							 | 
						|
								            {
							 | 
						|
								                if (!type.IsClass) continue;
							 | 
						|
								                if (!type.IsPublic) continue;
							 | 
						|
								                if (!CanNew(type)) continue;
							 | 
						|
								                Logger.Internals.Info(typeof(RuntimeUtility), "Invoke " + type.FullName);
							 | 
						|
								                RuntimeUtility.Title = type.FullName;
							 | 
						|
								
							 | 
						|
								                try
							 | 
						|
								                {
							 | 
						|
								                    Activator.CreateInstance(type);
							 | 
						|
								                }
							 | 
						|
								                catch (Exception ex)
							 | 
						|
								                {
							 | 
						|
								                    var ex2 = ex.InnerException ?? ex;
							 | 
						|
								                    Logger.Internals.Exception(ex2, typeof(RuntimeUtility));
							 | 
						|
								
							 | 
						|
								                    if (!catchException) throw ex2;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								            RuntimeUtility.Title = Title;
							 | 
						|
								
							 | 
						|
								            var after = DateTime.Now;
							 | 
						|
								            var span = after - before;
							 | 
						|
								            var milli = Convert.ToInt64(span.TotalMilliseconds);
							 | 
						|
								            var duration = $"{milli / 1000D} 秒";
							 | 
						|
								
							 | 
						|
								            var result = "Finished Invoke.\n\n";
							 | 
						|
								            result += $"  Duration:  {duration}\n";
							 | 
						|
								            result += $"   Started:  {before.Lucid()}\n";
							 | 
						|
								            result += $"     Ended:  {after.Lucid()}\n";
							 | 
						|
								            Logger.Internals.Info(typeof(RuntimeUtility), result);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region System
							 | 
						|
								
							 | 
						|
								        /// <summary>结束当前进程。</summary>
							 | 
						|
								        public static void Exit()
							 | 
						|
								        {
							 | 
						|
								            Environment.Exit(0);
							 | 
						|
								            Process.GetCurrentProcess().Kill();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>当前操作系统是 Windows。</summary>
							 | 
						|
								        public static bool IsWindows
							 | 
						|
								        {
							 | 
						|
								#if NETFRAMEWORK
							 | 
						|
								            get => Environment.OSVersion.Platform == PlatformID.Win32NT;
							 | 
						|
								#else
							 | 
						|
								            get => System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows);
							 | 
						|
								#endif
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>当前操作系统是 OS X 或 macOS。</summary>
							 | 
						|
								        public static bool IsOSX
							 | 
						|
								        {
							 | 
						|
								#if NETFRAMEWORK
							 | 
						|
								            get => Environment.OSVersion.Platform == PlatformID.MacOSX;
							 | 
						|
								#else
							 | 
						|
								            get => System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX);
							 | 
						|
								#endif
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>当前操作系统是 Linux。</summary>
							 | 
						|
								        public static bool IsLinux
							 | 
						|
								        {
							 | 
						|
								#if NETFRAMEWORK
							 | 
						|
								            get => Environment.OSVersion.Platform == PlatformID.Unix;
							 | 
						|
								#else
							 | 
						|
								            get => System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux);
							 | 
						|
								#endif
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								#if NETFRAMEWORK
							 | 
						|
								
							 | 
						|
								        /// <summary>当前进程是以管理员身份运行。</summary>
							 | 
						|
								        public static bool IsAdministratorRole()
							 | 
						|
								        {
							 | 
						|
								            var identity = System.Security.Principal.WindowsIdentity.GetCurrent();
							 | 
						|
								            var principal = new System.Security.Principal.WindowsPrincipal(identity);
							 | 
						|
								
							 | 
						|
								            var result = principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
							 | 
						|
								            return result;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								        #region Exception
							 | 
						|
								
							 | 
						|
								        /// <summary>读取调用堆栈。</summary>
							 | 
						|
								        public static string[] StackTrace()
							 | 
						|
								        {
							 | 
						|
								            var trace = new StackTrace(true);
							 | 
						|
								            var frames = trace.GetFrames();
							 | 
						|
								
							 | 
						|
								            var ab = new ArrayBuilder<string>();
							 | 
						|
								            foreach (var frame in frames)
							 | 
						|
								            {
							 | 
						|
								                // 滤除当前方法。
							 | 
						|
								
							 | 
						|
								                var method = frame.GetMethod();
							 | 
						|
								                if (method == null) continue;
							 | 
						|
								
							 | 
						|
								                var type = method.DeclaringType;
							 | 
						|
								                if (type == null) continue;
							 | 
						|
								
							 | 
						|
								                var value = $"{method.DeclaringType.FullName}.{method.Name}";
							 | 
						|
								                ab.Add(value);
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            return ab.Export();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        internal static string Message(Exception ex)
							 | 
						|
								        {
							 | 
						|
								            if (ex == null) return null;
							 | 
						|
								            try
							 | 
						|
								            {
							 | 
						|
								                var message = ex.Message;
							 | 
						|
								                if (!string.IsNullOrEmpty(message)) return message;
							 | 
						|
								
							 | 
						|
								                var typeName = ex.GetType().FullName;
							 | 
						|
								                message = $"异常 <{typeName}> 包含空消息。";
							 | 
						|
								                return message;
							 | 
						|
								            }
							 | 
						|
								            catch
							 | 
						|
								            {
							 | 
						|
								                var typeName = ex.GetType().FullName;
							 | 
						|
								                return $"获取 <{typeName}> 的消息时再次发生了异常。";
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        #endregion
							 | 
						|
								
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								}
							 | 
						|
								
							 |