diff --git a/src/common/ManagedTelemetry/Telemetry/EtwTrace.cs b/src/common/ManagedTelemetry/Telemetry/EtwTrace.cs index d1d3ec2456..dafe3ddaf4 100644 --- a/src/common/ManagedTelemetry/Telemetry/EtwTrace.cs +++ b/src/common/ManagedTelemetry/Telemetry/EtwTrace.cs @@ -26,7 +26,7 @@ namespace Microsoft.PowerToys.Telemetry private readonly bool telemetryEnabled = DataDiagnosticsSettings.GetEnabledValue(); // This is the global telemetry setting on whether to log events private readonly bool telemetryRecordingEnabled = DataDiagnosticsSettings.GetViewEnabledValue(); // This is the setting for recording telemetry events to disk for viewing - private readonly string etwFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Microsoft\PowerToys\", "etw"); + private string etwFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Microsoft\PowerToys\", "etw"); private bool disposedValue; private string sessionName; private string etwFilePath; @@ -49,6 +49,18 @@ namespace Microsoft.PowerToys.Telemetry /// Initializes a new instance of the class. /// public ETWTrace() + { + Init(); + } + + public ETWTrace(string etwPath) + { + this.etwFolderPath = etwPath; + + Init(); + } + + private void Init() { if (File.Exists(etwFolderPath)) { diff --git a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs index 2fd96930a2..67c6d9f42e 100644 --- a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs +++ b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs @@ -4,6 +4,8 @@ using Common; using Microsoft.PowerToys.FilePreviewCommon; +using Microsoft.PowerToys.PreviewHandler.Gcode.Telemetry.Events; +using Microsoft.PowerToys.Telemetry; namespace Microsoft.PowerToys.PreviewHandler.Gcode { @@ -84,6 +86,13 @@ namespace Microsoft.PowerToys.PreviewHandler.Gcode Resize += FormResized; base.DoPreview(fs); + try + { + PowerToysTelemetry.Log.WriteEvent(new GcodeFilePreviewed()); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } } catch (Exception ex) { @@ -153,6 +162,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Gcode /// Stream reference to access source file. private void PreviewError(Exception exception, T dataSource) { + try + { + PowerToysTelemetry.Log.WriteEvent(new GcodeFilePreviewError { Message = exception.Message }); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } + Controls.Clear(); _infoBarAdded = true; AddTextBoxControl(Properties.Resource.GcodeNotPreviewedError); diff --git a/src/modules/previewpane/GcodePreviewHandler/Program.cs b/src/modules/previewpane/GcodePreviewHandler/Program.cs index 2ebc1fb944..4237e40932 100644 --- a/src/modules/previewpane/GcodePreviewHandler/Program.cs +++ b/src/modules/previewpane/GcodePreviewHandler/Program.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Windows.Threading; using Common.UI; +using Microsoft.PowerToys.Telemetry; using PowerToys.Interop; namespace Microsoft.PowerToys.PreviewHandler.Gcode @@ -27,6 +28,8 @@ namespace Microsoft.PowerToys.PreviewHandler.Gcode { if (args.Length == 6) { + ETWTrace etwTrace = new ETWTrace(Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData", "LocalLow", "Microsoft", "PowerToys", "etw")); + string filePath = args[0]; IntPtr hwnd = IntPtr.Parse(args[1], NumberStyles.HexNumber, CultureInfo.InvariantCulture); @@ -52,12 +55,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Gcode Rectangle s = default; if (!_previewHandlerControl.SetRect(s)) { + etwTrace?.Dispose(); + // When the parent HWND became invalid, the application won't respond to Application.Exit(). Environment.Exit(0); } }, Dispatcher.CurrentDispatcher, _tokenSource.Token); + + etwTrace?.Dispose(); } else { diff --git a/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFileHandlerLoaded.cs b/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFileHandlerLoaded.cs new file mode 100644 index 0000000000..c1d1fba40a --- /dev/null +++ b/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFileHandlerLoaded.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Gcode.Telemetry.Events +{ + /// + /// A telemetry event to be raised when a svg file has been viewed in the preview pane. + /// + [EventData] + public class GcodeFileHandlerLoaded : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFilePreviewError.cs b/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFilePreviewError.cs new file mode 100644 index 0000000000..9e9a232e04 --- /dev/null +++ b/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFilePreviewError.cs @@ -0,0 +1,26 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Gcode.Telemetry.Events +{ + /// + /// A telemetry event to be raised when an error has occurred in the preview pane. + /// + [EventData] + public class GcodeFilePreviewError : EventBase, IEvent + { + /// + /// Gets or sets the error message to log as part of the telemetry event. + /// + public string Message { get; set; } + + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance; + } +} diff --git a/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFilePreviewed.cs b/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFilePreviewed.cs new file mode 100644 index 0000000000..693e314e40 --- /dev/null +++ b/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFilePreviewed.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Gcode.Telemetry.Events +{ + /// + /// A telemetry event to be raised when a svg file has been viewed in the preview pane. + /// + [EventData] + public class GcodeFilePreviewed : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs index bb4b1f869d..89f480c792 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs +++ b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs @@ -9,6 +9,8 @@ using System.Text.RegularExpressions; using Common; using Microsoft.PowerToys.PreviewHandler.Markdown.Properties; +using Microsoft.PowerToys.PreviewHandler.Markdown.Telemetry.Events; +using Microsoft.PowerToys.Telemetry; using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.WinForms; using Windows.System; @@ -215,9 +217,25 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown { } }); + + try + { + PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewed()); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } } - catch (Exception) + catch (Exception ex) { + try + { + PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewError { Message = ex.Message }); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } + Controls.Clear(); _infoBarDisplayed = true; _infoBar = GetTextBoxControl(Resources.MarkdownNotPreviewedError); diff --git a/src/modules/previewpane/MarkdownPreviewHandler/Program.cs b/src/modules/previewpane/MarkdownPreviewHandler/Program.cs index aebd45cdcb..a151b475c8 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/Program.cs +++ b/src/modules/previewpane/MarkdownPreviewHandler/Program.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Windows.Threading; using Common.UI; +using Microsoft.PowerToys.Telemetry; using PowerToys.Interop; namespace Microsoft.PowerToys.PreviewHandler.Markdown @@ -27,6 +28,8 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown { if (args.Length == 6) { + ETWTrace etwTrace = new ETWTrace(Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData", "LocalLow", "Microsoft", "PowerToys", "etw")); + string filePath = args[0]; IntPtr hwnd = IntPtr.Parse(args[1], NumberStyles.HexNumber, CultureInfo.InvariantCulture); @@ -52,12 +55,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown Rectangle s = default; if (!_previewHandlerControl.SetRect(s)) { + etwTrace?.Dispose(); + // When the parent HWND became invalid, the application won't respond to Application.Exit(). Environment.Exit(0); } }, Dispatcher.CurrentDispatcher, _tokenSource.Token); + + etwTrace?.Dispose(); } else { diff --git a/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFileHandlerLoaded.cs b/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFileHandlerLoaded.cs new file mode 100644 index 0000000000..dec9852dec --- /dev/null +++ b/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFileHandlerLoaded.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Markdown.Telemetry.Events +{ + /// + /// A telemetry event that is triggered when a markdown file is viewed in the preview pane. + /// + [EventData] + public class MarkdownFileHandlerLoaded : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFilePreviewError.cs b/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFilePreviewError.cs new file mode 100644 index 0000000000..95268b1619 --- /dev/null +++ b/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFilePreviewError.cs @@ -0,0 +1,23 @@ +// 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 Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Markdown.Telemetry.Events +{ + /// + /// A telemetry event that is triggered when an error occurs while attempting to view a markdown file in the preview pane. + /// + public class MarkdownFilePreviewError : EventBase, IEvent + { + /// + /// Gets or sets the error message. + /// + public string Message { get; set; } + + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance; + } +} diff --git a/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFilePreviewed.cs b/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFilePreviewed.cs new file mode 100644 index 0000000000..e38d2d38ca --- /dev/null +++ b/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFilePreviewed.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Markdown.Telemetry.Events +{ + /// + /// A telemetry event that is triggered when a markdown file is viewed in the preview pane. + /// + [EventData] + public class MarkdownFilePreviewed : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs index f9b5069e88..4068567985 100644 --- a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs +++ b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs @@ -1,8 +1,17 @@ // 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.Drawing; +using System.IO; +using System.Runtime.InteropServices.ComTypes; +using System.Windows.Forms; + using Common; +using Common.Utilities; using Microsoft.PowerToys.PreviewHandler.Pdf.Properties; +using Microsoft.PowerToys.PreviewHandler.Pdf.Telemetry.Events; +using Microsoft.PowerToys.Telemetry; using Windows.Data.Pdf; using Windows.Storage.Streams; using Windows.UI.ViewManagement; @@ -149,9 +158,25 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf memStream.Dispose(); } } + + try + { + PowerToysTelemetry.Log.WriteEvent(new PdfFilePreviewed()); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } } - catch (Exception) + catch (Exception ex) { + try + { + PowerToysTelemetry.Log.WriteEvent(new PdfFilePreviewError { Message = ex.Message }); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } + Controls.Clear(); _infoBar = GetTextBoxControl(Resources.PdfNotPreviewedError); Controls.Add(_infoBar); diff --git a/src/modules/previewpane/PdfPreviewHandler/Program.cs b/src/modules/previewpane/PdfPreviewHandler/Program.cs index 985e2ca512..63c5ae6ed2 100644 --- a/src/modules/previewpane/PdfPreviewHandler/Program.cs +++ b/src/modules/previewpane/PdfPreviewHandler/Program.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.Windows.Threading; using Common.UI; +using Microsoft.PowerToys.Telemetry; using PowerToys.Interop; namespace Microsoft.PowerToys.PreviewHandler.Pdf @@ -26,6 +27,8 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf { if (args.Length == 6) { + ETWTrace etwTrace = new ETWTrace(Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData", "LocalLow", "Microsoft", "PowerToys", "etw")); + string filePath = args[0]; IntPtr hwnd = IntPtr.Parse(args[1], NumberStyles.HexNumber, CultureInfo.InvariantCulture); @@ -51,12 +54,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf Rectangle s = default; if (!_previewHandlerControl.SetRect(s)) { + etwTrace?.Dispose(); + // When the parent HWND became invalid, the application won't respond to Application.Exit(). Environment.Exit(0); } }, Dispatcher.CurrentDispatcher, _tokenSource.Token); + + etwTrace?.Dispose(); } else { diff --git a/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFileHandlerLoaded.cs b/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFileHandlerLoaded.cs new file mode 100644 index 0000000000..fc2ac2881b --- /dev/null +++ b/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFileHandlerLoaded.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Pdf.Telemetry.Events +{ + /// + /// A telemetry event that is triggered when a pdf file is viewed in the preview pane. + /// + [EventData] + public class PdfFileHandlerLoaded : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFilePreviewError.cs b/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFilePreviewError.cs new file mode 100644 index 0000000000..73dec91265 --- /dev/null +++ b/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFilePreviewError.cs @@ -0,0 +1,23 @@ +// 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 Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Pdf.Telemetry.Events +{ + /// + /// A telemetry event that is triggered when an error occurs while attempting to view a markdown file in the preview pane. + /// + public class PdfFilePreviewError : EventBase, IEvent + { + /// + /// Gets or sets the error message. + /// + public string Message { get; set; } + + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance; + } +} diff --git a/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFilePreviewed.cs b/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFilePreviewed.cs new file mode 100644 index 0000000000..0a223a24b2 --- /dev/null +++ b/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFilePreviewed.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Pdf.Telemetry.Events +{ + /// + /// A telemetry event that is triggered when a markdown file is viewed in the preview pane. + /// + [EventData] + public class PdfFilePreviewed : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/modules/previewpane/QoiPreviewHandler/Program.cs b/src/modules/previewpane/QoiPreviewHandler/Program.cs index b127ff24d7..203368a165 100644 --- a/src/modules/previewpane/QoiPreviewHandler/Program.cs +++ b/src/modules/previewpane/QoiPreviewHandler/Program.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Windows.Threading; using Common.UI; +using Microsoft.PowerToys.Telemetry; using PowerToys.Interop; namespace Microsoft.PowerToys.PreviewHandler.Qoi @@ -27,6 +28,8 @@ namespace Microsoft.PowerToys.PreviewHandler.Qoi { if (args.Length == 6) { + ETWTrace etwTrace = new ETWTrace(Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData", "LocalLow", "Microsoft", "PowerToys", "etw")); + string filePath = args[0]; IntPtr hwnd = IntPtr.Parse(args[1], NumberStyles.HexNumber, CultureInfo.InvariantCulture); @@ -52,12 +55,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Qoi Rectangle s = default; if (!_previewHandlerControl.SetRect(s)) { + etwTrace?.Dispose(); + // When the parent HWND became invalid, the application won't respond to Application.Exit(). Environment.Exit(0); } }, Dispatcher.CurrentDispatcher, _tokenSource.Token); + + etwTrace?.Dispose(); } else { diff --git a/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandlerControl.cs b/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandlerControl.cs index 29bf8d2d7d..047a3e614f 100644 --- a/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandlerControl.cs +++ b/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandlerControl.cs @@ -4,6 +4,8 @@ using Common; using Microsoft.PowerToys.FilePreviewCommon; +using Microsoft.PowerToys.PreviewHandler.Qoi.Telemetry.Events; +using Microsoft.PowerToys.Telemetry; namespace Microsoft.PowerToys.PreviewHandler.Qoi { @@ -71,6 +73,13 @@ namespace Microsoft.PowerToys.PreviewHandler.Qoi Resize += FormResized; base.DoPreview(fs); + try + { + PowerToysTelemetry.Log.WriteEvent(new QoiFilePreviewed()); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } } catch (Exception ex) { @@ -140,6 +149,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Qoi /// Stream reference to access source file. private void PreviewError(Exception exception, T dataSource) { + try + { + PowerToysTelemetry.Log.WriteEvent(new QoiFilePreviewError { Message = exception.Message }); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } + Controls.Clear(); _infoBarAdded = true; AddTextBoxControl(Properties.Resource.QoiNotPreviewedError); diff --git a/src/modules/previewpane/QoiPreviewHandler/Telemetry/Events/QoiFilePreviewError.cs b/src/modules/previewpane/QoiPreviewHandler/Telemetry/Events/QoiFilePreviewError.cs new file mode 100644 index 0000000000..cdc4516fd9 --- /dev/null +++ b/src/modules/previewpane/QoiPreviewHandler/Telemetry/Events/QoiFilePreviewError.cs @@ -0,0 +1,26 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Qoi.Telemetry.Events +{ + /// + /// A telemetry event to be raised when an error has occurred in the preview pane. + /// + [EventData] + public class QoiFilePreviewError : EventBase, IEvent + { + /// + /// Gets or sets the error message to log as part of the telemetry event. + /// + public string Message { get; set; } + + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance; + } +} diff --git a/src/modules/previewpane/QoiPreviewHandler/Telemetry/Events/QoiFilePreviewed.cs b/src/modules/previewpane/QoiPreviewHandler/Telemetry/Events/QoiFilePreviewed.cs new file mode 100644 index 0000000000..273ec8caf0 --- /dev/null +++ b/src/modules/previewpane/QoiPreviewHandler/Telemetry/Events/QoiFilePreviewed.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Qoi.Telemetry.Events +{ + /// + /// A telemetry event to be raised when a Qoi file has been viewed in the preview pane. + /// + [EventData] + public class QoiFilePreviewed : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/modules/previewpane/SvgPreviewHandler/Program.cs b/src/modules/previewpane/SvgPreviewHandler/Program.cs index 005d6cb73c..77e64ff2c7 100644 --- a/src/modules/previewpane/SvgPreviewHandler/Program.cs +++ b/src/modules/previewpane/SvgPreviewHandler/Program.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Windows.Threading; using Common.UI; +using Microsoft.PowerToys.Telemetry; using PowerToys.Interop; namespace Microsoft.PowerToys.PreviewHandler.Svg @@ -27,6 +28,8 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg { if (args.Length == 6) { + ETWTrace etwTrace = new ETWTrace(Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData", "LocalLow", "Microsoft", "PowerToys", "etw")); + string filePath = args[0]; IntPtr hwnd = IntPtr.Parse(args[1], NumberStyles.HexNumber, CultureInfo.InvariantCulture); @@ -52,12 +55,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg Rectangle s = default; if (!_previewHandlerControl.SetRect(s)) { + etwTrace?.Dispose(); + // When the parent HWND became invalid, the application won't respond to Application.Exit(). Environment.Exit(0); } }, Dispatcher.CurrentDispatcher, _tokenSource.Token); + + etwTrace?.Dispose(); } else { diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs index 931946dc0b..095c985896 100644 --- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs +++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs @@ -2,11 +2,14 @@ // 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.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using Common; using Common.Utilities; +using Microsoft.PowerToys.PreviewHandler.Svg.Telemetry.Events; +using Microsoft.PowerToys.Telemetry; using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.WinForms; using SvgPreviewHandler; @@ -139,8 +142,15 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg svgData = SvgPreviewHandlerHelper.SwapNamespaces(svgData); svgData = SvgPreviewHandlerHelper.AddStyleSVG(svgData); } - catch (Exception) + catch (Exception ex) { + try + { + PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewError { Message = ex.Message }); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } } try @@ -157,6 +167,13 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg AddWebViewControl(svgData); Resize += FormResized; base.DoPreview(dataSource); + try + { + PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewed()); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } } catch (Exception ex) { @@ -284,6 +301,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg /// Stream reference to access source file. private void PreviewError(Exception exception, T dataSource) { + try + { + PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewError { Message = exception.Message }); + } + catch + { // Should not crash if sending telemetry is failing. Ignore the exception. + } + Controls.Clear(); _infoBarAdded = true; AddTextBoxControl(Properties.Resource.SvgNotPreviewedError); diff --git a/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFileHandlerLoaded.cs b/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFileHandlerLoaded.cs new file mode 100644 index 0000000000..aaea992ba9 --- /dev/null +++ b/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFileHandlerLoaded.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Svg.Telemetry.Events +{ + /// + /// A telemetry event to be raised when a svg file has been viewed in the preview pane. + /// + [EventData] + public class SvgFileHandlerLoaded : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFilePreviewError.cs b/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFilePreviewError.cs new file mode 100644 index 0000000000..daed435502 --- /dev/null +++ b/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFilePreviewError.cs @@ -0,0 +1,26 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Svg.Telemetry.Events +{ + /// + /// A telemetry event to be raised when an error has occurred in the preview pane. + /// + [EventData] + public class SvgFilePreviewError : EventBase, IEvent + { + /// + /// Gets or sets the error message to log as part of the telemetry event. + /// + public string Message { get; set; } + + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance; + } +} diff --git a/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFilePreviewed.cs b/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFilePreviewed.cs new file mode 100644 index 0000000000..5348bcd466 --- /dev/null +++ b/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFilePreviewed.cs @@ -0,0 +1,21 @@ +// 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.Diagnostics.Tracing; + +using Microsoft.PowerToys.Telemetry; +using Microsoft.PowerToys.Telemetry.Events; + +namespace Microsoft.PowerToys.PreviewHandler.Svg.Telemetry.Events +{ + /// + /// A telemetry event to be raised when a svg file has been viewed in the preview pane. + /// + [EventData] + public class SvgFilePreviewed : EventBase, IEvent + { + /// + public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage; + } +} diff --git a/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs index 2bf4e0942a..e5a0d92aa8 100644 --- a/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs @@ -168,6 +168,9 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels string etwDirPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft\\PowerToys\\etw"); DeleteDiagnosticDataOlderThan28Days(etwDirPath); + string localLowEtwDirPath = Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData", "LocalLow", "Microsoft", "PowerToys", "etw"); + DeleteDiagnosticDataOlderThan28Days(localLowEtwDirPath); + InitializeLanguages(); } @@ -1253,7 +1256,26 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels internal void ViewDiagnosticData() { + string localLowEtwDirPath = Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData", "LocalLow", "Microsoft", "PowerToys", "etw"); string etwDirPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft\\PowerToys\\etw"); + + string[] localLowEtlFiles = Directory.GetFiles(localLowEtwDirPath, "*.etl"); + + foreach (string file in localLowEtlFiles) + { + string fileName = Path.GetFileName(file); + string destFile = Path.Combine(etwDirPath, fileName); + + try + { + File.Copy(file, destFile, overwrite: true); + } + catch (Exception ex) + { + Logger.LogError($"Failed to copy etl file: {fileName}. Error: {ex.Message}"); + } + } + string tracerptPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "system32"); ETLConverter converter = new ETLConverter(etwDirPath, tracerptPath);