I was planning to write more about Ext. net. Since I am playing Silverlight and Android, I am not planning to write it down. And I am very busy recently, so I am not posting in time.
Now, let's get started: Recently, the customer has a requirement to write a log file for the apple all-in-one machine on the mini-program monitoring production line and upload it to the server. I first wanted to use Perl or Python, but I didn't have enough time (because I was not familiar with these two languages), so I wanted to try mono. Mono is not as easy as you can imagine, but it is barely usable.
Although monodevelop works, we prefer vs development. So encode the code in. It is worth noting that:
- If you are developing a winform program, use GTK to reproduce the program.
- If it is developed in Vs, it is best to use English for all encoding and comments. Otherwise, garbled characters may occur when you change to another system.
- Note whether mono supports writing; otherwise, it is a white write.
Next, start encoding.
1. Read the configuration file
I used to use XML and found that system. xml. LINQ is not supported, and system. XML is not supported. It is also troublesome to read the INI file, so I just want to read the text file. The sample configuration is as follows:
MonitoringDirectoryType:['Immediate','Cycle']Path:['/Users/PRODUCTION/Public/FinalTest/LogsFolder','/Users/PRODUCTION/Public/FinalTest/LogsFolder']TargetPath:['/Volumes/mes_data/FINALTEST/n81a/{Y}/{M}/{D}/FIN012','/Volumes/mes_data/FINALTEST/n81a/{Y}/{M}/{D}/FIN012']IncludeSubdirectories:['FALSE','false']Filter:['*.TXT','*.CSV']BackupPath:['/Users/PRODUCTION/BACKUP/{Y}/{M}/{D}','/Users/PRODUCTION/BACKUP/{Y}/{M}/{D}']BackupExpired:['2','2']CycleMinutes:['','1440']
The parsing code is as follows:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using MonitoringApp.Custom;using System.Text.RegularExpressions;using Gtk;namespace MonitoringApp.Code.App{ public class Configuration { private static bool isLoadFirst = false; private static List<MyConfig> configLst; public static List<MyConfig> ConfigLst { get { if (configLst == null) { try { if (!isLoadFirst) return LoadFromInitParams(); else return null; } catch (Exception ex) { LogManager.WriteErrorLog(ex); return null; } } return configLst; } set { configLst = value; } } /// <summary> /// Load Configuration file /// </summary> /// <returns></returns> private static List<MyConfig> LoadFromInitParams() { isLoadFirst = true; string _configPath = Path.Combine(Directory.GetCurrentDirectory(), "Configuration.txt"); if (File.Exists(_configPath)) { if (ConfigLst == null) ConfigLst = new List<MyConfig>(); else return ConfigLst; using (StreamReader sr = new StreamReader(_configPath)) { int lineIndex = 1; while (sr.Peek() > 0) { string str = sr.ReadLine().Trim(); if (str.Length == 0) continue; if (!str.Contains("[") || !str.Contains("]")) { LogManager.WriteErrorLog(string.Format("Config Error:'[' OR ']' Not Exist.At Line {0}.", lineIndex)); continue; } if (!str.Contains(":")) { LogManager.WriteErrorLog(string.Format("Config Error:':' Not Exist.At Line {0}.", lineIndex)); continue; } string[] names = str.Split(':'); str = str.Substring(str.IndexOf(':') + 1).Trim(']').Trim('[').Trim('\''); string[] strConfigs = str.Split(','); SetConfig(names, ConfigLst, strConfigs, lineIndex == 1); lineIndex++; } } return ConfigLst; } else { LogManager.WriteErrorLog(string.Format("can't find config file.Path:{0}.",_configPath)); return null; } } /// <summary> /// Set Config /// </summary> /// <param name="name"></param> /// <param name="lst"></param> /// <param name="strConfigs"></param> private static void SetConfig(string[] name, List<MyConfig> lst, string[] strConfigs, bool isLineOne) { try { var mcConfig = (MonitoringConfigurations)Enum.Parse(typeof(MonitoringConfigurations), name[0], true); //Set Values for (int i = 0; i < strConfigs.Length; i++) { string value = strConfigs[i].Trim('\''); switch (mcConfig) { case MonitoringConfigurations.MonitoringDirectoryType: { #region MonitoringDirectoryType Defalut:immediate switch (value.ToLower()) { case "immediate": { if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.MDType = MonitoringDirectoryType.Immediate; lst.Add(myConfig); } else { lst[i].MDType = MonitoringDirectoryType.Immediate; } break; } case "cycle": { if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.MDType = MonitoringDirectoryType.Cycle; lst.Add(myConfig); } else { lst[i].MDType = MonitoringDirectoryType.Cycle; } break; } default: { if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.MDType = MonitoringDirectoryType.Immediate; lst.Add(myConfig); } else { lst[i].MDType = MonitoringDirectoryType.Immediate; } break; } } #endregion break; } case MonitoringConfigurations.Path: #region Path if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.Path = value; lst.Add(myConfig); } else { lst[i].Path = value; } #endregion break; case MonitoringConfigurations.IncludeSubdirectories: #region IncludeSubdirectories if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.IncludeSubdirectories = Convert.ToBoolean(value); lst.Add(myConfig); } else { lst[i].IncludeSubdirectories = Convert.ToBoolean(value); } #endregion break; case MonitoringConfigurations.Filter: #region Filter if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.Filter = value; lst.Add(myConfig); } else { lst[i].Filter = value; } break; #endregion case MonitoringConfigurations.BackupPath: #region BackupPath if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.BackupPath = value; lst.Add(myConfig); } else { lst[i].BackupPath = value; } #endregion break; case MonitoringConfigurations.TargetPath: #region TargetPath if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.TargetPath = value; lst.Add(myConfig); } else { lst[i].TargetPath = value; } #endregion break; case MonitoringConfigurations.BackupExpired: #region BackupExpired Unit:days Default:30 if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.BackupExpired = Convert.ToInt32(value.Length == 0 ? "30" : value); lst.Add(myConfig); } else { lst[i].BackupExpired = Convert.ToInt32(value.Length == 0 ? "30" : value); } #endregion break; case MonitoringConfigurations.CycleMinutes: #region CycleMinutes Unit:Minute Default:60 if (isLineOne) { MyConfig myConfig = new MyConfig(); myConfig.CycleMinutes = Convert.ToInt32(value.Length == 0 ? "60" : value); lst.Add(myConfig); } else { lst[i].CycleMinutes = Convert.ToInt32(value.Length == 0 ? "60" : value); } #endregion break; default: break; } } } catch (Exception ex) { LogManager.WriteErrorLog(ex); } } }}
It is worth noting that:
- This is read by row. From the read configuration, we can see that multiple configuration items are supported.
- If an error occurs, logs are recorded.
- It is troublesome to explain how to configure with the customer. The configurations are described as follows:
Monitoringdirectorytype: Directory type. Only two values (immediate and cycle) are supported ). Immediate indicates real-time monitoring (default), and cycle indicates periodic monitoring. Path: monitor directory path. Must be an existing path. Targetpath: target directory path. It can be a remote directory path. The SMB path cannot be used, but it should be of the "/volumes/mes_data/n81a" type. Includesubdirectories: Indicates whether to include subdirectories. Filter: Filter strings. For example, "*" indicates monitoring all files, and "*. txt" indicates monitoring all text files. Backuppath: backup path. Backupexpired: Backup expiration time. The Unit is day. Must be an integer. The default value is 30 days. Cycleminutes: Cycle cycle time. Unit: Minute. Must be an integer. The default value is 60 minutes.
Then, write a description document for the configuration, so that the customer will configure it.
2) record logs
When the program is running, various problems are inevitable, and it is inevitable to record logs. The related code is as follows:
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using Gtk;namespace MonitoringApp.Code.App{ public class LogManager { public static object obj = new object(); static LogManager() { } #region Fields and Properties private static string _logPath = string.Empty; public static string LogPath { get { lock (obj) { if (_logPath == string.Empty) { var _logStr = string.Format("{0}/log/{1}/{2}", Path.Combine(Directory.GetCurrentDirectory(), "Data"), DateTime.Now.ToString("yyyy-MM"), DateTime.Now.Day); if (!System.IO.Directory.Exists(_logStr)) System.IO.Directory.CreateDirectory(_logStr); return string.Format("{0}/", _logStr); } return _logPath; } } set { _logPath = value; } } private static string _logFielPrefix = string.Empty; public static string LogFielPrefix { get { return _logFielPrefix; } set { _logFielPrefix = value; } } #endregion #region Log public static void WriteLog(string logFile, string msg) { try { lock (obj) { var _sb = new System.Text.StringBuilder(); _sb.Append(LogPath).Append(LogFielPrefix).Append(logFile).Append(".Log"); using (var _sw = System.IO.File.AppendText(_sb.ToString())) { _sw.WriteLine("==============================={0}===============================", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); _sw.WriteLine(msg); _sw.Flush(); _sw.Close(); Console.WriteLine(msg); } } } catch { } } public static void WriteLog(LogFile logFile, string msg) { WriteLog(logFile.ToString(), msg); } public static void WriteTraceLog(string msg) { Console.WriteLine(msg); } public static void WriteErrorLog(string msg) { WriteLog(LogFile.Error, msg); } public static void WriteErrorLog(Exception ex) { var _sbError = new StringBuilder(); _sbError.Append("[Message]").Append(ex.Message); _sbError.Append("\r\n[TargetSite]").Append(ex.TargetSite); _sbError.Append("\r\n[StackTrace]").Append(ex.StackTrace); _sbError.Append("\r\n[Source]").Append(ex.Source); foreach (var _item in ex.Data.Keys) { _sbError.Append("\r\n[").Append(_item).Append("]").Append(ex.Data[_item]); } if (ex.InnerException != null && ex.InnerException.Message != ex.Message) { _sbError.AppendLine("____________________________________________________________________________________"); _sbError.Append("[Message]").Append(ex.InnerException.Message); _sbError.Append("\r\n[TargetSite]").Append(ex.InnerException.TargetSite); _sbError.Append("\r\n[StackTrace]").Append(ex.InnerException.StackTrace); _sbError.Append("\r\n[Source]").Append(ex.InnerException.Source); _sbError.AppendLine("____________________________________________________________________________________"); } WriteLog(LogFile.Error, _sbError.ToString()); } public static void WriteWarningLog(string msg) { WriteLog(LogFile.Warning, msg); } #endregion } public enum LogFile { Trace, Warning, Error, SQL, System }}
It is worth noting that "directory. getcurrentdirectory ()"You can get the personal directory of the current user. As for the path to the current directory of the program, winform does not work. (If any friend finds a suitable method, leave a message ). The apple System and the window system are very different. I have never played the Apple system and I am not used to it at the beginning.
Next, we will describe how to monitor directories and regular backups, and finally how to release and deploy them. Release and deployment are the most important part. I don't know what the problem will be. I thought that this small program could be completed in one day, but it was abolished three days in the Mid-Autumn Festival. Fortunately, we are lucky to solve this problem. Time relationship.