[FancyZones Editor] Logger (#13928)
This commit is contained in:
parent
a93dc423f0
commit
91ed50d993
|
@ -3,16 +3,12 @@
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Utils;
|
using FancyZonesEditor.Utils;
|
||||||
using ManagedCommon;
|
using ManagedCommon;
|
||||||
using Microsoft.PowerToys.Common.UI;
|
using Microsoft.PowerToys.Common.UI;
|
||||||
|
@ -25,26 +21,7 @@ namespace FancyZonesEditor
|
||||||
public partial class App : Application, IDisposable
|
public partial class App : Application, IDisposable
|
||||||
{
|
{
|
||||||
// Non-localizable strings
|
// Non-localizable strings
|
||||||
private const string CrashReportLogFile = "FZEditorCrashLog.txt";
|
|
||||||
private const string ErrorReportLogFile = "FZEditorErrorLog.txt";
|
|
||||||
private const string PowerToysIssuesURL = "https://aka.ms/powerToysReportBug";
|
private const string PowerToysIssuesURL = "https://aka.ms/powerToysReportBug";
|
||||||
|
|
||||||
private const string CrashReportExceptionTag = "Exception";
|
|
||||||
private const string CrashReportSourceTag = "Source: ";
|
|
||||||
private const string CrashReportTargetAssemblyTag = "TargetAssembly: ";
|
|
||||||
private const string CrashReportTargetModuleTag = "TargetModule: ";
|
|
||||||
private const string CrashReportTargetSiteTag = "TargetSite: ";
|
|
||||||
private const string CrashReportEnvironmentTag = "Environment";
|
|
||||||
private const string CrashReportCommandLineTag = "* Command Line: ";
|
|
||||||
private const string CrashReportTimestampTag = "* Timestamp: ";
|
|
||||||
private const string CrashReportOSVersionTag = "* OS Version: ";
|
|
||||||
private const string CrashReportIntPtrLengthTag = "* IntPtr Length: ";
|
|
||||||
private const string CrashReportx64Tag = "* x64: ";
|
|
||||||
private const string CrashReportCLRVersionTag = "* CLR Version: ";
|
|
||||||
private const string CrashReportAssembliesTag = "Assemblies - ";
|
|
||||||
private const string CrashReportDynamicAssemblyTag = "dynamic assembly doesn't have location";
|
|
||||||
private const string CrashReportLocationNullTag = "location is null or empty";
|
|
||||||
|
|
||||||
private const string ParsingErrorReportTag = "Settings parsing error";
|
private const string ParsingErrorReportTag = "Settings parsing error";
|
||||||
private const string ParsingErrorDataTag = "Data: ";
|
private const string ParsingErrorDataTag = "Data: ";
|
||||||
|
|
||||||
|
@ -89,9 +66,12 @@ namespace FancyZonesEditor
|
||||||
_eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, interop.Constants.FZEExitEvent());
|
_eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, interop.Constants.FZEExitEvent());
|
||||||
if (_eventHandle.WaitOne())
|
if (_eventHandle.WaitOne())
|
||||||
{
|
{
|
||||||
|
Logger.LogInfo("FancyZones disabled, exit");
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
}).Start();
|
}).Start();
|
||||||
|
|
||||||
|
Logger.LogInfo("FancyZones Editor started");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStartup(object sender, StartupEventArgs e)
|
private void OnStartup(object sender, StartupEventArgs e)
|
||||||
|
@ -100,6 +80,7 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>
|
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>
|
||||||
{
|
{
|
||||||
|
Logger.LogInfo("Runner exited");
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -139,15 +120,7 @@ namespace FancyZonesEditor
|
||||||
// Error message if parsing failed
|
// Error message if parsing failed
|
||||||
if (!parseResult.Result)
|
if (!parseResult.Result)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
Logger.LogError(ParsingErrorReportTag + ": " + parseResult.Message + "; " + ParsingErrorDataTag + ": " + parseResult.MalformedData);
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("## " + ParsingErrorReportTag);
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine(parseResult.Message);
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine(ParsingErrorDataTag);
|
|
||||||
sb.AppendLine(parseResult.MalformedData);
|
|
||||||
|
|
||||||
MessageBox.Show(parseResult.Message, FancyZonesEditor.Properties.Resources.Error_Parsing_Zones_Settings_Title, MessageBoxButton.OK);
|
MessageBox.Show(parseResult.Message, FancyZonesEditor.Properties.Resources.Error_Parsing_Zones_Settings_Title, MessageBoxButton.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +136,8 @@ namespace FancyZonesEditor
|
||||||
{
|
{
|
||||||
_eventHandle.Set();
|
_eventHandle.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.LogInfo("FancyZones Editor exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void App_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
|
public void App_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
|
||||||
|
@ -197,126 +172,20 @@ namespace FancyZonesEditor
|
||||||
MessageBox.Show(fullMessage, FancyZonesEditor.Properties.Resources.Error_Exception_Message_Box_Title);
|
MessageBox.Show(fullMessage, FancyZonesEditor.Properties.Resources.Error_Exception_Message_Box_Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShowExceptionReportMessageBox(string reportData)
|
|
||||||
{
|
|
||||||
var fileStream = File.OpenWrite(ErrorReportLogFile);
|
|
||||||
using (var sw = new StreamWriter(fileStream))
|
|
||||||
{
|
|
||||||
sw.Write(reportData);
|
|
||||||
sw.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
fileStream.Close();
|
|
||||||
|
|
||||||
ShowReportMessageBox(fileStream.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
|
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
|
||||||
{
|
{
|
||||||
var fileStream = File.OpenWrite(CrashReportLogFile);
|
Logger.LogError("Unhandled exception", (Exception)args.ExceptionObject);
|
||||||
using (var sw = new StreamWriter(fileStream))
|
ShowReportMessageBox();
|
||||||
{
|
|
||||||
sw.Write(FormatException((Exception)args.ExceptionObject));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fileStream.Close();
|
private static void ShowReportMessageBox()
|
||||||
|
|
||||||
ShowReportMessageBox(fileStream.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowReportMessageBox(string fileName)
|
|
||||||
{
|
{
|
||||||
MessageBox.Show(
|
MessageBox.Show(
|
||||||
FancyZonesEditor.Properties.Resources.Crash_Report_Message_Box_Text_Part1 +
|
FancyZonesEditor.Properties.Resources.Crash_Report_Message_Box_Text +
|
||||||
Path.GetFullPath(fileName) +
|
|
||||||
"\n" +
|
|
||||||
FancyZonesEditor.Properties.Resources.Crash_Report_Message_Box_Text_Part2 +
|
|
||||||
PowerToysIssuesURL,
|
PowerToysIssuesURL,
|
||||||
FancyZonesEditor.Properties.Resources.Fancy_Zones_Editor_App_Title);
|
FancyZonesEditor.Properties.Resources.Fancy_Zones_Editor_App_Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string FormatException(Exception ex)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("## " + CrashReportExceptionTag);
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("```");
|
|
||||||
|
|
||||||
var exlist = new List<StringBuilder>();
|
|
||||||
|
|
||||||
while (ex != null)
|
|
||||||
{
|
|
||||||
var exsb = new StringBuilder();
|
|
||||||
exsb.Append(ex.GetType().FullName);
|
|
||||||
exsb.Append(": ");
|
|
||||||
exsb.AppendLine(ex.Message);
|
|
||||||
if (ex.Source != null)
|
|
||||||
{
|
|
||||||
exsb.Append(" " + CrashReportSourceTag);
|
|
||||||
exsb.AppendLine(ex.Source);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ex.TargetSite != null)
|
|
||||||
{
|
|
||||||
exsb.Append(" " + CrashReportTargetAssemblyTag);
|
|
||||||
exsb.AppendLine(ex.TargetSite.Module.Assembly.ToString());
|
|
||||||
exsb.Append(" " + CrashReportTargetModuleTag);
|
|
||||||
exsb.AppendLine(ex.TargetSite.Module.ToString());
|
|
||||||
exsb.Append(" " + CrashReportTargetSiteTag);
|
|
||||||
exsb.AppendLine(ex.TargetSite.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
exsb.AppendLine(ex.StackTrace);
|
|
||||||
exlist.Add(exsb);
|
|
||||||
|
|
||||||
ex = ex.InnerException;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var result in exlist.Select(o => o.ToString()).Reverse())
|
|
||||||
{
|
|
||||||
sb.AppendLine(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine("```");
|
|
||||||
sb.AppendLine();
|
|
||||||
|
|
||||||
sb.AppendLine("## " + CrashReportEnvironmentTag);
|
|
||||||
sb.AppendLine(CrashReportCommandLineTag + Environment.CommandLine);
|
|
||||||
|
|
||||||
// Using InvariantCulture since this is used for a timestamp internally
|
|
||||||
sb.AppendLine(CrashReportTimestampTag + DateTime.Now.ToString(CultureInfo.InvariantCulture));
|
|
||||||
sb.AppendLine(CrashReportOSVersionTag + Environment.OSVersion.VersionString);
|
|
||||||
sb.AppendLine(CrashReportIntPtrLengthTag + IntPtr.Size);
|
|
||||||
sb.AppendLine(CrashReportx64Tag + Environment.Is64BitOperatingSystem);
|
|
||||||
sb.AppendLine(CrashReportCLRVersionTag + Environment.Version);
|
|
||||||
sb.AppendLine("## " + CrashReportAssembliesTag + AppDomain.CurrentDomain.FriendlyName);
|
|
||||||
sb.AppendLine();
|
|
||||||
foreach (var ass in AppDomain.CurrentDomain.GetAssemblies().OrderBy(o => o.GlobalAssemblyCache ? 50 : 0))
|
|
||||||
{
|
|
||||||
sb.Append("* ");
|
|
||||||
sb.Append(ass.FullName);
|
|
||||||
sb.Append(" (");
|
|
||||||
|
|
||||||
if (ass.IsDynamic)
|
|
||||||
{
|
|
||||||
sb.Append(CrashReportDynamicAssemblyTag);
|
|
||||||
}
|
|
||||||
else if (string.IsNullOrEmpty(ass.Location))
|
|
||||||
{
|
|
||||||
sb.Append(CrashReportLocationNullTag);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.Append(ass.Location);
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!_isDisposed)
|
if (!_isDisposed)
|
||||||
|
@ -329,6 +198,7 @@ namespace FancyZonesEditor
|
||||||
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
||||||
// TODO: set large fields to null
|
// TODO: set large fields to null
|
||||||
_isDisposed = true;
|
_isDisposed = true;
|
||||||
|
Logger.LogInfo("FancyZones Editor disposed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
|
|
||||||
namespace FancyZonesEditor
|
namespace FancyZonesEditor
|
||||||
|
@ -34,11 +35,13 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void OnAddZone(object sender, RoutedEventArgs e)
|
private void OnAddZone(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogInfo("Add zone");
|
||||||
_model.AddZone();
|
_model.AddZone();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected new void OnCancel(object sender, RoutedEventArgs e)
|
protected new void OnCancel(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogInfo("Cancel changes");
|
||||||
base.OnCancel(sender, e);
|
base.OnCancel(sender, e);
|
||||||
_stashedModel.RestoreTo(_model);
|
_stashedModel.RestoreTo(_model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
|
|
||||||
namespace FancyZonesEditor
|
namespace FancyZonesEditor
|
||||||
|
@ -12,6 +13,7 @@ namespace FancyZonesEditor
|
||||||
{
|
{
|
||||||
protected void OnSaveApplyTemplate(object sender, RoutedEventArgs e)
|
protected void OnSaveApplyTemplate(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
var mainEditor = App.Overlay;
|
var mainEditor = App.Overlay;
|
||||||
if (mainEditor.CurrentDataContext is LayoutModel model)
|
if (mainEditor.CurrentDataContext is LayoutModel model)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
|
|
||||||
namespace FancyZonesEditor
|
namespace FancyZonesEditor
|
||||||
|
@ -417,6 +418,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
public void DoMerge(List<int> indices)
|
public void DoMerge(List<int> indices)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (indices.Count == 0)
|
if (indices.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -455,6 +458,7 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
public void Split(int zoneIndex, int position, Orientation orientation)
|
public void Split(int zoneIndex, int position, Orientation orientation)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
if (!CanSplit(zoneIndex, position, orientation))
|
if (!CanSplit(zoneIndex, position, orientation))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -519,6 +523,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
public void Drag(int resizerIndex, int delta)
|
public void Drag(int resizerIndex, int delta)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (!CanDrag(resizerIndex, delta))
|
if (!CanDrag(resizerIndex, delta))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -10,6 +10,7 @@ using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Controls.Primitives;
|
using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
|
|
||||||
namespace FancyZonesEditor
|
namespace FancyZonesEditor
|
||||||
|
@ -316,6 +317,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void OnSplit(object sender, SplitEventArgs args)
|
private void OnSplit(object sender, SplitEventArgs args)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
MergeCancelClick(null, null);
|
MergeCancelClick(null, null);
|
||||||
|
|
||||||
var zonePanel = sender as GridZone;
|
var zonePanel = sender as GridZone;
|
||||||
|
@ -488,6 +491,7 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void OnMergeComplete(object o, MouseButtonEventArgs e)
|
private void OnMergeComplete(object o, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
_inMergeDrag = false;
|
_inMergeDrag = false;
|
||||||
|
|
||||||
var selectedIndices = new List<int>();
|
var selectedIndices = new List<int>();
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
|
|
||||||
namespace FancyZonesEditor
|
namespace FancyZonesEditor
|
||||||
|
@ -83,6 +84,11 @@ namespace FancyZonesEditor
|
||||||
{
|
{
|
||||||
_model = (LayoutModel)DataContext;
|
_model = (LayoutModel)DataContext;
|
||||||
|
|
||||||
|
if (_model != null)
|
||||||
|
{
|
||||||
|
Logger.LogInfo("Loaded " + _model.Name);
|
||||||
|
}
|
||||||
|
|
||||||
RenderPreview();
|
RenderPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
101
src/modules/fancyzones/editor/FancyZonesEditor/Logs/Logger.cs
Normal file
101
src/modules/fancyzones/editor/FancyZonesEditor/Logs/Logger.cs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Abstractions;
|
||||||
|
using System.Reflection;
|
||||||
|
using interop;
|
||||||
|
|
||||||
|
namespace FancyZonesEditor.Logs
|
||||||
|
{
|
||||||
|
public static class Logger
|
||||||
|
{
|
||||||
|
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||||
|
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
|
||||||
|
public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location).ProductVersion;
|
||||||
|
private static readonly string ApplicationLogPath = Path.Combine(Constants.AppDataPath(), "FancyZones\\Editor\\Logs\\", Version);
|
||||||
|
|
||||||
|
private static readonly string Error = "Error";
|
||||||
|
private static readonly string Warning = "Warning";
|
||||||
|
private static readonly string Info = "Info";
|
||||||
|
private static readonly string Debug = "Debug";
|
||||||
|
private static readonly string TraceFlag = "Trace";
|
||||||
|
|
||||||
|
static Logger()
|
||||||
|
{
|
||||||
|
if (!_fileSystem.Directory.Exists(ApplicationLogPath))
|
||||||
|
{
|
||||||
|
_fileSystem.Directory.CreateDirectory(ApplicationLogPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using InvariantCulture since this is used for a log file name
|
||||||
|
var logFilePath = _fileSystem.Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".txt");
|
||||||
|
|
||||||
|
Trace.Listeners.Add(new TextWriterTraceListener(logFilePath));
|
||||||
|
|
||||||
|
Trace.AutoFlush = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogError(string message)
|
||||||
|
{
|
||||||
|
Log(message, Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogError(string message, Exception ex)
|
||||||
|
{
|
||||||
|
Log(
|
||||||
|
message + Environment.NewLine +
|
||||||
|
ex?.Message + Environment.NewLine +
|
||||||
|
"Inner exception: " + Environment.NewLine +
|
||||||
|
ex?.InnerException?.Message + Environment.NewLine +
|
||||||
|
"Stack trace: " + Environment.NewLine +
|
||||||
|
ex?.StackTrace,
|
||||||
|
Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogWarning(string message)
|
||||||
|
{
|
||||||
|
Log(message, Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogInfo(string message)
|
||||||
|
{
|
||||||
|
Log(message, Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogDebug(string message)
|
||||||
|
{
|
||||||
|
Log(message, Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogTrace()
|
||||||
|
{
|
||||||
|
Log(string.Empty, TraceFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Log(string message, string type)
|
||||||
|
{
|
||||||
|
Trace.WriteLine("[" + DateTime.Now.TimeOfDay + "] [" + type + "] " + GetCallerInfo());
|
||||||
|
Trace.Indent();
|
||||||
|
if (message != string.Empty)
|
||||||
|
{
|
||||||
|
Trace.WriteLine(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace.Unindent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetCallerInfo()
|
||||||
|
{
|
||||||
|
StackTrace stackTrace = new StackTrace();
|
||||||
|
|
||||||
|
var methodName = stackTrace.GetFrame(3)?.GetMethod();
|
||||||
|
var className = methodName?.DeclaringType.Name;
|
||||||
|
return className + " :: " + methodName?.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ using System.Windows.Automation;
|
||||||
using System.Windows.Automation.Peers;
|
using System.Windows.Automation.Peers;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
using FancyZonesEditor.Utils;
|
using FancyZonesEditor.Utils;
|
||||||
using Microsoft.PowerToys.Common.UI;
|
using Microsoft.PowerToys.Common.UI;
|
||||||
|
@ -164,6 +165,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private async void NewLayoutButton_Click(object sender, RoutedEventArgs e)
|
private async void NewLayoutButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (_openedDialog != null)
|
if (_openedDialog != null)
|
||||||
{
|
{
|
||||||
// another dialog already opened
|
// another dialog already opened
|
||||||
|
@ -195,6 +198,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void DuplicateLayout_Click(object sender, RoutedEventArgs e)
|
private void DuplicateLayout_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
EditLayoutDialog.Hide();
|
EditLayoutDialog.Hide();
|
||||||
|
|
||||||
var mainEditor = App.Overlay;
|
var mainEditor = App.Overlay;
|
||||||
|
@ -261,6 +266,7 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void Apply()
|
private void Apply()
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
var mainEditor = App.Overlay;
|
var mainEditor = App.Overlay;
|
||||||
if (mainEditor.CurrentDataContext is LayoutModel model)
|
if (mainEditor.CurrentDataContext is LayoutModel model)
|
||||||
{
|
{
|
||||||
|
@ -272,6 +278,7 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void OnClosing(object sender, EventArgs e)
|
private void OnClosing(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
CancelLayoutChanges();
|
CancelLayoutChanges();
|
||||||
|
|
||||||
App.FancyZonesEditorIO.SerializeZoneSettings();
|
App.FancyZonesEditorIO.SerializeZoneSettings();
|
||||||
|
@ -281,12 +288,15 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void DeleteLayout_Click(object sender, RoutedEventArgs e)
|
private void DeleteLayout_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
EditLayoutDialog.Hide();
|
EditLayoutDialog.Hide();
|
||||||
DeleteLayout((FrameworkElement)sender);
|
DeleteLayout((FrameworkElement)sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void EditLayout_Click(object sender, RoutedEventArgs e)
|
private async void EditLayout_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
// Avoid trying to open the same dialog twice.
|
// Avoid trying to open the same dialog twice.
|
||||||
if (_openedDialog != null)
|
if (_openedDialog != null)
|
||||||
{
|
{
|
||||||
|
@ -310,6 +320,7 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void EditZones_Click(object sender, RoutedEventArgs e)
|
private void EditZones_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
var dataContext = ((FrameworkElement)sender).DataContext;
|
var dataContext = ((FrameworkElement)sender).DataContext;
|
||||||
Select((LayoutModel)dataContext);
|
Select((LayoutModel)dataContext);
|
||||||
EditLayoutDialog.Hide();
|
EditLayoutDialog.Hide();
|
||||||
|
@ -342,6 +353,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog sender, ModernWpf.Controls.ContentDialogButtonClickEventArgs args)
|
private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog sender, ModernWpf.Controls.ContentDialogButtonClickEventArgs args)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
LayoutModel selectedLayoutModel;
|
LayoutModel selectedLayoutModel;
|
||||||
|
|
||||||
if (GridLayoutRadioButton.IsChecked == true)
|
if (GridLayoutRadioButton.IsChecked == true)
|
||||||
|
@ -393,6 +406,8 @@ namespace FancyZonesEditor
|
||||||
// EditLayout: Save changes
|
// EditLayout: Save changes
|
||||||
private void EditLayoutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
private void EditLayoutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
var mainEditor = App.Overlay;
|
var mainEditor = App.Overlay;
|
||||||
if (!(mainEditor.CurrentDataContext is LayoutModel model))
|
if (!(mainEditor.CurrentDataContext is LayoutModel model))
|
||||||
{
|
{
|
||||||
|
@ -415,6 +430,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
private async void DeleteLayout(FrameworkElement element)
|
private async void DeleteLayout(FrameworkElement element)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
var dialog = new ContentDialog()
|
var dialog = new ContentDialog()
|
||||||
{
|
{
|
||||||
Title = Properties.Resources.Are_You_Sure,
|
Title = Properties.Resources.Are_You_Sure,
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
|
|
||||||
namespace FancyZonesEditor
|
namespace FancyZonesEditor
|
||||||
|
@ -134,6 +135,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
public void Show()
|
public void Show()
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
var mainWindowSettings = ((App)Application.Current).MainWindowSettings;
|
var mainWindowSettings = ((App)Application.Current).MainWindowSettings;
|
||||||
if (_layoutPreview != null)
|
if (_layoutPreview != null)
|
||||||
{
|
{
|
||||||
|
@ -154,6 +157,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
public void ShowLayout()
|
public void ShowLayout()
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings;
|
MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings;
|
||||||
CurrentDataContext = settings.UpdateSelectedLayoutModel();
|
CurrentDataContext = settings.UpdateSelectedLayoutModel();
|
||||||
|
|
||||||
|
@ -201,6 +206,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
public void OpenEditor(LayoutModel model)
|
public void OpenEditor(LayoutModel model)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
_layoutPreview = null;
|
_layoutPreview = null;
|
||||||
if (CurrentDataContext is GridLayoutModel)
|
if (CurrentDataContext is GridLayoutModel)
|
||||||
{
|
{
|
||||||
|
@ -229,6 +236,8 @@ namespace FancyZonesEditor
|
||||||
|
|
||||||
public void CloseEditor()
|
public void CloseEditor()
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
var mainWindowSettings = ((App)Application.Current).MainWindowSettings;
|
var mainWindowSettings = ((App)Application.Current).MainWindowSettings;
|
||||||
|
|
||||||
_editorLayout = null;
|
_editorLayout = null;
|
||||||
|
|
|
@ -150,21 +150,12 @@ namespace FancyZonesEditor.Properties {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to Error logged to .
|
|
||||||
/// </summary>
|
|
||||||
public static string Crash_Report_Message_Box_Text_Part1 {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("Crash_Report_Message_Box_Text_Part1", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Please report the bug to .
|
/// Looks up a localized string similar to Please report the bug to .
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Crash_Report_Message_Box_Text_Part2 {
|
public static string Crash_Report_Message_Box_Text {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("Crash_Report_Message_Box_Text_Part2", resourceCulture);
|
return ResourceManager.GetString("Crash_Report_Message_Box_Text", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,10 +135,7 @@
|
||||||
<data name="Grid_Layout_Editor" xml:space="preserve">
|
<data name="Grid_Layout_Editor" xml:space="preserve">
|
||||||
<value>Grid layout editor</value>
|
<value>Grid layout editor</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Crash_Report_Message_Box_Text_Part1" xml:space="preserve">
|
<data name="Crash_Report_Message_Box_Text" xml:space="preserve">
|
||||||
<value>Error logged to </value>
|
|
||||||
</data>
|
|
||||||
<data name="Crash_Report_Message_Box_Text_Part2" xml:space="preserve">
|
|
||||||
<value>Please report the bug to </value>
|
<value>Please report the bug to </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Custom" xml:space="preserve">
|
<data name="Custom" xml:space="preserve">
|
||||||
|
|
|
@ -11,6 +11,7 @@ using System.IO.Abstractions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using FancyZonesEditor.Logs;
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
|
|
||||||
namespace FancyZonesEditor.Utils
|
namespace FancyZonesEditor.Utils
|
||||||
|
@ -247,6 +248,8 @@ namespace FancyZonesEditor.Utils
|
||||||
// All strings in this function shouldn't be localized.
|
// All strings in this function shouldn't be localized.
|
||||||
public static void ParseCommandLineArguments()
|
public static void ParseCommandLineArguments()
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
string[] args = Environment.GetCommandLineArgs();
|
string[] args = Environment.GetCommandLineArgs();
|
||||||
|
|
||||||
if (args.Length < 2 && !App.DebugMode)
|
if (args.Length < 2 && !App.DebugMode)
|
||||||
|
@ -399,8 +402,9 @@ namespace FancyZonesEditor.Utils
|
||||||
App.Overlay.Monitors.Add(monitor);
|
App.Overlay.Monitors.Add(monitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Logger.LogError("Invalid command line arguments: " + args[1], ex);
|
||||||
MessageBox.Show(Properties.Resources.Error_Invalid_Arguments, Properties.Resources.Error_Message_Box_Title);
|
MessageBox.Show(Properties.Resources.Error_Invalid_Arguments, Properties.Resources.Error_Message_Box_Title);
|
||||||
((App)Application.Current).Shutdown();
|
((App)Application.Current).Shutdown();
|
||||||
}
|
}
|
||||||
|
@ -408,6 +412,8 @@ namespace FancyZonesEditor.Utils
|
||||||
|
|
||||||
public ParsingResult ParseParams()
|
public ParsingResult ParseParams()
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (_fileSystem.File.Exists(FancyZonesEditorParamsFile))
|
if (_fileSystem.File.Exists(FancyZonesEditorParamsFile))
|
||||||
{
|
{
|
||||||
string data = string.Empty;
|
string data = string.Empty;
|
||||||
|
@ -471,6 +477,7 @@ namespace FancyZonesEditor.Utils
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Logger.LogError("Editor params parsing error", ex);
|
||||||
return new ParsingResult(false, ex.Message, data);
|
return new ParsingResult(false, ex.Message, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,6 +491,8 @@ namespace FancyZonesEditor.Utils
|
||||||
|
|
||||||
public ParsingResult ParseZoneSettings()
|
public ParsingResult ParseZoneSettings()
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
_unusedDevices.Clear();
|
_unusedDevices.Clear();
|
||||||
|
|
||||||
if (_fileSystem.File.Exists(FancyZonesSettingsFile))
|
if (_fileSystem.File.Exists(FancyZonesSettingsFile))
|
||||||
|
@ -498,6 +507,7 @@ namespace FancyZonesEditor.Utils
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Logger.LogError("Zone settings parsing error", ex);
|
||||||
return new ParsingResult(false, ex.Message, settingsString);
|
return new ParsingResult(false, ex.Message, settingsString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,6 +525,7 @@ namespace FancyZonesEditor.Utils
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Logger.LogError("Zone settings parsing error", ex);
|
||||||
return new ParsingResult(false, ex.Message, settingsString);
|
return new ParsingResult(false, ex.Message, settingsString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,6 +535,8 @@ namespace FancyZonesEditor.Utils
|
||||||
|
|
||||||
public void SerializeZoneSettings()
|
public void SerializeZoneSettings()
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
ZoneSettingsWrapper zoneSettings = new ZoneSettingsWrapper { };
|
ZoneSettingsWrapper zoneSettings = new ZoneSettingsWrapper { };
|
||||||
zoneSettings.Devices = new List<DeviceWrapper>();
|
zoneSettings.Devices = new List<DeviceWrapper>();
|
||||||
zoneSettings.CustomZoneSets = new List<CustomLayoutWrapper>();
|
zoneSettings.CustomZoneSets = new List<CustomLayoutWrapper>();
|
||||||
|
@ -680,8 +693,9 @@ namespace FancyZonesEditor.Utils
|
||||||
|
|
||||||
zoneSettings.QuickLayoutKeys.Add(wrapper);
|
zoneSettings.QuickLayoutKeys.Add(wrapper);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Logger.LogError("Serialize quick layout keys error", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,12 +707,15 @@ namespace FancyZonesEditor.Utils
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Logger.LogError("Serialize zone settings error", ex);
|
||||||
App.ShowExceptionMessageBox(Properties.Resources.Error_Applying_Layout, ex);
|
App.ShowExceptionMessageBox(Properties.Resources.Error_Applying_Layout, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ReadFile(string fileName)
|
private string ReadFile(string fileName)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
Stream inputStream = _fileSystem.File.Open(fileName, FileMode.Open);
|
Stream inputStream = _fileSystem.File.Open(fileName, FileMode.Open);
|
||||||
using (StreamReader reader = new StreamReader(inputStream))
|
using (StreamReader reader = new StreamReader(inputStream))
|
||||||
{
|
{
|
||||||
|
@ -710,6 +727,8 @@ namespace FancyZonesEditor.Utils
|
||||||
|
|
||||||
private bool SetDevices(List<DeviceWrapper> devices)
|
private bool SetDevices(List<DeviceWrapper> devices)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (devices == null)
|
if (devices == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -763,6 +782,8 @@ namespace FancyZonesEditor.Utils
|
||||||
|
|
||||||
private bool SetCustomLayouts(List<CustomLayoutWrapper> customLayouts)
|
private bool SetCustomLayouts(List<CustomLayoutWrapper> customLayouts)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (customLayouts == null)
|
if (customLayouts == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -791,9 +812,10 @@ namespace FancyZonesEditor.Utils
|
||||||
layout = ParseGridInfo(zoneSet);
|
layout = ParseGridInfo(zoneSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
|
Logger.LogError("Parse custom layout error", ex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,6 +835,8 @@ namespace FancyZonesEditor.Utils
|
||||||
|
|
||||||
private bool SetTemplateLayouts(List<TemplateLayoutWrapper> templateLayouts)
|
private bool SetTemplateLayouts(List<TemplateLayoutWrapper> templateLayouts)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (templateLayouts == null)
|
if (templateLayouts == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -840,6 +864,8 @@ namespace FancyZonesEditor.Utils
|
||||||
|
|
||||||
private bool SetQuickLayoutSwitchKeys(List<QuickLayoutKeysWrapper> quickSwitchKeys)
|
private bool SetQuickLayoutSwitchKeys(List<QuickLayoutKeysWrapper> quickSwitchKeys)
|
||||||
{
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (quickSwitchKeys == null)
|
if (quickSwitchKeys == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -971,50 +997,5 @@ namespace FancyZonesEditor.Utils
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ParsingCmdArgsErrorReport(string args, int count, string targetMonitorName, List<NativeMonitorData> monitorData, List<Monitor> monitors)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("```");
|
|
||||||
sb.AppendLine(" ## Command-line arguments:");
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine(args);
|
|
||||||
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("```");
|
|
||||||
sb.AppendLine(" ## Parsed command-line arguments:");
|
|
||||||
sb.AppendLine();
|
|
||||||
|
|
||||||
sb.Append("Span zones across monitors: ");
|
|
||||||
sb.AppendLine(App.Overlay.SpanZonesAcrossMonitors.ToString());
|
|
||||||
|
|
||||||
// using CultureInfo.InvariantCulture since this is for PowerToys team
|
|
||||||
sb.Append("Monitors count: ");
|
|
||||||
sb.AppendLine(count.ToString(CultureInfo.InvariantCulture));
|
|
||||||
sb.Append("Target monitor: ");
|
|
||||||
sb.AppendLine(targetMonitorName);
|
|
||||||
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine(" # Per monitor data:");
|
|
||||||
sb.AppendLine();
|
|
||||||
foreach (NativeMonitorData data in monitorData)
|
|
||||||
{
|
|
||||||
sb.AppendLine(data.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("```");
|
|
||||||
sb.AppendLine(" ## Monitors discovered:");
|
|
||||||
sb.AppendLine();
|
|
||||||
|
|
||||||
foreach (Monitor m in monitors)
|
|
||||||
{
|
|
||||||
sb.AppendLine(m.Device.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue