diff --git a/SuperCom/App.xaml.cs b/SuperCom/App.xaml.cs index bb1bfb8..26521c2 100644 --- a/SuperCom/App.xaml.cs +++ b/SuperCom/App.xaml.cs @@ -1,4 +1,6 @@ -using SuperControls.Style.Windows; +using SuperCom.Log; +using SuperCom.WatchDog; +using SuperControls.Style.Windows; using System; using System.Collections.Generic; using System.Configuration; @@ -14,15 +16,37 @@ namespace SuperCom /// /// Interaction logic for App.xaml /// + /// + public partial class App : Application { + private static bool Error { get; set; } + + public static Logger Logger = Logger.Instance; + private static MemoryDog memoryDog { get; set; } + + public static Action OnMemoryDog; + public static Action OnMemoryChanged; + + static App() + { + memoryDog = new MemoryDog(); + memoryDog.OnNotFeed += () => + { + OnMemoryDog?.Invoke(); + }; + memoryDog.OnMemoryChanged += (memory) => + { + OnMemoryChanged?.Invoke(memory); + }; + } protected override void OnStartup(StartupEventArgs e) { // UI线程未捕获异常处理事件 - //#if DEBUG +#if DEBUG - //#else +#else this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException); // Task线程内未捕获异常处理事件 @@ -31,7 +55,9 @@ protected override void OnStartup(StartupEventArgs e) // 非UI线程未捕获异常处理事件 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); - //#endif +#endif + // 看门狗 + memoryDog.Watch(); base.OnStartup(e); } @@ -39,9 +65,15 @@ void App_DispatcherUnhandledException(object sender, System.Windows.Threading.Di { try { + if (Error) + return; + Error = true; Window_ErrorMsg window_ErrorMsg = new Window_ErrorMsg(); - window_ErrorMsg.SetError(e.Exception.ToString()); + string error = e.Exception.ToString(); + Logger.Error(error); + window_ErrorMsg.SetError(error); window_ErrorMsg.ShowDialog(); + } catch (Exception ex) { @@ -59,11 +91,13 @@ void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs try { - StringBuilder builder = new StringBuilder(); - if (e.IsTerminating) + if (e.IsTerminating && !Error) { + Error = true; Window_ErrorMsg window_ErrorMsg = new Window_ErrorMsg(); - window_ErrorMsg.SetError(e.ExceptionObject.ToString()); + string error = e.ExceptionObject.ToString(); + Logger.Error(error); + window_ErrorMsg.SetError(error); window_ErrorMsg.ShowDialog(); } } @@ -81,8 +115,8 @@ void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { // task线程内未处理捕获 - Console.WriteLine(e.Exception.StackTrace); - Console.WriteLine(e.Exception.Message); + Logger.Error(e.Exception.StackTrace); + Logger.Error(e.Exception.Message); e.SetObserved(); // 设置该异常已察觉(这样处理后就不会引起程序崩溃) } } diff --git a/SuperCom/Config/ConfigManager.cs b/SuperCom/Config/ConfigManager.cs index f79d704..c886750 100644 --- a/SuperCom/Config/ConfigManager.cs +++ b/SuperCom/Config/ConfigManager.cs @@ -8,7 +8,7 @@ public static class ConfigManager { public const string SQLITE_DATA_PATH = "user_data.sqlite"; - public const string RELEASE_DATE = "2023-01-17"; + public const string RELEASE_DATE = "2023-02-05"; public static Main Main { get; set; } public static CommonSettings CommonSettings { get; set; } public static Settings Settings { get; set; } diff --git a/SuperCom/Config/Settings.cs b/SuperCom/Config/Settings.cs index 0e9e137..9613dd0 100644 --- a/SuperCom/Config/Settings.cs +++ b/SuperCom/Config/Settings.cs @@ -8,6 +8,7 @@ public class Settings : AbstractConfig { private const int DEFAULT_LOG_FRAG_SIZE = 40; // MB + private const int DEFAULT_MEMORY_LIMIT = 1024; // MB private Settings() : base(ConfigManager.SQLITE_DATA_PATH, $"WindowConfig.Settings") { Width = SystemParameters.WorkArea.Width * 0.7; @@ -17,6 +18,7 @@ private Settings() : base(ConfigManager.SQLITE_DATA_PATH, $"WindowConfig.Setting AutoBackup = true; EnabledLogFrag = true; LogFragSize = DEFAULT_LOG_FRAG_SIZE; + MemoryLimit = DEFAULT_MEMORY_LIMIT; } public static List BackUpPeriods = new List { 1, 3, 7, 15, 30 }; @@ -47,6 +49,7 @@ public static Settings CreateInstance() public long RemoteIndex { get; set; } public bool EnabledLogFrag { get; set; } public long LogFragSize { get; set; } + public long MemoryLimit { get; set; } } } diff --git a/SuperCom/Entity/ComSettings.cs b/SuperCom/Entity/ComSettings.cs index f324ee5..08fa839 100644 --- a/SuperCom/Entity/ComSettings.cs +++ b/SuperCom/Entity/ComSettings.cs @@ -87,7 +87,7 @@ public static void InitSqlite() } catch (Exception ex) { - Console.WriteLine(ex.Message); + App.Logger.Error(ex.Message); } } } diff --git a/SuperCom/Entity/PortTabItem.cs b/SuperCom/Entity/PortTabItem.cs index a0087aa..9c67195 100644 --- a/SuperCom/Entity/PortTabItem.cs +++ b/SuperCom/Entity/PortTabItem.cs @@ -1,5 +1,6 @@  using ICSharpCode.AvalonEdit; +using ICSharpCode.AvalonEdit.Highlighting; using SuperCom.Config; using SuperCom.Config.WindowConfig; using SuperUtils.Common; @@ -98,7 +99,6 @@ public string WriteData set { _WriteData = value; RaisePropertyChanged(); } } - private StringBuilder Builder { get; set; } public TextEditor TextEditor { get; set; } private bool _AddTimeStamp = true; @@ -126,7 +126,7 @@ public bool EnabledMonitor } - public UInt64 CurrentCharSize { get; set; } + public double CurrentCharSize { get; set; } private long _RX = 0L; public long RX @@ -195,6 +195,30 @@ public bool Pinned get { return _Pinned; } set { _Pinned = value; RaisePropertyChanged(); } } + private bool _FixedText; + public bool FixedText + { + get { return _FixedText; } + set + { + _FixedText = value; + RaisePropertyChanged(); + if (TextEditor != null) + { + if (value) + TextEditor.TextChanged -= TextBox_TextChanged; + else + TextEditor.TextChanged += TextBox_TextChanged; + } + } + } + + + public void TextBox_TextChanged(object sender, EventArgs e) + { + TextEditor textEditor = sender as TextEditor; + textEditor?.ScrollToEnd(); + } public bool RunningCommands { get; set; } @@ -202,7 +226,6 @@ public bool Pinned public void ClearData() { - Builder.Clear(); FirstSaveData = true; } @@ -397,7 +420,7 @@ public bool IsInFilterRule(string line) } catch (Exception ex) { - Console.WriteLine(ex.Message); + App.Logger.Error(ex.Message); continue; } @@ -509,7 +532,11 @@ public void SepFile() if (ConfigManager.Settings.EnabledLogFrag) { //if (CurrentCharSize >= 4096) - if (CurrentCharSize / 1024 >= (UInt64)ConfigManager.Settings.LogFragSize) +#if DEBUG + if (CurrentCharSize / 1024 / 1024 >= (UInt64)ConfigManager.Settings.LogFragSize) +#else + if (CurrentCharSize / 1024 / 1024 >= (UInt64)ConfigManager.Settings.LogFragSize) +#endif { CurrentCharSize = 0; ConnectTime = DateTime.Now; @@ -533,14 +560,15 @@ public void SepFile() } public bool FirstSaveData; + private StringBuilder builder = new StringBuilder(); public void SaveData(string line) { - RX += line.Length; + RX += Encoding.UTF8.GetByteCount(line); // todo string value = line.Replace("\0", "\\0"); if (AddTimeStamp) { // 遍历字符串 - StringBuilder builder = new StringBuilder(); + builder.Clear(); // 一次遍历效率最高,使用 indexof 还额外多遍历几次 char c; for (int i = 0; i < value.Length; i++) @@ -567,7 +595,7 @@ public void SaveData(string line) } value = builder.ToString(); } - CurrentCharSize += (UInt64)value.Length * sizeof(char); + CurrentCharSize += Encoding.UTF8.GetByteCount(value); MonitorLine(value); FilterLine(value); // 过滤器 SepFile(); @@ -578,7 +606,7 @@ public void SaveData(string line) } catch (Exception ex) { - Console.WriteLine(ex.Message); + App.Logger.Error(ex.Message); } } @@ -590,7 +618,6 @@ public PortTabItem(string name, bool connected) Name = name; Connected = connected; Setting = new PortSetting(); - Builder = new StringBuilder(); SaveFileName = GetSaveFileName(); } } diff --git a/SuperCom/Entity/VirtualPort.cs b/SuperCom/Entity/VirtualPort.cs index 0064ffc..54e4c57 100644 --- a/SuperCom/Entity/VirtualPort.cs +++ b/SuperCom/Entity/VirtualPort.cs @@ -103,7 +103,7 @@ await Task.Run(() => result.Add(port); }, null, (ex) => { - Console.WriteLine(ex.Message); + App.Logger.Error(ex.Message); }, () => { completed = true; @@ -140,13 +140,13 @@ await Task.Run(() => { CmdHelper.Run($"cmd.exe", cmdParam, (output) => { - Console.WriteLine(output); + App.Logger.Info(output); if (output.IndexOf("logged as \"in use\"") >= 0) count++; completed = count == 2; }, null, (ex) => { - Console.WriteLine(ex.Message); + App.Logger.Error(ex.Message); }); }); // 超时 @@ -177,14 +177,14 @@ await Task.Run(() => { CmdHelper.Run($"cmd.exe", cmdParam, (output) => { - Console.WriteLine(output); + App.Logger.Info(output); if (output.IndexOf($"Removed CNCA{n}") >= 0 || output.IndexOf($"Removed CNCB{n}") >= 0) count++; completed = count == 2; }, null, (ex) => { - Console.WriteLine(ex.Message); + App.Logger.Error(ex.Message); completed = true; }); }); @@ -211,12 +211,12 @@ public static async Task UpdatePorts(List ports) foreach (VirtualPort port in ports) { string cmdParam = $"/C cd /d \"{AppDir}\" && setupc.exe change {port.ID} {port.ToUpdateString()}"; - Console.WriteLine(cmdParam); + App.Logger.Info($"执行命令:{cmdParam}"); await Task.Run(() => { CmdHelper.Run($"cmd.exe", cmdParam, (output) => { - Console.WriteLine(output); + App.Logger.Info(output); if (output.IndexOf($"Restarted {port.ID}") >= 0) completed = true; }); diff --git a/SuperCom/Lang/LangManager.cs b/SuperCom/Lang/LangManager.cs index c3db680..c4f74c0 100644 --- a/SuperCom/Lang/LangManager.cs +++ b/SuperCom/Lang/LangManager.cs @@ -32,7 +32,7 @@ public static bool SetLang(string lang) } catch (Exception ex) { - Console.WriteLine(ex.Message); + App.Logger.Error(ex.Message); return false; } } diff --git a/SuperCom/Log/Logger.cs b/SuperCom/Log/Logger.cs index 691d875..dba4f42 100644 --- a/SuperCom/Log/Logger.cs +++ b/SuperCom/Log/Logger.cs @@ -1,5 +1,6 @@ using SuperUtils.Framework.Logger; using SuperUtils.IO; +using SuperUtils.Time; using System; using System.IO; @@ -7,7 +8,8 @@ namespace SuperCom.Log { public class Logger : AbstractLogger { - public static string FilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "app.log"); + private static string LogDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "app_logs"); + private static string LogFilePath = Path.Combine(LogDir, "app.log"); private Logger() { } public static Logger Instance { get; } @@ -15,12 +17,16 @@ private Logger() { } static Logger() { Instance = new Logger(); + Instance.LogLevel = AbstractLogger.Level.Info; + if (!Directory.Exists(LogDir)) + DirHelper.TryCreateDirectory(LogDir); + LogFilePath = Path.Combine(LogDir, $"{DateHelper.NowDate()}.log"); } public override void LogPrint(string str) { Console.WriteLine(str); - FileHelper.TryAppendToFile(FilePath, str); + FileHelper.TryAppendToFile(LogFilePath, str, System.Text.Encoding.UTF8); } } } diff --git a/SuperCom/MainWindow.xaml b/SuperCom/MainWindow.xaml index 4a31102..46189fe 100644 --- a/SuperCom/MainWindow.xaml +++ b/SuperCom/MainWindow.xaml @@ -25,6 +25,20 @@ mc:Ignorable="d"> + + + + + + + + + + + + + +