diff --git a/PowerToys.sln b/PowerToys.sln index ad2e5ddc68..7c6d765194 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -244,6 +244,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "interop-tests", "src\common EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Folder", "src\modules\launcher\Plugins\Microsoft.Plugin.Folder\Microsoft.Plugin.Folder.csproj", "{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher.Telemetry", "src\modules\launcher\PowerLauncher.Telemetry\PowerLauncher.Telemetry.csproj", "{08C8C05F-0362-41BC-818C-724572DF8B06}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telemetry", "src\common\ManagedTelemetry\Telemetry\Telemetry.csproj", "{5D00D290-4016-4CFE-9E41-1E7C724509BA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -868,6 +872,38 @@ Global {787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|x64.ActiveCfg = Release|x64 {787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|x64.Build.0 = Release|x64 {787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|x86.ActiveCfg = Release|x64 + {08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|ARM.ActiveCfg = Debug|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|ARM.Build.0 = Debug|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|ARM64.Build.0 = Debug|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|x64.ActiveCfg = Debug|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|x64.Build.0 = Debug|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|x86.ActiveCfg = Debug|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|x86.Build.0 = Debug|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Release|ARM.ActiveCfg = Release|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Release|ARM.Build.0 = Release|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Release|ARM64.ActiveCfg = Release|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Release|ARM64.Build.0 = Release|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Release|x64.ActiveCfg = Release|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Release|x64.Build.0 = Release|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Release|x86.ActiveCfg = Release|Any CPU + {08C8C05F-0362-41BC-818C-724572DF8B06}.Release|x86.Build.0 = Release|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|ARM.ActiveCfg = Debug|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|ARM.Build.0 = Debug|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|ARM64.Build.0 = Debug|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|x64.ActiveCfg = Debug|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|x64.Build.0 = Debug|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|x86.ActiveCfg = Debug|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|x86.Build.0 = Debug|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|ARM.ActiveCfg = Release|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|ARM.Build.0 = Release|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|ARM64.ActiveCfg = Release|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|ARM64.Build.0 = Release|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|x64.ActiveCfg = Release|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|x64.Build.0 = Release|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|x86.ActiveCfg = Release|Any CPU + {5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -935,6 +971,8 @@ Global {985B3F2F-CEED-4C0A-A249-69257E719145} = {1AFB6476-670D-4E80-A464-657E01DFF482} {437AD818-3F1F-4CA5-A79B-25233A157026} = {1AFB6476-670D-4E80-A464-657E01DFF482} {787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {4AFC9975-2456-4C70-94A4-84073C1CED93} + {08C8C05F-0362-41BC-818C-724572DF8B06} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68} + {5D00D290-4016-4CFE-9E41-1E7C724509BA} = {1AFB6476-670D-4E80-A464-657E01DFF482} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index 70ced77bfa..f24842bc1f 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -720,7 +720,7 @@ - + diff --git a/src/common/ManagedTelemetry/Telemetry/PowerToysTelemetry.cs b/src/common/ManagedTelemetry/Telemetry/PowerToysTelemetry.cs new file mode 100644 index 0000000000..9159e837e4 --- /dev/null +++ b/src/common/ManagedTelemetry/Telemetry/PowerToysTelemetry.cs @@ -0,0 +1,47 @@ +// 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 PreviewHandlerCommon.Telemetry; + +namespace Microsoft.PowerToys.Telemetry +{ + /// + /// Telemetry helper class for PowerToys. + /// + public class PowerToysTelemetry : TelemetryBase + { + + /// + /// Name for ETW event. + /// + private const string EventSourceName = "Microsoft.PowerToys"; + + /// + /// Initializes a new instance of the class. + /// + public PowerToysTelemetry() + : base(EventSourceName) + { + } + + /// + /// Gets an instance of the class. + /// + public static PowerToysTelemetry Log = new PowerToysTelemetry(); + + /// + /// Publishes ETW event when an action is triggered on + /// + public void WriteEvent(T telemetryEvent) + { + this.Write(null, new EventSourceOptions() + { + Keywords = ProjectKeywordMeasure, + Tags = ProjectTelemetryTagProductAndServicePerformance, + }, + telemetryEvent); + } + } +} diff --git a/src/common/ManagedTelemetry/Telemetry/Telemetry.csproj b/src/common/ManagedTelemetry/Telemetry/Telemetry.csproj new file mode 100644 index 0000000000..cca827fbf6 --- /dev/null +++ b/src/common/ManagedTelemetry/Telemetry/Telemetry.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + diff --git a/src/modules/previewpane/common/Telemetry/TelemetryBase.cs b/src/common/Telemetry/TelemetryBase.cs similarity index 94% rename from src/modules/previewpane/common/Telemetry/TelemetryBase.cs rename to src/common/Telemetry/TelemetryBase.cs index 1440aec9d6..28eec72559 100644 --- a/src/modules/previewpane/common/Telemetry/TelemetryBase.cs +++ b/src/common/Telemetry/TelemetryBase.cs @@ -2,7 +2,6 @@ // 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.Eventing.Reader; using System.Diagnostics.Tracing; namespace PreviewHandlerCommon.Telemetry diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs index 50e271df78..e256e69286 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs @@ -1,47 +1,144 @@ -// 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.Text.Json; -using System.Text.Json.Serialization; - -namespace Microsoft.PowerToys.Settings.UI.Lib -{ - public class EnabledModules - { - public EnabledModules() - { - this.FancyZones = false; - this.ImageResizer = false; - this.FileExplorerPreview = false; - this.PowerRename = false; - this.ShortcutGuide = false; - this.PowerLauncher = true; - } +// 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.Runtime.CompilerServices; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.PowerToys.Settings.Telemetry; +using Microsoft.PowerToys.Telemetry; + +namespace Microsoft.PowerToys.Settings.UI.Lib +{ + public class EnabledModules + { + public EnabledModules() + { + } + + private bool fancyZones = true; [JsonPropertyName("FancyZones")] - public bool FancyZones { get; set; } + public bool FancyZones + { + get => this.fancyZones; + set + { + if (this.fancyZones != value) + { + LogTelemetryEvent(value); + this.fancyZones = value; + } + } + } + + private bool imageResizer = true; [JsonPropertyName("Image Resizer")] - public bool ImageResizer { get; set; } + public bool ImageResizer + { + get => this.imageResizer; + set + { + if (this.imageResizer != value) + { + LogTelemetryEvent(value); + this.imageResizer = value; + } + } + } + + private bool fileExplorerPreview = true; [JsonPropertyName("File Explorer Preview")] - public bool FileExplorerPreview { get; set; } + public bool FileExplorerPreview + { + get => this.fileExplorerPreview; + set + { + if (this.fileExplorerPreview != value) + { + LogTelemetryEvent(value); + this.fileExplorerPreview = value; + } + } + } + + private bool shortcutGuide = true; [JsonPropertyName("Shortcut Guide")] - public bool ShortcutGuide { get; set; } - - public bool PowerRename { get; set; } - - [JsonPropertyName("Keyboard Manager")] - public bool KeyboardManager { get; set; } - - [JsonPropertyName("Run")] - public bool PowerLauncher { get; set; } - - public string ToJsonString() + public bool ShortcutGuide { - return JsonSerializer.Serialize(this); + get => this.shortcutGuide; + set + { + if (this.shortcutGuide != value) + { + LogTelemetryEvent(value); + this.shortcutGuide = value; + } + } } - } + + private bool powerRename = true; + + public bool PowerRename + { + get => this.powerRename; + set + { + if (this.powerRename != value) + { + LogTelemetryEvent(value); + this.powerRename = value; + } + } + } + + private bool keyboardManager = true; + [JsonPropertyName("Keyboard Manager")] + public bool KeyboardManager + { + get => this.keyboardManager; + set + { + if (this.keyboardManager != value) + { + LogTelemetryEvent(value); + this.keyboardManager = value; + } + } + } + + private bool powerLauncher = true; + + [JsonPropertyName("Run")] + public bool PowerLauncher + { + get => this.powerLauncher; + set + { + if (this.powerLauncher != value) + { + LogTelemetryEvent(value); + this.powerLauncher = value; + } + } +} + + public string ToJsonString() + { + return JsonSerializer.Serialize(this); + } + + private void LogTelemetryEvent(bool value, [CallerMemberName] string moduleName = null ) + { + var dataEvent = new SettingsEnabledModuleEvent() + { + Value = value, + ModuleName = moduleName, + }; + PowerToysTelemetry.Log.WriteEvent(dataEvent); + } + } } \ No newline at end of file diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/Microsoft.PowerToys.Settings.UI.Lib.csproj b/src/core/Microsoft.PowerToys.Settings.UI.Lib/Microsoft.PowerToys.Settings.UI.Lib.csproj index db1d040113..b8d8e05ec2 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/Microsoft.PowerToys.Settings.UI.Lib.csproj +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/Microsoft.PowerToys.Settings.UI.Lib.csproj @@ -33,6 +33,7 @@ + diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/Telemetry/Events/SettingsEnabledModuleEvent.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/Telemetry/Events/SettingsEnabledModuleEvent.cs new file mode 100644 index 0000000000..d96e7fc75a --- /dev/null +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/Telemetry/Events/SettingsEnabledModuleEvent.cs @@ -0,0 +1,12 @@ +using System.Diagnostics.Tracing; + +namespace Microsoft.PowerToys.Settings.Telemetry +{ + [EventData] + public class SettingsEnabledModuleEvent + { + public string ModuleName { get; set; } + + public bool Value { get; set; } + } +} diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs b/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs index 3eb5d43604..e6fc42b0d0 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs @@ -29,7 +29,8 @@ namespace Microsoft.PowerToys.Settings.UI.Runner // send IPC Message shellPage.SetDefaultSndMessageCallback(msg => { - Program.GetTwoWayIPCManager().Send(msg); + //IPC Manager is null when launching runner directly + Program.GetTwoWayIPCManager()?.Send(msg); }); // send IPC Message diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw b/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw index dcb845c56d..408431a5af 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw +++ b/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw @@ -314,10 +314,10 @@ During zone layout changes, windows assigned to a zone will match new size/positions - + Give feedback - + Module overview @@ -329,7 +329,7 @@ Check for updates - + Privacy statement @@ -341,10 +341,10 @@ Light - + Report a bug - + Request a feature @@ -392,7 +392,7 @@ Miscellaneous - + Open-source notice @@ -431,9 +431,6 @@ Lets you resize images by right-clicking. - - Enable - Enable Image Resizer @@ -527,7 +524,7 @@ Always Run as Admin - + Learn about Admin mode diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Views/FancyZonesPage.xaml b/src/core/Microsoft.PowerToys.Settings.UI/Views/FancyZonesPage.xaml index 5db9ab5525..f8ea4e2331 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/Views/FancyZonesPage.xaml +++ b/src/core/Microsoft.PowerToys.Settings.UI/Views/FancyZonesPage.xaml @@ -53,7 +53,7 @@ + Margin="{StaticResource MediumTopMargin}" /> - + + + - + + + - + @@ -66,7 +63,7 @@ Padding="0" IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}" Margin="0" - > + SelectionMode="None">