diff --git a/App.config b/App.config index d1428ad..4bfa005 100644 --- a/App.config +++ b/App.config @@ -1,6 +1,6 @@ - + diff --git a/Config.cs b/Config.cs index 1e13067..79f1c6f 100644 --- a/Config.cs +++ b/Config.cs @@ -51,14 +51,19 @@ public static IPAddress TheIPAddress /// Use numbers for the ping instead of a graph. public static bool UseNumbers; - + #region Logging options + public static bool EnableLogging; + public static string LogDirPath; + #endregion static Config() => Reset(); - public static void SetAll(int delay, int maxPing, Color bgColor, Color goodColor, Color normalColor, - Color badColor, bool runOnStartup, IPAddress address, - bool alarmConnectionLost, bool alarmTimeOut, bool alarmResumed, bool useNumbers, - string _SFXConnectionLost, string _SFXTimeOut, string _SFXResumed, bool offlineCounter) + public static void SetAll( + int delay, int maxPing, Color bgColor, Color goodColor, Color normalColor, + Color badColor, bool runOnStartup, IPAddress address, + bool alarmConnectionLost, bool alarmTimeOut, bool alarmResumed, bool useNumbers, + string _SFXConnectionLost, string _SFXTimeOut, string _SFXResumed, bool offlineCounter, + bool enableLogging, string logPath) { Delay = delay; MaxPing = maxPing; @@ -76,6 +81,16 @@ public static void SetAll(int delay, int maxPing, Color bgColor, Color goodColor SFXTimeOut = _SFXTimeOut; SFXResumed = _SFXResumed; OfflineCounter = offlineCounter; + EnableLogging = enableLogging; + LogDirPath = logPath; + + if (EnableLogging) + { + if (!Directory.Exists(LogDirPath)) + { + Directory.CreateDirectory(LogDirPath); + } + } } public static void Reset() @@ -97,6 +112,7 @@ public static void Reset() SFXTimeOut = NONE_SFX; SFXResumed = NONE_SFX; RunOnStartup = false; + EnableLogging = false; } public static void Load() @@ -182,6 +198,14 @@ public static void Load() case nameof(OfflineCounter): bool.TryParse(split[1], out OfflineCounter); break; + + case nameof(EnableLogging): + bool.TryParse(split[1], out EnableLogging); + break; + + case nameof(LogDirPath): + LogDirPath = split[1]; + break; } } } @@ -236,6 +260,9 @@ public static void Save() sb.AppendLine($"{nameof(OfflineCounter)} {OfflineCounter}"); + sb.AppendLine($"{nameof(EnableLogging)} {EnableLogging}"); + sb.AppendLine($"{nameof(LogDirPath)} {LogDirPath}"); + File.WriteAllText(CONF_FILE_NAME, sb.ToString()); } diff --git a/NotificationIcon.cs b/NotificationIcon.cs index 6a1dc62..7442609 100644 --- a/NotificationIcon.cs +++ b/NotificationIcon.cs @@ -1,7 +1,9 @@ -using PingoMeter.vendor; +using Microsoft.Win32; +using PingoMeter.vendor; using PingoMeter.vendor.StartupCreator; using System; +using System.Diagnostics; using System.Drawing; using System.IO; using System.Media; @@ -35,6 +37,10 @@ internal sealed class NotificationIcon SoundPlayer SFXTimeOut; SoundPlayer SFXResumed; + IPStatus? previousLogStatus = null; + string previousLogMessage = null; + DateTimeOffset lastPowerModeChangeTime = DateTimeOffset.MinValue; + enum PingHealthEnum { Good, @@ -84,15 +90,21 @@ public NotificationIcon() noneIcon = Icon.FromHandle(hiconOriginal); g = Graphics.FromImage(drawable); font = new Font("Consolas", 9f, FontStyle.Bold); - font100 = new Font("Consolas", 7f, FontStyle.Bold);; + font100 = new Font("Consolas", 7f, FontStyle.Bold); + WriteLog("Startup", null, $"{Process.GetCurrentProcess().ProcessName} started"); + + SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; + SetIcon(); } ~NotificationIcon() { + SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; DestroyIcon(hicon); DestroyIcon(hiconOriginal); g.Dispose(); + WriteLog("Shutdown", null, $"{Process.GetCurrentProcess().ProcessName} shutting down"); } public void Run() @@ -270,7 +282,12 @@ private void PingPool(object _) { PingReply reply = p.Send(Config.TheIPAddress, 5000, buffer); - switch (reply.Status) + //there is a lower-limit to the configured timeout, so we have to override the timeout process. + var calculatedStatus = (reply.Status == IPStatus.Success && reply.RoundtripTime > Config.MaxPing) + ? IPStatus.TimedOut + : reply.Status; + + switch (calculatedStatus) { case IPStatus.TimedOut: DrawGraph(-1L); @@ -287,6 +304,8 @@ private void PingPool(object _) } alarmStatus = AlarmEnum.TimeOut; + + WriteLog(calculatedStatus, $"{ notifyIcon.Text } ({ reply.RoundtripTime }ms)", doRepeat: false); } else { @@ -306,18 +325,18 @@ private void PingPool(object _) notifyIcon.ShowBalloonTip(BALLOON_TIP_TIME_OUT, "PingoMeter", "Ping resumed", ToolTipIcon.Info); } + WriteLog(calculatedStatus, $"Ping resumed ({reply.RoundtripTime}ms)", doRepeat: false); + alarmStatus = AlarmEnum.OK; timeOutAgain = false; break; default: - DrawGraph(-1L); + var statusName = GetIPStatusName(reply.Status); notifyIcon.Text = "Status: " + statusName; - - if (alarmStatus != AlarmEnum.ConnectionLost) { PlaySound(SFXConnectionLost, Config.SFXConnectionLost); @@ -327,23 +346,40 @@ private void PingPool(object _) } alarmStatus = AlarmEnum.ConnectionLost; + WriteLog(calculatedStatus, "Connection Lost.", doRepeat: false); break; } } catch (PingException) { - DrawGraph(-1L); - notifyIcon.Text = "Status: Connection lost."; - - if (alarmStatus != AlarmEnum.ConnectionLost) + //false positives happen on wake. + //check if just woke up + int wakeTimeInMillis = 500; + var utcnow = DateTimeOffset.Now; + if ((utcnow - lastPowerModeChangeTime).TotalMilliseconds < wakeTimeInMillis) { - PlaySound(SFXConnectionLost, Config.SFXConnectionLost); - - if (Config.AlarmConnectionLost) - notifyIcon.ShowBalloonTip(BALLOON_TIP_TIME_OUT, "PingoMeter", "Connection lost", ToolTipIcon.Error); + //just woke up + DrawGraph(-1L); + notifyIcon.Text = "Status: Connection lost?"; + WriteLog("Wake", null, $"{Process.GetCurrentProcess().ProcessName} lost connection because PC waking up"); } + else + { + DrawGraph(-1L); + notifyIcon.Text = "Status: Connection lost."; - alarmStatus = AlarmEnum.ConnectionLost; + if (alarmStatus != AlarmEnum.ConnectionLost) + { + PlaySound(SFXConnectionLost, Config.SFXConnectionLost); + + if (Config.AlarmConnectionLost) + notifyIcon.ShowBalloonTip(BALLOON_TIP_TIME_OUT, "PingoMeter", "Connection lost", ToolTipIcon.Error); + } + + alarmStatus = AlarmEnum.ConnectionLost; + + WriteLog(IPStatus.Unknown, "Connection Lost (PingException).", doRepeat: false); + } } catch (Exception ex) { @@ -353,6 +389,7 @@ private void PingPool(object _) notifyIcon.ShowBalloonTip(BALLOON_TIP_TIME_OUT, "PingoMeter", "Error: " + ex.Message, ToolTipIcon.Error); alarmStatus = AlarmEnum.None; + WriteLog(IPStatus.Unknown, $"Error: {ex.Message}", doRepeat: false); } Thread.Sleep(Config.Delay); @@ -503,5 +540,78 @@ private string GetIPStatusName(IPStatus status) } } + /// + /// Write into the monthly log-file + /// + /// IPStatus object that describes the info. Will be logged by both IP and text. + /// Text message to log. Quotes will be escaped if necessary. Not null. + /// bool to re-log the same message more than once if eg connection is out. + private void WriteLog(IPStatus status, string message, bool doRepeat) + { + // note that we only care if the message is distinct if its UNKNOWN, otherwise we assume all messages are the same. + // this lets us add some metadata to the non-error messages without duplication. + if (doRepeat || !status.Equals(previousLogStatus) || !(message.Equals(previousLogMessage) || (int)status >= 0)) { + previousLogStatus = status; + previousLogMessage = message; + var eventName = status.ToString(); + var ipStatusNum = (int)status; + WriteLog(eventName, ipStatusNum, message); + } + } + + /// + /// Write into the monthly log-file + /// + /// Event number to log. + /// /// Event name to log. Will match the . + /// Text message to log. Quotes will be escaped if necessary. Not null. + private void WriteLog(string eventName, int? ipStatusNum, string message) + { + if (Config.EnableLogging) + { + var now = DateTime.Now; + + // csv escape + // this should probably all be done with a proper CSV package but this project doesn't have any + // external package dependencies so I don't want to start now. + var messageEscapedCsv = (message.Contains("\"") || message.Contains("\n")) + ? $"\"{message.Replace("\"", "\"\"")}\"" + : message; + + if (!Directory.Exists(Config.LogDirPath)) + { + Directory.CreateDirectory(Config.LogDirPath); + } + + var logFilePath = Path.Combine(Config.LogDirPath, $@"{Process.GetCurrentProcess().ProcessName}-{now.Year}-{now.Month}.log.csv"); + if(!File.Exists(logFilePath)) + { + string[] headings = { "Date", "Event", "IPStatus", "IPAddress", "Message" }; + string headingLine = string.Join(", ", headings); + using (StreamWriter writer = new StreamWriter(logFilePath)) + { + writer.WriteLine(headingLine); + writer.Flush(); + } + } + + using (StreamWriter writer = new StreamWriter(logFilePath, append:true)) + { + var date = now.ToString("yyyy-MM-dd HH:mm:ss"); + var ipAddressLogEntry = ipStatusNum.HasValue + ? Config.TheIPAddress.ToString() + : string.Empty; //no need to log address for startup/shutdown operations. + string[] body = { date, eventName, ipStatusNum.ToString(), ipAddressLogEntry, messageEscapedCsv }; + string bodyLine = string.Join(", ", body); + writer.WriteLine(bodyLine); + writer.Flush(); + } + } + } + + private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) + { + lastPowerModeChangeTime = DateTimeOffset.Now; + } } } diff --git a/PingoMeter.csproj b/PingoMeter.csproj index 88a3b16..83251b7 100644 --- a/PingoMeter.csproj +++ b/PingoMeter.csproj @@ -8,7 +8,7 @@ WinExe PingoMeter PingoMeter - v4.5 + v4.8 512 true diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index e0117b9..59114c3 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace PingoMeter.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs index 1fa9b21..3e04c9f 100644 --- a/Properties/Settings.Designer.cs +++ b/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace PingoMeter.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/Setting.Designer.cs b/Setting.Designer.cs index 77d8f4a..02ae5ce 100644 --- a/Setting.Designer.cs +++ b/Setting.Designer.cs @@ -53,6 +53,7 @@ private void InitializeComponent() this.numbersModeCheckBox = new System.Windows.Forms.CheckBox(); this.graphColorsGroupBox = new System.Windows.Forms.GroupBox(); this.tabPage2 = new System.Windows.Forms.TabPage(); + this.cbOfflineCounter = new System.Windows.Forms.CheckBox(); this.cbStartupRun = new System.Windows.Forms.CheckBox(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.label11 = new System.Windows.Forms.Label(); @@ -65,13 +66,19 @@ private void InitializeComponent() this.alarmTimeOut = new System.Windows.Forms.CheckBox(); this.alarmResumed = new System.Windows.Forms.CheckBox(); this.alarmConnectionLost = new System.Windows.Forms.CheckBox(); - this.tabPage3 = new System.Windows.Forms.TabPage(); + this.loggingTabPage = new System.Windows.Forms.TabPage(); + this.LoggingGroupBox = new System.Windows.Forms.GroupBox(); + this.LogPathTextBox = new System.Windows.Forms.TextBox(); + this.LogPathPickerButton = new System.Windows.Forms.Button(); + this.label12 = new System.Windows.Forms.Label(); + this.EnableLoggingCheckbox = new System.Windows.Forms.CheckBox(); + this.aboutTabPage = new System.Windows.Forms.TabPage(); this.linkLabel1 = new System.Windows.Forms.LinkLabel(); this.labelVersion = new System.Windows.Forms.Label(); this.label9 = new System.Windows.Forms.Label(); this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.cbOfflineCounter = new System.Windows.Forms.CheckBox(); + this.ExploreButton = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.delay)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.maxPing)).BeginInit(); this.tabControl1.SuspendLayout(); @@ -80,7 +87,9 @@ private void InitializeComponent() this.tabPage2.SuspendLayout(); this.groupBox2.SuspendLayout(); this.groupBox1.SuspendLayout(); - this.tabPage3.SuspendLayout(); + this.loggingTabPage.SuspendLayout(); + this.LoggingGroupBox.SuspendLayout(); + this.aboutTabPage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.SuspendLayout(); // @@ -307,10 +316,11 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.tabControl1.Controls.Add(this.tabPage1); this.tabControl1.Controls.Add(this.tabPage2); - this.tabControl1.Controls.Add(this.tabPage3); + this.tabControl1.Controls.Add(this.loggingTabPage); + this.tabControl1.Controls.Add(this.aboutTabPage); this.tabControl1.Location = new System.Drawing.Point(12, 12); this.tabControl1.Name = "tabControl1"; - this.tabControl1.Padding = new System.Drawing.Point(30, 3); + this.tabControl1.Padding = new System.Drawing.Point(20, 3); this.tabControl1.SelectedIndex = 0; this.tabControl1.Size = new System.Drawing.Size(339, 335); this.tabControl1.TabIndex = 12; @@ -377,6 +387,16 @@ private void InitializeComponent() this.tabPage2.TabIndex = 1; this.tabPage2.Text = "Advanced"; // + // cbOfflineCounter + // + this.cbOfflineCounter.AutoSize = true; + this.cbOfflineCounter.Location = new System.Drawing.Point(6, 255); + this.cbOfflineCounter.Name = "cbOfflineCounter"; + this.cbOfflineCounter.Size = new System.Drawing.Size(132, 19); + this.cbOfflineCounter.TabIndex = 14; + this.cbOfflineCounter.Text = "Offline time counter"; + this.cbOfflineCounter.UseVisualStyleBackColor = true; + // // cbStartupRun // this.cbStartupRun.AutoSize = true; @@ -504,18 +524,81 @@ private void InitializeComponent() this.alarmConnectionLost.Text = "Connection lost"; this.alarmConnectionLost.UseVisualStyleBackColor = true; // - // tabPage3 - // - this.tabPage3.BackColor = System.Drawing.SystemColors.Control; - this.tabPage3.Controls.Add(this.linkLabel1); - this.tabPage3.Controls.Add(this.labelVersion); - this.tabPage3.Controls.Add(this.label9); - this.tabPage3.Controls.Add(this.pictureBox1); - this.tabPage3.Location = new System.Drawing.Point(4, 24); - this.tabPage3.Name = "tabPage3"; - this.tabPage3.Size = new System.Drawing.Size(331, 307); - this.tabPage3.TabIndex = 2; - this.tabPage3.Text = "About"; + // loggingTabPage + // + this.loggingTabPage.BackColor = System.Drawing.SystemColors.Control; + this.loggingTabPage.Controls.Add(this.LoggingGroupBox); + this.loggingTabPage.Controls.Add(this.EnableLoggingCheckbox); + this.loggingTabPage.Location = new System.Drawing.Point(4, 24); + this.loggingTabPage.Name = "loggingTabPage"; + this.loggingTabPage.Padding = new System.Windows.Forms.Padding(10); + this.loggingTabPage.Size = new System.Drawing.Size(331, 307); + this.loggingTabPage.TabIndex = 3; + this.loggingTabPage.Text = "Logging"; + // + // LoggingGroupBox + // + this.LoggingGroupBox.Controls.Add(this.ExploreButton); + this.LoggingGroupBox.Controls.Add(this.LogPathTextBox); + this.LoggingGroupBox.Controls.Add(this.LogPathPickerButton); + this.LoggingGroupBox.Controls.Add(this.label12); + this.LoggingGroupBox.Location = new System.Drawing.Point(13, 35); + this.LoggingGroupBox.Name = "LoggingGroupBox"; + this.LoggingGroupBox.Padding = new System.Windows.Forms.Padding(3, 13, 3, 3); + this.LoggingGroupBox.Size = new System.Drawing.Size(305, 259); + this.LoggingGroupBox.TabIndex = 1; + this.LoggingGroupBox.TabStop = false; + this.LoggingGroupBox.Text = "Logging Options"; + // + // LogPathTextBox + // + this.LogPathTextBox.Location = new System.Drawing.Point(57, 24); + this.LogPathTextBox.Name = "LogPathTextBox"; + this.LogPathTextBox.Size = new System.Drawing.Size(211, 21); + this.LogPathTextBox.TabIndex = 2; + // + // LogPathPickerButton + // + this.LogPathPickerButton.Location = new System.Drawing.Point(274, 23); + this.LogPathPickerButton.Name = "LogPathPickerButton"; + this.LogPathPickerButton.Size = new System.Drawing.Size(25, 23); + this.LogPathPickerButton.TabIndex = 1; + this.LogPathPickerButton.Text = "..."; + this.LogPathPickerButton.UseVisualStyleBackColor = true; + this.LogPathPickerButton.Click += new System.EventHandler(this.LogPathPickerButton_Click); + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(6, 27); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(45, 15); + this.label12.TabIndex = 0; + this.label12.Text = "Log dir"; + // + // EnableLoggingCheckbox + // + this.EnableLoggingCheckbox.AutoSize = true; + this.EnableLoggingCheckbox.Location = new System.Drawing.Point(10, 10); + this.EnableLoggingCheckbox.Name = "EnableLoggingCheckbox"; + this.EnableLoggingCheckbox.Size = new System.Drawing.Size(113, 19); + this.EnableLoggingCheckbox.TabIndex = 0; + this.EnableLoggingCheckbox.Text = "Enable Logging"; + this.EnableLoggingCheckbox.UseVisualStyleBackColor = true; + this.EnableLoggingCheckbox.CheckedChanged += new System.EventHandler(this.EnableLoggingCheckbox_CheckedChanged); + // + // aboutTabPage + // + this.aboutTabPage.BackColor = System.Drawing.SystemColors.Control; + this.aboutTabPage.Controls.Add(this.linkLabel1); + this.aboutTabPage.Controls.Add(this.labelVersion); + this.aboutTabPage.Controls.Add(this.label9); + this.aboutTabPage.Controls.Add(this.pictureBox1); + this.aboutTabPage.Location = new System.Drawing.Point(4, 24); + this.aboutTabPage.Name = "aboutTabPage"; + this.aboutTabPage.Size = new System.Drawing.Size(331, 307); + this.aboutTabPage.TabIndex = 2; + this.aboutTabPage.Text = "About"; // // linkLabel1 // @@ -556,15 +639,15 @@ private void InitializeComponent() this.pictureBox1.TabIndex = 0; this.pictureBox1.TabStop = false; // - // cbOfflineCounter + // ExploreButton // - this.cbOfflineCounter.AutoSize = true; - this.cbOfflineCounter.Location = new System.Drawing.Point(6, 255); - this.cbOfflineCounter.Name = "cbOfflineCounter"; - this.cbOfflineCounter.Size = new System.Drawing.Size(132, 19); - this.cbOfflineCounter.TabIndex = 14; - this.cbOfflineCounter.Text = "Offline time counter"; - this.cbOfflineCounter.UseVisualStyleBackColor = true; + this.ExploreButton.Location = new System.Drawing.Point(9, 54); + this.ExploreButton.Name = "ExploreButton"; + this.ExploreButton.Size = new System.Drawing.Size(289, 23); + this.ExploreButton.TabIndex = 3; + this.ExploreButton.Text = "View Log Directory in Explorer"; + this.ExploreButton.UseVisualStyleBackColor = true; + this.ExploreButton.Click += new System.EventHandler(this.ExploreButton_Click); // // Setting // @@ -595,8 +678,12 @@ private void InitializeComponent() this.groupBox2.PerformLayout(); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); - this.tabPage3.ResumeLayout(false); - this.tabPage3.PerformLayout(); + this.loggingTabPage.ResumeLayout(false); + this.loggingTabPage.PerformLayout(); + this.LoggingGroupBox.ResumeLayout(false); + this.LoggingGroupBox.PerformLayout(); + this.aboutTabPage.ResumeLayout(false); + this.aboutTabPage.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.ResumeLayout(false); @@ -629,7 +716,7 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox alarmConnectionLost; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.CheckBox alarmResumed; - private System.Windows.Forms.TabPage tabPage3; + private System.Windows.Forms.TabPage aboutTabPage; private System.Windows.Forms.LinkLabel linkLabel1; private System.Windows.Forms.Label labelVersion; private System.Windows.Forms.Label label9; @@ -646,5 +733,12 @@ private void InitializeComponent() private System.Windows.Forms.Button connectionLostSFXBtn; private System.Windows.Forms.CheckBox cbStartupRun; private System.Windows.Forms.CheckBox cbOfflineCounter; + private System.Windows.Forms.TabPage loggingTabPage; + private System.Windows.Forms.CheckBox EnableLoggingCheckbox; + private System.Windows.Forms.GroupBox LoggingGroupBox; + private System.Windows.Forms.Button LogPathPickerButton; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.TextBox LogPathTextBox; + private System.Windows.Forms.Button ExploreButton; } } \ No newline at end of file diff --git a/Setting.cs b/Setting.cs index b40b329..7b13df8 100644 --- a/Setting.cs +++ b/Setting.cs @@ -34,6 +34,8 @@ public Setting() Config.RunOnStartup = false; } + InitLoggingGroup(); + loaded = true; } @@ -55,7 +57,9 @@ private void SyncToConfig(IPAddress address) _SFXConnectionLost: toolTip1.GetToolTip(connectionLostSFXBtn), _SFXTimeOut: toolTip1.GetToolTip(pingTimeoutSFXBtn), _SFXResumed: toolTip1.GetToolTip(connectionResumeSFXBtn), - offlineCounter: cbOfflineCounter.Checked); + offlineCounter: cbOfflineCounter.Checked, + enableLogging: EnableLoggingCheckbox.Checked, + logPath: LogPathTextBox.Text); } private void SyncFromConfig() @@ -83,6 +87,9 @@ private void SyncFromConfig() SetSoundInfoForButtom(pingTimeoutSFXBtn, Config.SFXTimeOut); SetSoundInfoForButtom(connectionLostSFXBtn, Config.SFXConnectionLost); SetSoundInfoForButtom(connectionResumeSFXBtn, Config.SFXResumed); + + EnableLoggingCheckbox.Checked = Config.EnableLogging; + LogPathTextBox.Text = Config.LogDirPath; } private void ClearSFX(Button button, MouseEventArgs mouseEvent) @@ -227,5 +234,48 @@ private void numbersModeCheckBox_CheckedChanged(object sender, EventArgs e) { graphColorsGroupBox.Visible = !numbersModeCheckBox.Checked; } + + private string DefaultLoggingPath => $@"%LOCALAPPDATA%\{Process.GetCurrentProcess().ProcessName}\Logs"; + + private void InitLoggingGroup() + { + LoggingGroupBox.Visible = EnableLoggingCheckbox.Checked; + if (EnableLoggingCheckbox.Checked) + { + if (string.IsNullOrWhiteSpace(LogPathTextBox.Text)) + { + string resolvedPath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(DefaultLoggingPath)); + LogPathTextBox.Text = resolvedPath; + } + } + else + { + LogPathTextBox.Text = ""; + } + } + + private void EnableLoggingCheckbox_CheckedChanged(object sender, EventArgs e) + { + InitLoggingGroup(); + } + + private void LogPathPickerButton_Click(object sender, EventArgs e) + { + using (var fbd = new FolderBrowserDialog()) + { + fbd.RootFolder = Environment.SpecialFolder.LocalApplicationData; + DialogResult result = fbd.ShowDialog(); + + if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath)) + { + LogPathTextBox.Text = fbd.SelectedPath; + } + } + } + + private void ExploreButton_Click(object sender, EventArgs e) + { + Process.Start("explorer.exe", LogPathTextBox.Text); + } } }