Common.cs 8.3 KB
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace ChangeConfigKey
{
    internal class Common
    {
        static string ConfigDir;
        static string SaveDirectory { get { return "SrcConfig"; } }
        static string BaseDIr = System.AppDomain.CurrentDomain.BaseDirectory;
        public static Dictionary<string, ConfigStruct> configlist = new Dictionary<string, ConfigStruct>();
        public static void LoadConfig()
        {
            int cnt = 1;
            ConfigDir = Path.Combine(BaseDIr, SaveDirectory);
            if (!Directory.Exists(ConfigDir))
                return;
            string[] fileslist = Directory.GetFiles(ConfigDir, "*.config");
            foreach (string file in fileslist)
            {
                string filename = Path.GetFileName(file);
                string content = File.ReadAllText(file);
                XmlDocument xd = new XmlDocument();
                bool loaderror = false;
                try
                {
                    xd.LoadXml(content);
                }
                catch (Exception e)
                {
                    //读取异常 尝试加载灾备文件
                    loaderror = true;
                    Console.WriteLine($"读取{filename}异常:{e.ToString()}");
                }

                var crt = xd["config"];
                if (crt == null)
                    continue;
                int rootver = 0;
                if (xd["config"].Attributes["ver"] != null)
                    int.TryParse(crt.Attributes["ver"].Value, out rootver);
                foreach (XmlNode item in crt.ChildNodes)
                {
                    if (item.Name.ToLower() != "item")
                        continue;
                    if (item.Attributes["key"] == null || item.Attributes["value"] == null)
                        continue;
                    string key = item.Attributes["key"].Value;
                    string value = item.Attributes["value"].Value;

                    int ver = rootver;
                    if (item.Attributes["ver"] != null)
                        int.TryParse(item.Attributes["ver"].Value, out ver);

                    string Comment = "";
                    if (item.PreviousSibling != null && item.PreviousSibling.NodeType == XmlNodeType.Comment)
                    {
                        Comment = item.PreviousSibling.InnerText;
                    }

                    if (configlist.ContainsKey(key))
                    {
                        if (configlist[key].configVer >= ver) continue;

                        configlist[key].configVer = ver;
                        configlist[key].configFile = filename;
                        configlist[key].Value = value;
                        configlist[key].Comment = Comment;
                    }
                    else
                    {
                        var cs = new ConfigStruct();
                        cs.configFile = filename;
                        cs.Key = key;
                        cs.Value = value;
                        cs.configVer = ver;
                        cs.Comment = Comment;
                        configlist.Add(key, cs);
                        Console.WriteLine($"读取原配置[{cnt++}]:{key}={value}");
                    }
                }

                if (!loaderror)
                {
                    //File.Delete(file);
                }
            }
        }
        /// <summary>
        /// 读取配置
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="key">key</param>
        /// <param name="defaultvalue">失败默认值</param>
        /// <returns></returns>
        public static bool Get<T>(string key, out T val)
        {
            val = default(T);
            if (string.IsNullOrEmpty(key))
                return false;
            if (configlist.ContainsKey(key))
            {
                configlist[key].type = typeof(T);
                val = (T)TypeDataProcess(typeof(T), configlist[key].Value.ToString(), (object)default(T));
                configlist.Remove(key);
                Console.WriteLine($"获取到值:{key}={val}");
                return true;
            }
            else
            {
                return false;
            }
        }

        static object TypeDataProcess(Type t, string data, object defaultvalue)
        {
            string tname = t.Name;
            if (tname == "String")
            {
                if (data == null)
                    data = defaultvalue.ToString();
                return (object)data.ToString();
            }
            else if (tname == "Color")
            {
                return (object)System.Drawing.Color.FromName(data);
            }
            else if (t.BaseType != null && t.BaseType.Name == "Enum")
            {
                try
                {
                    return (object)Enum.Parse(t, data.ToString());
                }
                catch
                {
                    return (object)Enum.Parse(t, Enum.GetNames(t)[0]);
                }
            }
            else if (tname == "Object")
            {
                return data;
            }
            else if (tname == "String[]")
            {
                return data.Split(new char[] { '\n' });
            }
            else if (tname == "Point")
            {
                return StringToPoint(data);
            }
            else if (tname == "Rectangle")
            {
                return StringToRectangle(data);
            }
            object obj = Activator.CreateInstance(t);
            MethodInfo method = t.GetMethod("TryParse", new Type[] { typeof(String), t.MakeByRefType() });
            if (method != null)
            {
                if (data == null)
                {
                    return defaultvalue;
                }

                object[] parameters = new object[] { data.ToString(), null };
                bool result = (bool)method.Invoke(obj, parameters);
                if (result)
                {
                    return parameters[1];
                }
                else
                {
                    return defaultvalue;
                }
            }
            else
            {
                throw new Exception("没有找到合适的值转换方法");
            }
        }
        internal class ConfigStruct
        {
            public string configFile;
            //public string configKey;
            public string Key;
            public string Value;
            public int configVer;
            public bool haschange = false;
            public Type type = typeof(string);
            public string Comment = "";
        }
        internal static Point StringToPoint(string value)
        {
            try
            {
                value = value.Trim();
                value = value.TrimStart('{');
                value = value.TrimEnd('}');
                value = value.Trim();
                string[] parts = value.Split(',');
                var _x = parts[0].Split('=')[1].Trim();
                var _y = parts[1].Split('=')[1].Trim();
                int x = int.Parse(_x);
                int y = int.Parse(_y);
                return new Point(x, y);
            }
            catch
            {
                return Point.Empty;
            }
        }
        internal static Rectangle StringToRectangle(string value)
        {
            try
            {
                value = value.Trim();
                value = value.TrimStart('{');
                value = value.TrimEnd('}');
                value = value.Trim();
                string[] parts = value.Split(',');
                var _x = parts[0].Split('=')[1].Trim();
                var _y = parts[1].Split('=')[1].Trim();
                var _w = parts[2].Split('=')[1].Trim();
                var _h = parts[3].Split('=')[1].Trim();
                int x = int.Parse(_x);
                int y = int.Parse(_y);
                int w = int.Parse(_w);
                int h = int.Parse(_h);
                return new Rectangle(x, y, w, h);
            }
            catch
            {
                return Rectangle.Empty;
            }
        }
    }
}