diff --git a/.gitignore b/.gitignore index d9d2d92..4d1eb44 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vs/ /GeneratorCode/obj /GeneratorCode/bin/Debug +/TmatrixCodeGenerator/ \ No newline at end of file diff --git a/GeneratorCode/Configure/NConfig.cs b/GeneratorCode/Configure/NConfig.cs new file mode 100644 index 0000000..ced9a2e --- /dev/null +++ b/GeneratorCode/Configure/NConfig.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Timers; +using IniParser; +using IniParser.Model; +using JetBrains.Annotations; + +namespace GeneratorCode.Configure +{ + public static class NConfig + { + private static string _cfgFileName = @".\config.ini"; + + private static IniData _cfgData = null; + + public delegate void ConfigChangedHandle(); + + public static event ConfigChangedHandle OnConfigChanged; + + private static void ConfigChanged() + { + OnConfigChanged?.Invoke(); + } + + private static void LoadCfgFromFile() + { + try + { + if (!File.Exists(_cfgFileName)) + { + var fs = new FileStream(_cfgFileName, FileMode.Create, FileAccess.Write); + var ws = new StreamWriter(fs); + ws.WriteLine("; 应用程序配置文件\n"); + } + + FileIniDataParser iniPraser = new FileIniDataParser(); + iniPraser.Parser.Configuration.CommentString = ";"; + _cfgData = iniPraser.ReadFile(_cfgFileName); + //Trace.WriteLine(_cfgData); + } + catch (Exception e) + { + Trace.WriteLine(e.Message); + } + } + + public static void InitConfigure() + { + var cfgTask = new List(); + var appPath = Process.GetCurrentProcess().MainModule.FileName; + + Trace.WriteLine("Application: " + appPath); + Trace.WriteLine("Directory: " + Path.GetDirectoryName(appPath)); + Trace.WriteLine("File: " + Path.GetFileName(appPath)); + + var fw = new FileSystemWatcher(@"E:\", @"my.cfg") + { + NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite, + //Filter = _cfgFileName, + //Path = Path.GetDirectoryName(appPath), + IncludeSubdirectories = false, + }; + + fw.Changed += (sender, e) => + { + //if (Path.GetFileName(appPath) != _cfgFileName) return; + + lock (cfgTask) + { + if (cfgTask.Contains(e.FullPath)) return; + + cfgTask.Add(e.FullPath); + } + + var tm = new Timer(1000) { AutoReset = false }; + + tm.Elapsed += (obj, args) => + { + lock (cfgTask) + { + cfgTask.Remove(e.FullPath); + LoadCfgFromFile(); + ConfigChanged(); + // LogOut("File: " + e.FullPath + " ==> " + e.ChangeType.ToString() + "\n"); + } + }; + + tm.Start(); + }; + + fw.EnableRaisingEvents = true; + + LoadCfgFromFile(); + } + + public static T GetCfgValue([NotNull] string secName, [NotNull] string keyName, T defValue = default(T)) + { + var ret = defValue; + + if (_cfgData.Equals(null)) + { + return ret; + } + + try + { + ret = (T) Convert.ChangeType(_cfgData[secName][keyName], typeof(T)); + } + catch(Exception e) + { + Trace.WriteLine("[" + _cfgData[secName][keyName] + "] :" + e.Message); + ret = defValue; + throw(e); + } + + return ret; + } + } +} diff --git a/GeneratorCode/GeneratorCode.csproj b/GeneratorCode/GeneratorCode.csproj index 13b3f3c..6cd812b 100644 --- a/GeneratorCode/GeneratorCode.csproj +++ b/GeneratorCode/GeneratorCode.csproj @@ -34,6 +34,9 @@ 4 + + ..\packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll + Libs\itextsharp.dll @@ -53,7 +56,8 @@ - + + @@ -75,7 +79,7 @@ PreserveNewest - + PreserveNewest diff --git a/GeneratorCode/Logs/NLog.cs b/GeneratorCode/Logs/NLog.cs new file mode 100644 index 0000000..f242547 --- /dev/null +++ b/GeneratorCode/Logs/NLog.cs @@ -0,0 +1,491 @@ +using System; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading; +using GeneratorCode.Configure; +using JetBrains.Annotations; + +namespace GeneratorCode.Logs +{ + public enum NLogLevel + { + Fatal = 0, + Crash, + Error, + Warring, + Info, + Debug, + MaxLevel + } + + public enum CacheOptMode + { + Drop = 0, + Replease + } + + public class NLogConfig + { + private object _cfgLock = new object(); + public delegate void LogCfgChangedHandle(); + + public static event LogCfgChangedHandle OnLogCfgChanged; + + public NLogConfig() + { + LogConfig(); + NConfig.OnConfigChanged += () => { LogCfgChanged(); }; + } + + protected static void LogCfgChanged() + { + OnLogCfgChanged?.Invoke(); + } + + public NLogLevel LogLevel { get; set; } + public NLogLevel DefaultLevel { get; set; } + public bool AsyncMode { get; set; } + public bool ForceNewLine { get; set; } + + public bool EnConsole { get; set; } + public bool EnTrace { get; set; } + public bool EnDebug { get; set; } + public bool EnFile { get; set; } + + + public int MaxItemsCache { get; set; } + public CacheOptMode CacheMode { get; set; } + public int SleepTime { get; set; } + public int NumOutItems { get; set; } + + public string Path { get; set; } + public string FileNamePre { get; set; } + public bool EnSplitLog { get; set; } + public bool SplitByData { get; set; } + public int SplitBySize { get; set; } + public bool RoolbackFile { get; set; } + public int MaxFileNum { get; set; } + + public void LogConfig() + { + lock (_cfgLock) + { + LogLevel = (NLogLevel)NConfig.GetCfgValue("LogGlobal", "LogLevel", (int)NLogLevel.MaxLevel); + DefaultLevel = (NLogLevel)NConfig.GetCfgValue("LogGlobal", "DefaultLogLevel", (int)NLogLevel.Info); + AsyncMode = NConfig.GetCfgValue("LogGlobal", "AsyncMode", false); + ForceNewLine = NConfig.GetCfgValue("LogGlobal", "AutoForceNewLine", false); + + EnConsole = NConfig.GetCfgValue("LogOutput", "Console", true); + EnTrace = NConfig.GetCfgValue("LogOutput", "Trace", false); + EnDebug = NConfig.GetCfgValue("LogOutput", "Debug", true); + EnFile = NConfig.GetCfgValue("LogOutput", "File", false); + + if (AsyncMode) + { + MaxItemsCache = NConfig.GetCfgValue("AsyncLogSetting", "MaxItemsCache", 0); + + if (MaxItemsCache == 0) MaxItemsCache = int.MaxValue; + + CacheMode = (CacheOptMode)NConfig.GetCfgValue("AsyncLogSetting", "CacheFullOpts", (int)CacheOptMode.Drop); + SleepTime = NConfig.GetCfgValue("AsyncLogSetting", "ThreadSleep", 10); + NumOutItems = NConfig.GetCfgValue("AsyncLogSetting", "NumItemsOutEachTime", 10); + } + + if (EnFile) + { + Path = NConfig.GetCfgValue("FileLogSetting", "Path", @"./"); + FileNamePre = NConfig.GetCfgValue("FileLogSetting", "FileNamePrefix", ""); + EnSplitLog = NConfig.GetCfgValue("FileLogSetting", "AutoSplitFile", true); + + if (EnSplitLog) + { + SplitByData = NConfig.GetCfgValue("SplitFiles", "SplitByDate", true); + SplitBySize = NConfig.GetCfgValue("SplitFiles", "SplitBySize", 4); + RoolbackFile = NConfig.GetCfgValue("SplitFiles", "FileNameRollback", true); + MaxFileNum = NConfig.GetCfgValue("SplitFiles", "MaxFileNameNum", 10); + } + } + } + } + } + + public class NLogItem + { + public NLogItem(NLogLevel level = NLogLevel.Debug, + [NotNull] string logContent = "", + [NotNull] string fileName = "", + [NotNull] string funName = "", + int lineNo = 0, + DateTime? dt = null) + { + if (dt == null) + { + LogStamp = DateTime.Now; + } + else + { + LogStamp = (DateTime)dt; + } + + LogLevel = level; + LogContent = logContent; + CodeFile = fileName; + CodeFunction = funName; + CodeLine = lineNo; + } + + public DateTime LogStamp { get; set; } + public NLogLevel LogLevel { get; set; } + public string LogContent { get; set; } + public string CodeFile { get; set; } + public int CodeLine { get; set; } + public string CodeFunction { get; set; } + } + + public static class NLog + { + private static NLogConfig _logCfg; + private static readonly ConcurrentQueue _logItemCollection = new ConcurrentQueue(); + private static readonly object _logOutputLock = new object(); + private static string _logFileName = ""; + private static uint _logFileNum = 0; + private static StreamWriter _logSw = null; + + private static void CreateLogFileHead() + { + _logSw?.WriteLine("FileName: " + _logFileName); + _logSw?.WriteLine("CreateTime: " + string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now)); + _logSw?.WriteLine("Program: " + Process.GetCurrentProcess().MainModule.FileName); + _logSw?.WriteLine("PID: " + Process.GetCurrentProcess().Id); + _logSw?.WriteLine("Split Count: " + (_logFileNum - 1).ToString()); + _logSw?.WriteLine("--------------------------------------------------"); + _logSw?.Flush(); + } + + private static void ConfigInit() + { + if (_logCfg.EnFile) + { + _logFileName = string.Format("{0}{1}[{3:yyyy-MM-dd_HH-mm}][{4:d}]_{2}", + _logCfg.Path, + _logCfg.FileNamePre.Length > 0 ? _logCfg.FileNamePre + "_" : "", + Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName), + DateTime.Now, + Process.GetCurrentProcess().Id); + + if (_logCfg.EnSplitLog && _logCfg.RoolbackFile && _logCfg.MaxFileNum > 0) + { + _logFileName += $"_{_logFileNum:d3}"; + _logFileNum = Convert.ToUInt32((_logFileNum + 1) % _logCfg.MaxFileNum); + } + + _logFileName += ".log"; + + if (File.Exists(_logFileName)) + { + if (_logCfg.EnSplitLog) + { + File.Delete(_logFileName); + } + } + + _logSw = new StreamWriter(_logFileName, true); + CreateLogFileHead(); + } + } + + public static void NLog_Init() + { + _logCfg = new NLogConfig(); + + NLogConfig.OnLogCfgChanged += () => + { + _logSw?.Close(); + + _logCfg.LogConfig(); + + ConfigInit(); + }; + + ConfigInit(); + + var asynWork = new Thread(() => + { + uint cnt = 0; + + while (true) + { + var lastDt = DateTime.Now; + var tolOut = Math.Min(_logCfg.NumOutItems, _logItemCollection.Count); + + foreach (var val in Enumerable.Range(1, tolOut)) + { + if (_logItemCollection.TryDequeue(out var logItem)) + { + LogOutput(logItem); + } + } + + Thread.Sleep(_logCfg.SleepTime); + + // 每秒执行一次维护工作 + if ((++cnt % (1000 / _logCfg.SleepTime)) != 0) + { + continue; + } + + _logSw?.Flush(); + + if (_logCfg.EnSplitLog) + { + bool isNeedSplit = true; + + if (_logCfg.SplitByData && lastDt.Day != DateTime.Now.Day) + { + isNeedSplit = true; + } + else if (_logCfg.SplitBySize > 0 && (new FileInfo(_logFileName)).Length > _logCfg.SplitBySize * (1024 * 1024)) + { + isNeedSplit = true; + } + + if (isNeedSplit) + { + _logSw?.Close(); + _logSw?.Dispose(); + _logSw = null; + + string parttn = string.Format("*[{0:d3}]_{1}", + Process.GetCurrentProcess().Id, + Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName)); + + _logFileName = string.Format("{0}{1}[{3:yyyy-MM-dd_HH-mm}][{4:d}]_{2}", + _logCfg.Path, + _logCfg.FileNamePre.Length > 0 ? _logCfg.FileNamePre + "_" : "", + Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName), + DateTime.Now, + Process.GetCurrentProcess().Id); + + if (_logCfg.EnSplitLog && _logCfg.RoolbackFile && _logCfg.MaxFileNum > 0) + { + _logFileName += $"_{_logFileNum:d3}"; + parttn += $"_{_logFileNum:d3}"; + _logFileNum = Convert.ToUInt32((_logFileNum + 1) % _logCfg.MaxFileNum); + } + + _logFileName += ".log"; + parttn += ".log"; + + foreach (var f in Directory.GetFiles(_logCfg.Path, parttn, SearchOption.TopDirectoryOnly)) + { + File.Delete(f); + Trace.WriteLine("Delect Rollback log: " + f); + } + + _logSw = new StreamWriter(_logFileName, true); + CreateLogFileHead(); + } + } + } + }) + { + Name = "Log Async Output Thread", + IsBackground = true + }; + + asynWork.Start(); + } + + private static string LogLevelToString([NotNull] NLogLevel logLevel) + { + string[] level = { "F", "C", "E", "I", "W", "D" }; + + if ((int) logLevel < level.Length && (int) logLevel >= 0) + return level[(int) logLevel]; + return "U"; + } + + private static string LogFormat(NLogLevel logLevel, string logMsg, string fileName, string funName, int lineNo, + DateTime dt) + { + var msg = "[" + dt.ToString("yyyy-MM-dd HH:mm:ss.fff") + + "] [" + LogLevelToString(logLevel) + "] [" + Path.GetFileName(fileName) + "] - " + + funName + "(" + lineNo + "):" + logMsg; + return msg; + } + + private static void LogOutput(NLogItem logItem) + { + var msg = LogFormat(logItem.LogLevel, + logItem.LogContent, + logItem.CodeFile, + logItem.CodeFunction, + logItem.CodeLine, + logItem.LogStamp); + + if (_logCfg.ForceNewLine) + { + msg += Environment.NewLine; + } + + lock (_logOutputLock) + { + if (_logCfg.EnConsole) Console.Write(msg); + + if (_logCfg.EnDebug | _logCfg.EnTrace) + { + if (_logCfg.EnTrace) + Trace.Write(msg); + else + System.Diagnostics.Debug.WriteLine(msg); + } + + if (_logCfg.EnFile) + { + _logSw?.Write(msg); + } + } + } + + private static void LogOutput2(string logMsg) + { + lock (_logOutputLock) + { + if (_logCfg.EnConsole) Console.Write(logMsg); + + if (_logCfg.EnDebug | _logCfg.EnTrace) + { + if (_logCfg.EnTrace) + Trace.Write(logMsg); + else + System.Diagnostics.Debug.WriteLine(logMsg); + } + + if (_logCfg.EnFile) + { + _logSw?.Write(logMsg); + } + } + } + + public static void LogOut([NotNull] string logMsg = "", + [CallerFilePath] string fileName = "", + [CallerMemberName] string funName = "", + [CallerLineNumber] int lineNo = 0) + { + if (NLogLevel.Debug >= _logCfg.LogLevel) return; + + if (_logCfg.AsyncMode) + { + if (_logItemCollection.Count >= _logCfg.MaxItemsCache) + { + if (_logCfg.CacheMode == CacheOptMode.Drop) + { + return; + } + else + { + NLogItem val; + _logItemCollection.TryDequeue(out val); + } + } + + var logItem = new NLogItem(_logCfg.DefaultLevel, logMsg, fileName, funName, lineNo, DateTime.Now); + _logItemCollection.Enqueue(logItem); + } + else + { + var logItem = new NLogItem(_logCfg.DefaultLevel, logMsg, fileName, funName, lineNo, DateTime.Now); + LogOutput(logItem); + } + } + + public static void LogOut(NLogLevel logLevel = NLogLevel.Info, + [NotNull] string logMsg = "", + [CallerFilePath] string fileName = "", + [CallerMemberName] string funName = "", + [CallerLineNumber] int lineNo = 0) + { + if (logLevel >= _logCfg.LogLevel) return; + + if (_logCfg.AsyncMode) + { + if (_logItemCollection.Count >= _logCfg.MaxItemsCache) + { + if (_logCfg.CacheMode == CacheOptMode.Drop) + { + return; + } + else + { + NLogItem val; + _logItemCollection.TryDequeue(out val); + } + } + + var logItem = new NLogItem(NLogLevel.Debug, logMsg, fileName, funName, lineNo, DateTime.Now); + _logItemCollection.Enqueue(logItem); + } + else + { + var logItem = new NLogItem(NLogLevel.Debug, logMsg, fileName, funName, lineNo, DateTime.Now); + LogOutput(logItem); + } + } + + #region LogOutputMethod + + public static void Debug([NotNull] string logMsg = "", + [CallerFilePath] string fileName = "", + [CallerMemberName] string funName = "", + [CallerLineNumber] int lineNo = 0) + { + LogOut(NLogLevel.Debug, logMsg, fileName, funName, lineNo); + } + + public static void Warring([NotNull] string logMsg = "", + [CallerFilePath] string fileName = "", + [CallerMemberName] string funName = "", + [CallerLineNumber] int lineNo = 0) + { + LogOut(NLogLevel.Warring, logMsg, fileName, funName, lineNo); + } + + public static void Info([NotNull] string logMsg = "", + [CallerFilePath] string fileName = "", + [CallerMemberName] string funName = "", + [CallerLineNumber] int lineNo = 0) + { + LogOut(NLogLevel.Info, logMsg, fileName, funName, lineNo); + } + + public static void Error([NotNull] string logMsg = "", + [CallerFilePath] string fileName = "", + [CallerMemberName] string funName = "", + [CallerLineNumber] int lineNo = 0) + { + LogOut(NLogLevel.Error, logMsg, fileName, funName, lineNo); + } + + public static void Crash([NotNull] string logMsg = "", + [CallerFilePath] string fileName = "", + [CallerMemberName] string funName = "", + [CallerLineNumber] int lineNo = 0) + { + LogOut(NLogLevel.Crash, logMsg, fileName, funName, lineNo); + } + + public static void Fatal([NotNull] string logMsg = "", + [CallerFilePath] string fileName = "", + [CallerMemberName] string funName = "", + [CallerLineNumber] int lineNo = 0) + { + LogOut(NLogLevel.Fatal, logMsg, fileName, funName, lineNo); + } + + #endregion + } +} diff --git a/GeneratorCode/NLog.cs b/GeneratorCode/NLog.cs deleted file mode 100644 index 059a633..0000000 --- a/GeneratorCode/NLog.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Timers; -using JetBrains.Annotations; - -namespace GeneratorCode -{ - public enum NLogLevel - { - Fatal = 0, - Error, - Info, - Warring, - Debug - } - - public class LogConfigInfo : ConfigurationSection - { - [ConfigurationProperty("logLevel")] public int logLevel => int.Parse(string.Format("{0}", base["logLevel"])); - } - - public class NLog - { - public NLog() - { - var cfgTask = new List(); - - var fw = new FileSystemWatcher - { - NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite, - Filter = "my.cfg", - IncludeSubdirectories = false, - Path = @"E:\" - }; - - fw.Changed += (sender, e) => - { - lock (cfgTask) - { - if (cfgTask.Contains(e.FullPath)) return; - - cfgTask.Add(e.FullPath); - } - - var tm = new Timer(1000) { AutoReset = false }; - - tm.Elapsed += (obj, args) => - { - lock (cfgTask) - { - cfgTask.Remove(e.FullPath); - LogOut("File: " + e.FullPath + " ==> " + e.ChangeType.ToString() + "\n"); - var cfgMap = new ExeConfigurationFileMap - { - ExeConfigFilename = @".\log.config" - }; - - try - { - var v = ConfigurationManager.OpenMappedExeConfiguration(cfgMap, - ConfigurationUserLevel.None); - - var cfgGrp = v.GetSection("global") as LogConfigInfo; - - Trace.WriteLine("LogLevel: [" + cfgGrp.logLevel.ToString() + "]"); - } - catch (Exception exception) - { - Trace.WriteLine(exception.Message); - } - } - }; - - tm.Start(); - }; - - //FileSystemWatcher fw = new FileSystemWatcher(@"E:\", "*.cfg"); - - //fw.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.LastAccess | NotifyFilters.FileName; - ; - //fw.Changed += new FileSystemEventHandler(OnFileChanged); - //fw.Created += new FileSystemEventHandler(OnFileChanged); - //fw.Deleted += new FileSystemEventHandler(OnFileChanged); - - fw.EnableRaisingEvents = true; - } - - private string LogLevelToString([NotNull] NLogLevel logLevel) - { - string[] level = { "F", "E", "I", "W", "D" }; - - if ((int) logLevel < level.Length && (int) logLevel >= 0) - return level[(int) logLevel]; - return "U"; - } - - private string LogFormat(NLogLevel logLevel, string logMsg, string fileName, string funName, int lineNo) - { - var msg = "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") - + "] [" + LogLevelToString(logLevel) + "] [" + Path.GetFileName(fileName) + "] - " - + funName + "(" + lineNo + "):" + logMsg; - return msg; - } - - private void LogOutput(string logMsg) - { - var thisLock = new object(); - - lock (thisLock) - { - Console.Write(logMsg); - Trace.Write(logMsg); - } - } - - public void LogOut([NotNull] string logMsg = "", - [CallerFilePath] string fileName = "", - [CallerMemberName] string funName = "", - [CallerLineNumber] int lineNo = 0) - { - var msg = LogFormat(NLogLevel.Debug, logMsg, fileName, funName, lineNo); - LogOutput(msg); - } - - public void LogOut(NLogLevel logLevel = NLogLevel.Info, - [NotNull] string logMsg = "", - [CallerFilePath] string fileName = "", - [CallerMemberName] string funName = "", - [CallerLineNumber] int lineNo = 0) - { - var msg = LogFormat(logLevel, logMsg, fileName, funName, lineNo); - LogOutput(msg); - } - - public void Debug([NotNull] string logMsg = "", - [CallerFilePath] string fileName = "", - [CallerMemberName] string funName = "", - [CallerLineNumber] int lineNo = 0) - { - LogOut(NLogLevel.Debug, logMsg, fileName, funName, lineNo); - } - - public void Warring([NotNull] string logMsg = "", - [CallerFilePath] string fileName = "", - [CallerMemberName] string funName = "", - [CallerLineNumber] int lineNo = 0) - { - LogOut(NLogLevel.Warring, logMsg, fileName, funName, lineNo); - } - - public void Info([NotNull] string logMsg = "", - [CallerFilePath] string fileName = "", - [CallerMemberName] string funName = "", - [CallerLineNumber] int lineNo = 0) - { - LogOut(NLogLevel.Info, logMsg, fileName, funName, lineNo); - } - - public void Error([NotNull] string logMsg = "", - [CallerFilePath] string fileName = "", - [CallerMemberName] string funName = "", - [CallerLineNumber] int lineNo = 0) - { - LogOut(NLogLevel.Error, logMsg, fileName, funName, lineNo); - } - - public void Fatal([NotNull] string logMsg = "", - [CallerFilePath] string fileName = "", - [CallerMemberName] string funName = "", - [CallerLineNumber] int lineNo = 0) - { - LogOut(NLogLevel.Fatal, logMsg, fileName, funName, lineNo); - } - } -} diff --git a/GeneratorCode/Program.cs b/GeneratorCode/Program.cs index 78807df..c077877 100644 --- a/GeneratorCode/Program.cs +++ b/GeneratorCode/Program.cs @@ -1,6 +1,9 @@ using System; using System.IO; using System.Text; +using System.Threading; +using GeneratorCode.Configure; +using GeneratorCode.Logs; using Newtonsoft.Json; using TmatrixLibrary; @@ -15,8 +18,8 @@ namespace GeneratorCode image_type = new[] { false, false, false, true }; StartPageID = 0; key = "S0,O000,B0000,P000-255,D2018/12/31;CCAFBQMXYPOAOCIRK52S8QC8SO4A0AGA8Y"; - //filePath = "E:\\NetEase\\轨迹笔\\Sample\\123.pdf"; //"C:\\Works\\pdf\\123.pdf"; - filePath = "C:\\Works\\pdf\\123.pdf"; + filePath = "E:\\NetEase\\轨迹笔\\Sample\\123.pdf"; //"C:\\Works\\pdf\\123.pdf"; + //filePath = "C:\\Works\\pdf\\123.pdf"; sessionId = "4BD5D923-47EA-4DEF-A1CD-9B85B515B191"; } @@ -99,7 +102,10 @@ namespace GeneratorCode { private static int Main(string[] args) { - GeneratorParams inParams; + NConfig.InitConfigure(); + NLog.NLog_Init(); + //NLog myLog = new NLog(); + GeneratorParams inParams = null; RspMessage rspMsg; var tmObj = new TmatrixClass(); @@ -116,7 +122,7 @@ namespace GeneratorCode // "ZUE9BT0NJUks1MlM4UUM4U080QTBBR0E4WSIsImZpbGVQYXRoIjoiQzpc" + // "XFdvcmtzXFxwZGZcXDEyMy5wZGYiLCJTdGFydFBhZ2VJRCI6MCwic2Vzc" + // "2lvbklkIjoiNEJENUQ5MjMtNDdFQS00REVGLUExQ0QtOUI4NUI1MTVCMTkxIn0="; - + try { if (args.Length == 1) @@ -142,6 +148,7 @@ namespace GeneratorCode rspMsg = new RspMessage(""); var msg = rspMsg.FormatRspMessage(10, e.Message, 0); RspMessage.SendRspMessage(msg); + NLog.Crash(string.Format("[{0}]: ", (inParams == null) ? inParams.sessionId : "UnInit") + e.Message); return -(int) ErrCode.ERR_JSON_DECODE; } @@ -151,9 +158,11 @@ namespace GeneratorCode var jsInput = JsonConvert.SerializeObject(inParams); - Console.WriteLine("Input:\n" + jsInput); + NLog.Debug("Input:\n" + jsInput); //Console.WriteLine("Input:\n" + Convert.ToBase64String(Encoding.Default.GetBytes(jsInput))); + Console.Read(); + return 0; if (!File.Exists(inParams.filePath)) return -(int) ErrCode.ERR_FILE_NOTEXISTS; try diff --git a/GeneratorCode/config.ini b/GeneratorCode/config.ini new file mode 100644 index 0000000..a7d8690 --- /dev/null +++ b/GeneratorCode/config.ini @@ -0,0 +1,57 @@ +; 应用程序配置文件 + +;--------------------------------------- +; Log 相关配置 +; +[LogGlobal] +; log 打印等级 +LogLevel = 255 +; 默认日志打印等级 +DefaultLogLevel = 4 +; 使用异步日志输出模式,默认false +AsyncMode = true +; 是否在每条日志后加入换行 +AutoForceNewLine = false + +; 日志输出配置 +[LogOutput] +; 是否允许控制台输出, 默认 true +Console = true +; 是否允许在 Visual Studio 调试器中输出(Release 版本), 默认 false +Trace = true +; 是否允许在 Visual Studio 调试器中输出(Debug 版本), 默认 false +Debug = false +; 是否允许在文件中输出, 默认 false +File = true + +; 异步输出模式配置 +[AsyncLogSetting] +; 日志最大缓冲条数, 0:无限制 +MaxItemsCache = 1000 +; 日志缓存满后处理方法:0:丢弃, 1:覆盖最早一条 +CacheFullOpts = 0 +; 线程每次输出完成后休眠时间(毫秒) +ThreadSleep = 10 +; 线程每次最多处理日志条数 +NumItemsOutEachTime = 10 + +; 文件日志配置 +[FileLogSetting] +; 日志创建目录 +Path = .\ +; 日志文件名格式 +FileNamePrefix = +; 是否自动分割日志文件 +AutoSplitFile = true + +; 日志文件分割配置 +[SplitFiles] +; 是否根据日期改变自动创建新的日志文件 +SplitByDate = true +; 是否根据日志大小自动创建日志文件: +; 0:不需要, 大于0:日志大于(字节)后自动创建新文件 +SplitBySize = 4 +; 是否启动日志文件名自动回滚功能 +FileNameRollback = true +; 日志文件名回滚最大文件数 +MaxFileNameNum = 10 \ No newline at end of file diff --git a/GeneratorCode/log.config b/GeneratorCode/log.config deleted file mode 100644 index b4e5172..0000000 --- a/GeneratorCode/log.config +++ /dev/null @@ -1,7 +0,0 @@ - - - -
- - - \ No newline at end of file diff --git a/GeneratorCode/packages.config b/GeneratorCode/packages.config index 7f83af3..4f35d8e 100644 --- a/GeneratorCode/packages.config +++ b/GeneratorCode/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/TmatrixCodeGenerator/obj/Debug/TmatrixSDK_OID4.csprojAssemblyReference.cache b/TmatrixCodeGenerator/obj/Debug/TmatrixSDK_OID4.csprojAssemblyReference.cache index 0b24726..be8a7d6 100644 Binary files a/TmatrixCodeGenerator/obj/Debug/TmatrixSDK_OID4.csprojAssemblyReference.cache and b/TmatrixCodeGenerator/obj/Debug/TmatrixSDK_OID4.csprojAssemblyReference.cache differ diff --git a/packages/ini-parser.2.5.2/.signature.p7s b/packages/ini-parser.2.5.2/.signature.p7s new file mode 100644 index 0000000..d2a845c Binary files /dev/null and b/packages/ini-parser.2.5.2/.signature.p7s differ diff --git a/packages/ini-parser.2.5.2/ini-parser.2.5.2.nupkg b/packages/ini-parser.2.5.2/ini-parser.2.5.2.nupkg new file mode 100644 index 0000000..01037a4 Binary files /dev/null and b/packages/ini-parser.2.5.2/ini-parser.2.5.2.nupkg differ diff --git a/packages/ini-parser.2.5.2/lib/net20/INIFileParser.dll b/packages/ini-parser.2.5.2/lib/net20/INIFileParser.dll new file mode 100644 index 0000000..d19e920 Binary files /dev/null and b/packages/ini-parser.2.5.2/lib/net20/INIFileParser.dll differ diff --git a/packages/ini-parser.2.5.2/lib/net20/INIFileParser.dll.mdb b/packages/ini-parser.2.5.2/lib/net20/INIFileParser.dll.mdb new file mode 100644 index 0000000..3c8c37e Binary files /dev/null and b/packages/ini-parser.2.5.2/lib/net20/INIFileParser.dll.mdb differ diff --git a/packages/ini-parser.2.5.2/lib/net20/INIFileParser.xml b/packages/ini-parser.2.5.2/lib/net20/INIFileParser.xml new file mode 100644 index 0000000..7d5e96b --- /dev/null +++ b/packages/ini-parser.2.5.2/lib/net20/INIFileParser.xml @@ -0,0 +1,1181 @@ + + + + INIFileParser + + + + + Asserts that a strings has no blank spaces. + + The string to be checked. + + + + + Represents an INI data parser for files. + + + + + Ctor + + + + + Ctor + + + + + + Implements reading ini data from a file. + + + Uses codification for the file. + + + Path to the file + + + + + Implements reading ini data from a file. + + + Path to the file + + + File's encoding. + + + + + Saves INI data to a file. + + + Creats an ASCII encoded file by default. + + + Path to the file. + + + IniData to be saved as an INI file. + + + + + Writes INI data to a text file. + + + Path to the file. + + + IniData to be saved as an INI file. + + + Specifies the encoding used to create the file. + + + + + Represents all data from an INI file + + + + + Represents all sections from an INI file + + + + + Initializes an empty IniData instance. + + + + + Initializes a new IniData instance using a previous + . + + + object containing the + data with the sections of the file + + + + + Configuration used to write an ini file with the proper + delimiter characters and data. + + + If the instance was created by a parser, + this instance is a copy of the used + by the parser (i.e. different objects instances) + If this instance is created programatically without using a parser, this + property returns an instance of + + + + + Global sections. Contains key/value pairs which are not + enclosed in any section (i.e. they are defined at the beginning + of the file, before any section. + + + + + Gets the instance + with the specified section name. + + + + + Gets or sets all the + for this IniData instance. + + + + + Used to mark the separation between the section name and the key name + when using . + + + Defaults to '.'. + + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + + + + See property for more information. + + + + + Deletes all comments in all sections and key values + + + + + Merges the other iniData into this one by overwriting existing values. + Comments get appended. + + + IniData instance to merge into this. + If it is null this operation does nothing. + + + + + Attempts to retrieve a key, using a single string combining section and + key name. + + + The section and key name to retrieve, separated by . + + If key contains no separator, it is treated as a key in the section. + + Key may contain no more than one separator character. + + + If true is returned, is set to the value retrieved. Otherwise, is set + to an empty string. + + + True if key was found, otherwise false. + + + key contained multiple separators. + + + + + Retrieves a key using a single input string combining section and key name. + + + The section and key name to retrieve, separated by . + + If key contains no separator, it is treated as a key in the section. + + Key may contain no more than one separator character. + + + The key's value if it was found, otherwise null. + + + key contained multiple separators. + + + + + Merge the sections into this by overwriting this sections. + + + + + Merges the given global values into this globals by overwriting existing values. + + + + + Information associated to a key from an INI file. + Includes both the value and the comments associated to the key. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + from a previous instance of . + + + Data is deeply copied + + + The instance of the class + used to create the new instance. + + + + + Gets or sets the comment list associated to this key. + + + + + Gets or sets the value associated to this key. + + + + + Gets or sets the name of the key. + + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + + + + Represents a collection of Keydata. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with a given + search comparer + + + Search comparer used to find the key by name in the collection + + + + + Initializes a new instance of the class + from a previous instance of . + + + Data from the original KeyDataCollection instance is deeply copied + + + The instance of the class + used to create the new instance. + + + + + Gets or sets the value of a concrete key. + + + If we try to assign the value of a key which doesn't exists, + a new key is added with the name and the value is assigned to it. + + + Name of the key + + + The string with key's value or null if the key was not found. + + + + + Return the number of keys in the collection + + + + + + Adds a new key to the collection + + + KeyData instance. + + + true if the key was added false if a key with the same name already exist + in the collection + + + + + Adds a new key with the specified name and value to the collection + + + Name of the new key to be added. + + + Value associated to the key. + + + true if the key was added false if a key with the same name already exist + in the collection. + + + + + Clears all comments of this section + + + + + Gets if a specifyed key name exists in the collection. + + Key name to search + true if a key with the specified name exists in the collectoin + false otherwise + + + + Retrieves the data for a specified key given its name + + Name of the key to retrieve. + + A instance holding + the key information or null if the key wasn't found. + + + + + Deletes all keys in this collection. + + + + + Deletes a previously existing key, including its associated data. + + The key to be removed. + + true if a key with the specified name was removed + false otherwise. + + + + + Sets the key data associated to a specified key. + + The new for the key. + + + + Allows iteration througt the collection. + + A strong-typed IEnumerator + + + + Implementation needed + + A weak-typed IEnumerator. + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + + + + Collection of KeyData for a given section + + + + + Information associated to a section in a INI File + Includes both the value and the comments associated to the key. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + from a previous instance of . + + + Data is deeply copied + + + The instance of the class + used to create the new instance. + + + Search comparer. + + + + + Deletes all comments in this section and key/value pairs + + + + + Deletes all the key-value pairs in this section. + + + + + Merges otherSection into this, adding new keys if they don't exists + or overwriting values if the key already exists. + Comments get appended. + + + Comments are also merged but they are always added, not overwritten. + + + + + + Gets or sets the name of the section. + + + The name of the section + + + + + Gets or sets the comment list associated to this section. + + + A list of strings. + + + + + Gets or sets the keys associated to this section. + + + A collection of KeyData objects. + + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + + + + Represents a collection of SectionData. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + + StringComparer used when accessing section names + + + + + Initializes a new instance of the class + from a previous instance of . + + + Data is deeply copied + + + The instance of the class + used to create the new instance. + + + + Returns the number of SectionData elements in the collection + + + + + Gets the key data associated to a specified section name. + + An instance of as class + holding the key data from the current parsed INI data, or a null + value if the section doesn't exist. + + + + Creates a new section with empty data. + + + If a section with the same name exists, this operation has no effect. + + Name of the section to be created + true if the a new section with the specified name was added, + false otherwise + If the section name is not valid. + + + + Adds a new SectionData instance to the collection + + Data. + + + + Removes all entries from this collection + + + + + Gets if a section with a specified name exists in the collection. + + Name of the section to search + + true if a section with the specified name exists in the + collection false otherwise + + + + + Returns the section data from a specify section given its name. + + Name of the section. + + An instance of a class + holding the section data for the currently INI data + + + + + Sets the section data for given a section name. + + + The new instance. + + + + + + + true if the section with the specified name was removed, + false otherwise + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + + + + Data associated to this section + + + + + Configuration used to write an ini file with the proper + delimiter characters and data. + + + If the instance was created by a parser, + this instance is a copy of the used + by the parser (i.e. different objects instances) + If this instance is created programatically without using a parser, this + property returns an instance of + + + + + Formats a IniData structure to an string + + + + + Produces an string given + + The data to string. + Ini data. + + + + Configuration used by this formatter when converting IniData + to an string + + + + + Represents all data from an INI file exactly as the + class, but searching for sections and keys names is done with + a case insensitive search. + + + + + Initializes an empty IniData instance. + + + + + Initializes a new IniData instance using a previous + . + + + object containing the + data with the sections of the file + + + + + Copies an instance of the class + + Original + + + + Defines data for a Parser configuration object. + + With a configuration object you can redefine how the parser + will detect special items in the ini file by defining new regex + (e.g. you can redefine the comment regex so it just treat text as + a comment iff the comment caracter is the first in the line) + or changing the set of characters used to define elements in + the ini file (e.g. change the 'comment' caracter from ';' to '#') + You can also define how the parser should treat errors, or how liberal + or conservative should it be when parsing files with "strange" formats. + + + + Default values used if an instance of + is created without specifying a configuration. + + + By default the various delimiters for the data are setted: + ';' for one-line comments + '[' ']' for delimiting a section + '=' for linking key / value pairs + + An example of well formed data with the default values: + + ;section comment
+ [section] ; section comment
+
+ ; key comment
+ key = value ;key comment
+
+ ;key2 comment
+ key2 = value
+
+
+
+
+ + + Copy ctor. + + + Original instance to be copied. + + + + + Sets the char that defines the start of a section name. + + + Defaults to character '[' + + + + + Sets the char that defines the end of a section name. + + + Defaults to character ']' + + + + + Retrieving section / keys by name is done with a case-insensitive + search. + + + Defaults to false (case sensitive search) + + + + + Sets the char that defines the start of a comment. + A comment spans from the comment character to the end of the line. + + + Defaults to character ';' + + + + + Sets the string that defines the start of a comment. + A comment spans from the mirst matching comment string + to the end of the line. + + + Defaults to string ";" + + + + + Gets or sets the string to use as new line string when formating an IniData structure using a + IIniDataFormatter. Parsing an ini-file accepts any new line character (Unix/windows) + + + This allows to write a file with unix new line characters on windows (and vice versa) + + Defaults to value Environment.NewLine + + + + Sets the char that defines a value assigned to a key + + + Defaults to character '=' + + + + + Sets the string around KeyValuesAssignmentChar + + + Defaults to string ' ' + + + + + Allows having keys in the file that don't belong to any section. + i.e. allows defining keys before defining a section. + If set to false and keys without a section are defined, + the will stop with an error. + + + Defaults to true. + + + + + If set to false and the finds duplicate keys in a + section the parser will stop with an error. + If set to true, duplicated keys are allowed in the file. The value + of the duplicate key will be the last value asigned to the key in the file. + + + Defaults to false. + + + + + Only used if is also true + If set to true when the parser finds a duplicate key, it overrites + the previous value, so the key will always contain the value of the + last key readed in the file + If set to false the first readed value is preserved, so the key will + always contain the value of the first key readed in the file + + + Defaults to false. + + + + + Gets or sets a value indicating whether duplicate keys are concatenate + together by . + + + Defaults to false. + + + + + If true the instance will thrown an exception + if an error is found. + If false the parser will just stop execution and return a null value. + + + Defaults to true. + + + + + If set to false and the finds a duplicate section + the parser will stop with an error. + If set to true, duplicated sections are allowed in the file, but only a + element will be created in the + collection. + + + Defaults to false. + + + + + If set to false, the stop with a error if you try + to access a section that was not created previously and the parser will stop with an error. + If set to true, inexistents sections are created, always returning a valid + element. + + + Defaults to false. + + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + 2 + + + + + Responsible for parsing an string from an ini file, and creating + an structure. + + + + + Ctor + + + The parser uses a by default + + + + + Ctor + + + Parser's instance. + + + + + Configuration that defines the behaviour and constraints + that the parser must follow. + + + + + True is the parsing operation encounter any problem + + + + + Returns the list of errors found while parsing the ini file. + + + If the configuration option ThrowExceptionOnError is false it can contain one element + for each problem found while parsing; otherwise it will only contain the very same + exception that was raised. + + + + + Parses a string containing valid ini data + + + String with data + + + An instance with the data contained in + the correctly parsed an structured. + + + Thrown if the data could not be parsed + + + + + Checks if a given string contains a comment. + + + String with a line to be checked. + + + true if any substring from s is a comment, false otherwise. + + + + + Checks if a given string represents a section delimiter. + + + The string to be checked. + + + true if the string represents a section, false otherwise. + + + + + Checks if a given string represents a key / value pair. + + + The string to be checked. + + + true if the string represents a key / value pair, false otherwise. + + + + + Removes a comment from a string if exist, and returns the string without + the comment substring. + + + The string we want to remove the comments from. + + + The string s without comments. + + + + + Processes one line and parses the data found in that line + (section or key/value pair who may or may not have comments) + + The string with the line to process + + + + Proccess a string which contains an ini section. + + + The string to be processed + + + + + Processes a string containing an ini key/value pair. + + + The string to be processed + + + + + Extracts the key portion of a string containing a key/value pair.. + + + The string to be processed, which contains a key/value pair + + + The name of the extracted key. + + + + + Extracts the value portion of a string containing a key/value pair.. + + + The string to be processed, which contains a key/value pair + + + The name of the extracted value. + + + + + Abstract Method that decides what to do in case we are trying to add a duplicated key to a section + + + + + Adds a key to a concrete instance, checking + if duplicate keys are allowed in the configuration + + + Key name + + + Key's value + + + collection where the key should be inserted + + + Name of the section where the is contained. + Used only for logging purposes. + + + + + Temp list of comments + + + + + Tmp var with the name of the seccion which is being process + + + + + Represents an INI data parser for streams. + + + + + This instance will handle ini data parsing and writing + + + + + Ctor + + + + + Ctor + + + + + + Reads data in INI format from a stream. + + Reader stream. + + And instance with the readed ini data parsed. + + + Thrown if is null. + + + + + Writes the ini data to a stream. + + A write stream where the ini data will be stored + An instance. + + Thrown if is null. + + + + + Writes the ini data to a stream. + + A write stream where the ini data will be stored + An instance. + Formaterr instance that controls how the ini data is transformed to a string + + Thrown if is null. + + + + + Represents an INI data parser for strings. + + + + This class is deprecated and kept for backwards compatibility. + It's just a wrapper around class. + Please, replace your code. + + + + + This instance will handle ini data parsing and writing + + + + + Ctor + + + + + Ctor + + + + + + Parses a string containing data formatted as an INI file. + + The string containing the data. + + A new instance with the data parsed from the string. + + + + + Creates a string from the INI data. + + An instance. + + A formatted string with the contents of the + instance object. + + + + + Represents an error ococcurred while parsing data + + +
+