diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index fa94dd6d7e97..e7bcaab1b526 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -43,6 +43,7 @@ AMPROPSETID amr ANDSCANS animatedvisuals +anr ansicolor ANull AOC @@ -57,14 +58,12 @@ APPBARDATA appdata APPEXECLINK Appium -applayout Applicationcan APPLICATIONFRAMEHOST appmanifest APPNAME appref appsettings -appsfolder appwindow appwiz APSTUDIO @@ -145,7 +144,6 @@ BTNFACE bugreport BUILDARCH BUILDNUMBER -buildtask buildtransitive BVal BValue @@ -269,7 +267,6 @@ CSettings cso CSRW CStyle -cswinrt CSY CTest currentculture @@ -351,7 +348,6 @@ devpkey DEVSOURCE DIIRFLAG dimm -directshow DISABLEASACTIONKEY diskmgmt DISPLAYCHANGE @@ -367,7 +363,6 @@ dllmain DNLEN DONOTROUND DONTVALIDATEPATH -DOPUS dotnet DPICHANGED DPIs @@ -450,12 +445,13 @@ erwrite ESettings esrp etl -ETW +etw EUQ eurochange eventlog eventvwr everytime +evntrace evt EWXFORCE EWXFORCEIFHUNG @@ -527,7 +523,6 @@ FZE gacutil Gaeilge Gaidhlig -GBarm GCLP gdi gdiplus @@ -997,7 +992,6 @@ NCRENDERING ndp NEEDDISPATCH needinfo -netcore netcoreapp netcpl netframework @@ -1006,6 +1000,7 @@ netsh newcolor newdev NEWDIALOGSTYLE +NEWFILE newitem newpath newplus @@ -1074,7 +1069,6 @@ NTAPI ntdll ntfs NTSTATUS -nugets nullonfailure numberbox nwc @@ -1225,6 +1219,7 @@ proactively PROCESSENTRY PROCESSKEY processthreadsapi +PROCESSTRACE PRODEXT PRODUCTVERSION Progman @@ -1266,7 +1261,6 @@ PWSTR pwsz pwtd QDC -QDir qianlifeng qit QITAB @@ -1590,9 +1584,7 @@ SYSKEYUP SYSLIB SYSMENU SYSTEMAPPS -SYSTEMSETTINGS SYSTEMTIME -SYSTEMWOW tapp TApplication TApplied @@ -1612,7 +1604,6 @@ TCustom tdbuild TDefault TDevice -telem telephon templatenamespace testprocess @@ -1644,11 +1635,12 @@ toolkitconverters Toolset toolwindow TOPDOWNDIB -TOTALCMD TOUCHEVENTF TOUCHINPUT touchpad +TRACEHANDLE tracelogging +tracerpt trafficmanager traies transicc @@ -1706,11 +1698,9 @@ urlmon Usb USEDEFAULT USEFILEATTRIBUTES -USEPOSITION USERDATA Userenv USESHOWWINDOW -USESIZE USESTDHANDLES USRDLL UType @@ -1803,7 +1793,6 @@ wgpocpl WIC wil winapi -winappdriver wincodec Wincodecsdk wincolor @@ -1867,6 +1856,7 @@ WNDCLASSEX WNDCLASSEXW WNDCLASSW WNDPROC +wnode workarounds WORKSPACESEDITOR WORKSPACESLAUNCHER @@ -1912,7 +1902,6 @@ XNamespace Xoshiro XPels XPixel -xplorer XResource xsi XStr diff --git a/.pipelines/packages.config b/.pipelines/packages.config index a5cab593eb41..43fa34c91cdc 100644 --- a/.pipelines/packages.config +++ b/.pipelines/packages.config @@ -1,4 +1,4 @@ - + diff --git a/.pipelines/v2/release.yml b/.pipelines/v2/release.yml index b4a6a80833a5..2719777aa648 100644 --- a/.pipelines/v2/release.yml +++ b/.pipelines/v2/release.yml @@ -90,8 +90,8 @@ extends: - script: | call nuget.exe restore -configFile .pipelines/release-nuget.config -PackagesDirectory . .pipelines/packages.config || exit /b 1 - move /Y "Microsoft.PowerToys.Telemetry.2.0.0\build\include\TraceLoggingDefines.h" "src\common\Telemetry\TraceLoggingDefines.h" || exit /b 1 - move /Y "Microsoft.PowerToys.Telemetry.2.0.0\build\include\TelemetryBase.cs" "src\common\Telemetry\TelemetryBase.cs" || exit /b 1 + move /Y "Microsoft.PowerToys.Telemetry.2.0.2\build\include\TraceLoggingDefines.h" "src\common\Telemetry\TraceLoggingDefines.h" || exit /b 1 + move /Y "Microsoft.PowerToys.Telemetry.2.0.2\build\include\TelemetryBase.cs" "src\common\Telemetry\TelemetryBase.cs" || exit /b 1 displayName: Emplace telemetry files - stage: Publish diff --git a/Directory.Packages.props b/Directory.Packages.props index 95bc6fa8f1e3..a103ca59a84d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -28,6 +28,7 @@ + diff --git a/NOTICE.md b/NOTICE.md index f90b982505c3..38c961a11619 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -1320,6 +1320,7 @@ EXHIBIT A -Mozilla Public License. - MessagePack 2.5.187 - Microsoft.CodeAnalysis.NetAnalyzers 8.0.0 - Microsoft.Data.Sqlite 8.0.7 +- Microsoft.Diagnostics.Tracing.TraceEvent 3.1.16 - Microsoft.Extensions.DependencyInjection 8.0.0 - Microsoft.Extensions.Hosting 8.0.0 - Microsoft.Extensions.Hosting.WindowsServices 8.0.0 diff --git a/PowerToys.sln b/PowerToys.sln index 29744af75f77..3dc435bb84bd 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -297,6 +297,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Telemetry", "Telemetry", "{ ProjectSection(SolutionItems) = preProject src\common\Telemetry\ProjectTelemetry.h = src\common\Telemetry\ProjectTelemetry.h src\common\Telemetry\TelemetryBase.cs = src\common\Telemetry\TelemetryBase.cs + src\common\Telemetry\TraceBase.h = src\common\Telemetry\TraceBase.h src\common\Telemetry\TraceLoggingDefines.h = src\common\Telemetry\TraceLoggingDefines.h EndProjectSection EndProject @@ -624,6 +625,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WorkspacesLauncher", "src\m EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WorkspacesWindowArranger", "src\modules\Workspaces\WorkspacesWindowArranger\WorkspacesWindowArranger.vcxproj", "{37D07516-4185-43A4-924F-3C7A5D95ECF6}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EtwTrace", "src\common\Telemetry\EtwTrace\EtwTrace.vcxproj", "{8F021B46-362B-485C-BFBA-CCF83E820CBD}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MouseWithoutBorders.UnitTests", "src\modules\MouseWithoutBorders\MouseWithoutBorders.UnitTests\MouseWithoutBorders.UnitTests.csproj", "{66614C26-314C-4B91-9071-76133422CFEF}" EndProject Global @@ -2750,6 +2753,18 @@ Global {37D07516-4185-43A4-924F-3C7A5D95ECF6}.Release|x64.Build.0 = Release|x64 {37D07516-4185-43A4-924F-3C7A5D95ECF6}.Release|x86.ActiveCfg = Release|x64 {37D07516-4185-43A4-924F-3C7A5D95ECF6}.Release|x86.Build.0 = Release|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|ARM64.Build.0 = Debug|ARM64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x64.ActiveCfg = Debug|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x64.Build.0 = Debug|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x86.ActiveCfg = Debug|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x86.Build.0 = Debug|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.ActiveCfg = Release|ARM64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.Build.0 = Release|ARM64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.ActiveCfg = Release|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.Build.0 = Release|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x86.ActiveCfg = Release|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x86.Build.0 = Release|x64 {66614C26-314C-4B91-9071-76133422CFEF}.Debug|ARM64.ActiveCfg = Debug|ARM64 {66614C26-314C-4B91-9071-76133422CFEF}.Debug|ARM64.Build.0 = Debug|ARM64 {66614C26-314C-4B91-9071-76133422CFEF}.Debug|x64.ActiveCfg = Debug|x64 @@ -2991,6 +3006,7 @@ Global {367D7543-7DBA-4381-99F1-BF6142A996C4} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF} {2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF} {37D07516-4185-43A4-924F-3C7A5D95ECF6} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF} + {8F021B46-362B-485C-BFBA-CCF83E820CBD} = {8F62026A-294B-41C6-8839-87463613F216} {66614C26-314C-4B91-9071-76133422CFEF} = {B6C42F16-73EB-477E-8B0D-4E6CF6C20AAC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/installer/PowerToysSetup.sln b/installer/PowerToysSetup.sln index cdcef5407936..540ef43d2366 100644 --- a/installer/PowerToysSetup.sln +++ b/installer/PowerToysSetup.sln @@ -15,6 +15,8 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysBootstrapper", "Po EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Version", "..\src\common\version\version.vcxproj", "{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EtwTrace", "..\src\common\Telemetry\EtwTrace\EtwTrace.vcxproj", "{8F021B46-362B-485C-BFBA-CCF83E820CBD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 @@ -68,6 +70,14 @@ Global {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|ARM64.Build.0 = Release|ARM64 {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.ActiveCfg = Release|x64 {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.Build.0 = Release|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|ARM64.Build.0 = Debug|ARM64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x64.ActiveCfg = Debug|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x64.Build.0 = Debug|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.ActiveCfg = Release|ARM64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.Build.0 = Release|ARM64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.ActiveCfg = Release|x64 + {8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp index 884520820078..8995d2f9b62f 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.cpp +++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp @@ -10,6 +10,7 @@ #include "../../src/common/utils/modulesRegistry.h" #include "../../src/common/updating/installer.h" #include "../../src/common/version/version.h" +#include "../../src/common/Telemetry/EtwTrace/EtwTrace.h" #include #include @@ -27,9 +28,9 @@ HINSTANCE DLL_HANDLE = nullptr; TRACELOGGING_DEFINE_PROVIDER( g_hProvider, - "Microsoft.PowerToysInstaller", - // {e1d8165d-5cb6-5c74-3b51-bdfbfe4f7a3b} - (0xe1d8165d, 0x5cb6, 0x5c74, 0x3b, 0x51, 0xbd, 0xfb, 0xfe, 0x4f, 0x7a, 0x3b), + "Microsoft.PowerToys", + // {38e8889b-9731-53f5-e901-e8a7c1753074} + (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); const DWORD USERNAME_DOMAIN_LEN = DNLEN + UNLEN + 2; // Domain Name + '\' + User Name + '\0' @@ -38,6 +39,53 @@ const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0' static const wchar_t* POWERTOYS_EXE_COMPONENT = L"{A2C66D91-3485-4D00-B04D-91844E6B345B}"; static const wchar_t* POWERTOYS_UPGRADE_CODE = L"{42B84BF7-5FBF-473B-9C8B-049DC16F7708}"; +constexpr inline const wchar_t* DataDiagnosticsRegKey = L"Software\\Classes\\PowerToys"; +constexpr inline const wchar_t* DataDiagnosticsRegValueName = L"AllowDataDiagnostics"; + +#define TraceLoggingWriteWrapper(provider, eventName, ...) \ + if (isDataDiagnosticEnabled()) \ + { \ + trace.UpdateState(true); \ + TraceLoggingWrite(provider, eventName, __VA_ARGS__); \ + trace.Flush(); \ + trace.UpdateState(false); \ + } + +static Shared::Trace::ETWTrace trace{ L"PowerToys_Installer" }; + +inline bool isDataDiagnosticEnabled() +{ + HKEY key{}; + if (RegOpenKeyExW(HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + 0, + KEY_READ, + &key) != ERROR_SUCCESS) + { + return false; + } + + DWORD isDataDiagnosticsEnabled = 0; + DWORD size = sizeof(isDataDiagnosticsEnabled); + + if (RegGetValueW( + HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + DataDiagnosticsRegValueName, + RRF_RT_REG_DWORD, + nullptr, + &isDataDiagnosticsEnabled, + &size) != ERROR_SUCCESS) + { + RegCloseKey(key); + return false; + } + RegCloseKey(key); + + return isDataDiagnosticsEnabled == 1; +} + + HRESULT getInstallFolder(MSIHANDLE hInstall, std::wstring& installationDir) { DWORD len = 0; @@ -793,13 +841,14 @@ UINT __stdcall TelemetryLogInstallSuccessCA(MSIHANDLE hInstall) hr = WcaInitialize(hInstall, "TelemetryLogInstallSuccessCA"); ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Install_Success", TraceLoggingWideString(get_product_version().c_str(), "Version"), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE) + ); LExit: er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; @@ -814,7 +863,7 @@ UINT __stdcall TelemetryLogInstallCancelCA(MSIHANDLE hInstall) hr = WcaInitialize(hInstall, "TelemetryLogInstallCancelCA"); ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Install_Cancel", TraceLoggingWideString(get_product_version().c_str(), "Version"), @@ -835,7 +884,7 @@ UINT __stdcall TelemetryLogInstallFailCA(MSIHANDLE hInstall) hr = WcaInitialize(hInstall, "TelemetryLogInstallFailCA"); ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Install_Fail", TraceLoggingWideString(get_product_version().c_str(), "Version"), @@ -856,7 +905,7 @@ UINT __stdcall TelemetryLogUninstallSuccessCA(MSIHANDLE hInstall) hr = WcaInitialize(hInstall, "TelemetryLogUninstallSuccessCA"); ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "UnInstall_Success", TraceLoggingWideString(get_product_version().c_str(), "Version"), @@ -877,7 +926,7 @@ UINT __stdcall TelemetryLogUninstallCancelCA(MSIHANDLE hInstall) hr = WcaInitialize(hInstall, "TelemetryLogUninstallCancelCA"); ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "UnInstall_Cancel", TraceLoggingWideString(get_product_version().c_str(), "Version"), @@ -898,7 +947,7 @@ UINT __stdcall TelemetryLogUninstallFailCA(MSIHANDLE hInstall) hr = WcaInitialize(hInstall, "TelemetryLogUninstallFailCA"); ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "UnInstall_Fail", TraceLoggingWideString(get_product_version().c_str(), "Version"), @@ -919,7 +968,7 @@ UINT __stdcall TelemetryLogRepairCancelCA(MSIHANDLE hInstall) hr = WcaInitialize(hInstall, "TelemetryLogRepairCancelCA"); ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Repair_Cancel", TraceLoggingWideString(get_product_version().c_str(), "Version"), @@ -940,7 +989,7 @@ UINT __stdcall TelemetryLogRepairFailCA(MSIHANDLE hInstall) hr = WcaInitialize(hInstall, "TelemetryLogRepairFailCA"); ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Repair_Fail", TraceLoggingWideString(get_product_version().c_str(), "Version"), diff --git a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj index 959a600706ba..dee9f63e2b97 100644 --- a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj +++ b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj @@ -161,6 +161,9 @@ {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + diff --git a/src/common/GPOWrapper/GPOWrapper.cpp b/src/common/GPOWrapper/GPOWrapper.cpp index 817db8c4de95..a9ecb43818e6 100644 --- a/src/common/GPOWrapper/GPOWrapper.cpp +++ b/src/common/GPOWrapper/GPOWrapper.cpp @@ -224,4 +224,8 @@ namespace winrt::PowerToys::GPOWrapper::implementation { return static_cast(powertoys_gpo::getConfiguredNewPlusHideTemplateFilenameExtensionValue()); } + GpoRuleConfigured GPOWrapper::GetAllowDataDiagnosticsValue() + { + return static_cast(powertoys_gpo::getAllowDataDiagnosticsValue()); + } } diff --git a/src/common/GPOWrapper/GPOWrapper.h b/src/common/GPOWrapper/GPOWrapper.h index e1fcb5426b29..34c1e3646be2 100644 --- a/src/common/GPOWrapper/GPOWrapper.h +++ b/src/common/GPOWrapper/GPOWrapper.h @@ -61,6 +61,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation static GpoRuleConfigured GetConfiguredMwbDisableUserDefinedIpMappingRulesValue(); static winrt::hstring GPOWrapper::GetConfiguredMwbPolicyDefinedIpMappingRules(); static GpoRuleConfigured GetConfiguredNewPlusHideTemplateFilenameExtensionValue(); + static GpoRuleConfigured GetAllowDataDiagnosticsValue(); }; } diff --git a/src/common/GPOWrapper/GPOWrapper.idl b/src/common/GPOWrapper/GPOWrapper.idl index 1d375f1975e5..af58834a0c13 100644 --- a/src/common/GPOWrapper/GPOWrapper.idl +++ b/src/common/GPOWrapper/GPOWrapper.idl @@ -65,6 +65,7 @@ namespace PowerToys static GpoRuleConfigured GetConfiguredMwbDisableUserDefinedIpMappingRulesValue(); static String GetConfiguredMwbPolicyDefinedIpMappingRules(); static GpoRuleConfigured GetConfiguredNewPlusHideTemplateFilenameExtensionValue(); + static GpoRuleConfigured GetAllowDataDiagnosticsValue(); } } } diff --git a/src/common/ManagedTelemetry/Telemetry/DataDiagnosticsSettings.cs b/src/common/ManagedTelemetry/Telemetry/DataDiagnosticsSettings.cs new file mode 100644 index 000000000000..0a9aa7c89175 --- /dev/null +++ b/src/common/ManagedTelemetry/Telemetry/DataDiagnosticsSettings.cs @@ -0,0 +1,107 @@ +// 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 Microsoft.Win32; + +namespace Microsoft.PowerToys.Telemetry +{ + public static class DataDiagnosticsSettings + { + private static readonly string DataDiagnosticsRegistryKey = @"HKEY_CURRENT_USER\Software\Classes\PowerToys\"; + private static readonly string DataDiagnosticsRegistryValueName = @"AllowDataDiagnostics"; + private static readonly string DataDiagnosticsDataDiagnosticsUserActionRegistryValueName = @"DataDiagnosticsUserAction"; + private static readonly string DataDiagnosticsDataDiagnosticsViewDataRegistryValueName = @"DataDiagnosticsViewEnabled"; + + public static bool GetEnabledValue() + { + object registryValue = null; + try + { + registryValue = Registry.GetValue(DataDiagnosticsRegistryKey, DataDiagnosticsRegistryValueName, 0); + } + catch + { + } + + if (registryValue is not null) + { + return (int)registryValue == 1 ? true : false; + } + + return false; + } + + public static void SetEnabledValue(bool value) + { + try + { + Registry.SetValue(DataDiagnosticsRegistryKey, DataDiagnosticsRegistryValueName, value ? 1 : 0); + } + catch (Exception) + { + } + } + + public static bool GetUserActionValue() + { + object registryValue = null; + try + { + registryValue = Registry.GetValue(DataDiagnosticsRegistryKey, DataDiagnosticsDataDiagnosticsUserActionRegistryValueName, 0); + } + catch + { + } + + if (registryValue is not null) + { + return (int)registryValue == 1 ? true : false; + } + + return false; + } + + public static void SetUserActionValue(bool value) + { + try + { + Registry.SetValue(DataDiagnosticsRegistryKey, DataDiagnosticsDataDiagnosticsUserActionRegistryValueName, value ? 1 : 0); + } + catch (Exception) + { + } + } + + public static bool GetViewEnabledValue() + { + object registryValue = null; + try + { + registryValue = Registry.GetValue(DataDiagnosticsRegistryKey, DataDiagnosticsDataDiagnosticsViewDataRegistryValueName, 0); + } + catch + { + } + + if (registryValue is not null) + { + return (int)registryValue == 1 ? true : false; + } + + return false; + } + + public static void SetViewEnabledValue(bool value) + { + try + { + Registry.SetValue(DataDiagnosticsRegistryKey, DataDiagnosticsDataDiagnosticsViewDataRegistryValueName, value ? 1 : 0); + } + catch (Exception) + { + } + } + } +} diff --git a/src/common/ManagedTelemetry/Telemetry/EtwTrace.cs b/src/common/ManagedTelemetry/Telemetry/EtwTrace.cs new file mode 100644 index 000000000000..d1d3ec2456a3 --- /dev/null +++ b/src/common/ManagedTelemetry/Telemetry/EtwTrace.cs @@ -0,0 +1,158 @@ +// 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.Diagnostics.Tracing; +using System.Globalization; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Diagnostics.Tracing.Session; + +namespace Microsoft.PowerToys.Telemetry +{ + /// + /// This class is based loosely on the C++ ETWTrace class in Win32client/Framework project. + /// It is intended to record telemetry events generated by the PowerToys processes so that end users + /// can view them if they want. + /// + public class ETWTrace : IDisposable + { + internal const EventKeywords TelemetryKeyword = (EventKeywords)0x0000200000000000; + internal const EventKeywords MeasuresKeyword = (EventKeywords)0x0000400000000000; + internal const EventKeywords CriticalDataKeyword = (EventKeywords)0x0000800000000000; + + 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 bool disposedValue; + private string sessionName; + private string etwFilePath; + private bool started; +#nullable enable + private TraceEventSession? traceSession; + + internal sealed class Lister : EventListener + { + public Lister() + : base() + { + } + } + + private Lister? listener; +#nullable disable + + /// + /// Initializes a new instance of the class. + /// + public ETWTrace() + { + if (File.Exists(etwFolderPath)) + { + File.Delete(etwFolderPath); + } + + if (!Directory.Exists(etwFolderPath)) + { + Directory.CreateDirectory(etwFolderPath); + } + + if (this.telemetryEnabled && this.telemetryRecordingEnabled) + { + this.Start(); + } + + listener = new Lister(); + listener.EnableEvents(PowerToysTelemetry.Log, EventLevel.LogAlways); + } + + /// + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + this.Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + /// + /// Starts the trace session. + /// + public void Start() + { + lock (this) + { + if (this.started) + { + return; + } + + new Task(() => + { + while (true) + { + Thread.Sleep(30 * 1000); + + this.traceSession.Flush(); + } + }).Start(); + + string executable = Process.GetCurrentProcess().ProcessName; + string dateTimeNow = DateTime.Now.ToString("MM-d-yyyy__H_mm_ss", CultureInfo.InvariantCulture); + this.sessionName = string.Format(CultureInfo.InvariantCulture, "{0}-{1}-{2}", executable, Environment.ProcessId, dateTimeNow); + this.etwFilePath = Path.Combine(etwFolderPath, $"{this.sessionName}.etl"); + + this.traceSession = new TraceEventSession( + this.sessionName, this.etwFilePath, (TraceEventSessionOptions)(TraceEventSessionOptions.Create | TraceEventSessionOptions.PrivateLogger | TraceEventSessionOptions.PrivateInProcLogger)); + TraceEventProviderOptions args = new TraceEventProviderOptions(); + + this.traceSession.EnableProvider( + PowerToysTelemetry.Log.Guid, + matchAnyKeywords: (ulong)TelemetryKeyword | (ulong)MeasuresKeyword | (ulong)CriticalDataKeyword); + + this.started = true; + } + } + + /// + /// Stops the trace session. + /// + public void Stop() + { + lock (this) + { + if (!this.started) + { + return; + } + + if (this.traceSession != null) + { + Trace.TraceInformation("Disposing EventTraceSession"); + this.traceSession.Dispose(); + this.traceSession = null; + this.started = false; + } + } + } + + /// + /// Disposes the object. + /// + /// boolean for disposing. + protected virtual void Dispose(bool disposing) + { + if (!this.disposedValue) + { + if (disposing) + { + this.Stop(); + } + + this.disposedValue = true; + } + } + } +} diff --git a/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj b/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj index 504301516d57..3929c6061826 100644 --- a/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj +++ b/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj @@ -1,7 +1,7 @@  - + PowerToys Telemetry PowerToys.ManagedTelemetry @@ -11,4 +11,8 @@ + + + + diff --git a/src/common/ManagedTelemetry/Telemetry/PowerToysTelemetry.cs b/src/common/ManagedTelemetry/Telemetry/PowerToysTelemetry.cs index 9b74c682dffa..c1b77e67e49f 100644 --- a/src/common/ManagedTelemetry/Telemetry/PowerToysTelemetry.cs +++ b/src/common/ManagedTelemetry/Telemetry/PowerToysTelemetry.cs @@ -37,14 +37,17 @@ public PowerToysTelemetry() public void WriteEvent(T telemetryEvent) where T : EventBase, IEvent { - this.Write( - telemetryEvent.EventName, - new EventSourceOptions() - { - Keywords = ProjectKeywordMeasure, - Tags = ProjectTelemetryTagProductAndServicePerformance, - }, - telemetryEvent); + if (DataDiagnosticsSettings.GetEnabledValue()) + { + this.Write( + telemetryEvent.EventName, + new EventSourceOptions() + { + Keywords = ProjectKeywordMeasure, + Tags = ProjectTelemetryTagProductAndServicePerformance, + }, + telemetryEvent); + } } } } diff --git a/src/common/SettingsAPI/settings_helpers.cpp b/src/common/SettingsAPI/settings_helpers.cpp index 974b2fff6aaf..25d9719a6673 100644 --- a/src/common/SettingsAPI/settings_helpers.cpp +++ b/src/common/SettingsAPI/settings_helpers.cpp @@ -8,6 +8,8 @@ namespace PTSettingsHelper constexpr inline const wchar_t* last_version_run_filename = L"last_version_run.json"; constexpr inline const wchar_t* opened_at_first_launch_json_field_name = L"openedAtFirstLaunch"; constexpr inline const wchar_t* last_version_json_field_name = L"last_version"; + constexpr inline const wchar_t* DataDiagnosticsRegKey = L"Software\\Classes\\PowerToys"; + constexpr inline const wchar_t* DataDiagnosticsRegValueName = L"AllowDataDiagnostics"; std::wstring get_root_save_folder_location() { @@ -25,7 +27,7 @@ namespace PTSettingsHelper return result; } - std::wstring get_local_low_folder_location() + std::wstring get_local_low_folder_location() { PWSTR local_app_path; winrt::check_hresult(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, NULL, &local_app_path)); @@ -112,7 +114,7 @@ namespace PTSettingsHelper bool opened = saved_settings->GetNamedBoolean(opened_at_first_launch_json_field_name, false); return opened; } - + return false; } @@ -124,12 +126,11 @@ namespace PTSettingsHelper json::JsonObject obj; obj.SetNamedValue(opened_at_first_launch_json_field_name, json::value(true)); - json::to_file(oobePath.c_str(), obj); + json::to_file(oobePath.c_str(), obj); } std::wstring get_last_version_run() { - std::filesystem::path lastVersionRunPath(PTSettingsHelper::get_root_save_folder_location()); lastVersionRunPath = lastVersionRunPath.append(last_version_run_filename); if (std::filesystem::exists(lastVersionRunPath)) @@ -157,4 +158,29 @@ namespace PTSettingsHelper json::to_file(lastVersionRunPath.c_str(), obj); } + void save_data_diagnostics(bool enabled) + { + HKEY key{}; + if (RegCreateKeyExW(HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + 0, + nullptr, + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + nullptr, + &key, + nullptr) != ERROR_SUCCESS) + { + return; + } + + const bool value = enabled; + const size_t buf_size = sizeof(bool); + if (RegSetValueExW(key, DataDiagnosticsRegValueName, 0, REG_QWORD, reinterpret_cast(&value), buf_size) != ERROR_SUCCESS) + { + RegCloseKey(key); + return; + } + RegCloseKey(key); + } } diff --git a/src/common/SettingsAPI/settings_helpers.h b/src/common/SettingsAPI/settings_helpers.h index 9e01b3b2068f..14eae8ac62ce 100644 --- a/src/common/SettingsAPI/settings_helpers.h +++ b/src/common/SettingsAPI/settings_helpers.h @@ -24,4 +24,6 @@ namespace PTSettingsHelper void save_oobe_opened_state(); std::wstring get_last_version_run(); void save_last_version_run(const std::wstring& version); + + void save_data_diagnostics(bool enabled); } diff --git a/src/common/Telemetry/EtwTrace/EtwTrace.cpp b/src/common/Telemetry/EtwTrace/EtwTrace.cpp new file mode 100644 index 000000000000..05b6956953b8 --- /dev/null +++ b/src/common/Telemetry/EtwTrace/EtwTrace.cpp @@ -0,0 +1,310 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#pragma once +#include "pch.h" + +#include "ETWTrace.h" + +#include + +#include +#include + +namespace fs = std::filesystem; + +namespace +{ + constexpr inline const wchar_t* DataDiagnosticsRegKey = L"Software\\Classes\\PowerToys"; + constexpr inline const wchar_t* DataDiagnosticsRegValueName = L"AllowDataDiagnostics"; + constexpr inline const wchar_t* ViewDataDiagnosticsRegValueName = L"DataDiagnosticsViewEnabled"; + + inline std::wstring get_root_save_folder_location() + { + PWSTR local_app_path; + winrt::check_hresult(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &local_app_path)); + std::wstring result{ local_app_path }; + CoTaskMemFree(local_app_path); + + result += L"\\Microsoft\\PowerToys"; + std::filesystem::path save_path(result); + if (!std::filesystem::exists(save_path)) + { + std::filesystem::create_directories(save_path); + } + return result; + } + + bool IsDataDiagnosticsEnabled() + { + HKEY key{}; + if (RegOpenKeyExW(HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + 0, + KEY_READ, + &key) != ERROR_SUCCESS) + { + return false; + } + + DWORD isDataDiagnosticsEnabled = 0; + DWORD size = sizeof(isDataDiagnosticsEnabled); + + if (RegGetValueW( + HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + DataDiagnosticsRegValueName, + RRF_RT_REG_DWORD, + nullptr, + &isDataDiagnosticsEnabled, + &size) != ERROR_SUCCESS) + { + RegCloseKey(key); + return false; + } + RegCloseKey(key); + + return isDataDiagnosticsEnabled; + } + + bool isViewDataDiagnosticEnabled() + { + HKEY key{}; + if (RegOpenKeyExW(HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + 0, + KEY_READ, + &key) != ERROR_SUCCESS) + { + return false; + } + + DWORD isDataDiagnosticsEnabled = 0; + DWORD size = sizeof(isDataDiagnosticsEnabled); + + if (RegGetValueW( + HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + ViewDataDiagnosticsRegValueName, + RRF_RT_REG_DWORD, + nullptr, + &isDataDiagnosticsEnabled, + &size) != ERROR_SUCCESS) + { + RegCloseKey(key); + return false; + } + RegCloseKey(key); + + return isDataDiagnosticsEnabled == 1; + } + +} + +namespace Shared +{ + namespace Trace + { + ETWTrace::ETWTrace() + { + GUID id; + if (SUCCEEDED(CLSIDFromString(PowerToysProviderGUID, &id))) + { + m_providerGUID = id; + } + + fs::path outputFolder = get_root_save_folder_location(); + m_etwFolder = (outputFolder / c_etwFolderName); + } + + ETWTrace::ETWTrace(const std::wstring& etlFileNameOverride) : + ETWTrace() + { + m_etlFileNameOverride = etlFileNameOverride; + } + + ETWTrace::~ETWTrace() + { + Flush(); + Stop(); + m_etwFolder.clear(); + m_providerGUID = {}; + } + + void ETWTrace::UpdateState(bool tracing) + { + if (tracing) + { + Start(); + } + else + { + Stop(); + } + } + + void ETWTrace::Flush() + { + if (m_tracing) + { + Control(EVENT_TRACE_CONTROL_FLUSH); + // Control(EVENT_TRACE_CONTROL_INCREMENT_FILE); + } + } + + void ETWTrace::CreateEtwFolderIfNeeded() + { + if (!std::filesystem::exists(m_etwFolder)) + { + std::filesystem::create_directories(m_etwFolder); + } + else if (!std::filesystem::is_directory(m_etwFolder)) + { + std::filesystem::remove(m_etwFolder); + std::filesystem::create_directory(m_etwFolder); + } + + THROW_HR_IF(E_UNEXPECTED, !std::filesystem::exists(m_etwFolder)); + } + + void ETWTrace::InitEventTraceProperties() + { + const std::filesystem::path exePath(wil::GetModuleFileNameW(nullptr)); + const auto exeName = exePath.stem().wstring(); + + auto now = std::chrono::system_clock::now(); + auto timeNow = std::chrono::system_clock::to_time_t(now); + std::wstringstream dateTime; + struct tm timeInfo + { + }; + errno_t err = localtime_s(&timeInfo, &timeNow); + if (err == 0) + { + dateTime << std::put_time(&timeInfo, L"-%m-%d-%Y__%H_%M_%S"); + } + + if (m_etlFileNameOverride.empty()) + { + m_sessionName = wil::str_printf(L"%ws-%d%ws", exeName.c_str(), GetCurrentProcessId(), dateTime.str().c_str()); + } + else + { + m_sessionName = wil::str_printf(L"%ws-%d%ws", m_etlFileNameOverride.c_str(), GetCurrentProcessId(), dateTime.str().c_str()); + } + + std::replace(m_sessionName.begin(), m_sessionName.end(), '.', '_'); + + const ULONG etwSessionNameCharCount = static_cast(m_sessionName.size() + 1); + const ULONG etwSessionNameByteSize = etwSessionNameCharCount * sizeof(m_sessionName[0]); + + auto etlFileNameFormattedCounter = m_sessionName + c_etwNewFileFormattedCounter; + std::filesystem::path etlFilePath = m_etwFolder / etlFileNameFormattedCounter; + etlFilePath.replace_extension(c_etwFileNameEnd); + THROW_HR_IF(E_UNEXPECTED, etlFilePath.empty()); + + const auto etlFilePathStr = etlFilePath.wstring(); + // std::string/wstring returns number of characters not including the null terminator, so add +1 for that. + const ULONG etwFilePathCharCount = static_cast(etlFilePathStr.size() + 1); + const ULONG etwFilePathByteSize = etwFilePathCharCount * sizeof(etlFilePathStr[0]); + + const ULONG bufferSizeInBytes = sizeof(EVENT_TRACE_PROPERTIES) + etwSessionNameByteSize + etwFilePathByteSize; + auto eventTracePropertiesBuffer = std::make_unique(bufferSizeInBytes); + ZeroMemory(eventTracePropertiesBuffer.get(), bufferSizeInBytes); + auto eventTraceProperties = reinterpret_cast(eventTracePropertiesBuffer.get()); + + eventTraceProperties->Wnode.BufferSize = bufferSizeInBytes; + eventTraceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID; + eventTraceProperties->Wnode.ClientContext = 1; + eventTraceProperties->Wnode.Guid = m_providerGUID; + eventTraceProperties->BufferSize = 4; // 4KB, the minimum size + eventTraceProperties->LogFileMode = EVENT_TRACE_PRIVATE_LOGGER_MODE | EVENT_TRACE_PRIVATE_IN_PROC | EVENT_TRACE_FILE_MODE_NEWFILE; + eventTraceProperties->MaximumFileSize = 1; // 1 MB + + // LoggerName is placed at the end of EVENT_TRACE_PROPERTIES structure + eventTraceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES); + wcsncpy_s(reinterpret_cast(eventTracePropertiesBuffer.get() + eventTraceProperties->LoggerNameOffset), etwSessionNameCharCount, m_sessionName.c_str(), etwSessionNameCharCount); + + // LogFileName is placed at the end of the Logger Name + eventTraceProperties->LogFileNameOffset = eventTraceProperties->LoggerNameOffset + etwSessionNameByteSize; + wcsncpy_s(reinterpret_cast(eventTracePropertiesBuffer.get() + eventTraceProperties->LogFileNameOffset), etwFilePathCharCount, etlFilePathStr.c_str(), etwFilePathCharCount); + + m_eventTracePropertiesBuffer = std::move(eventTracePropertiesBuffer); + } + + void ETWTrace::Start() + { + if (m_tracing) + { + return; + } + + if (!IsDataDiagnosticsEnabled()) + { + return; + } + + if (!isViewDataDiagnosticEnabled()) + { + return; + } + + CreateEtwFolderIfNeeded(); + InitEventTraceProperties(); + + auto eventTraceProperties = reinterpret_cast(m_eventTracePropertiesBuffer.get()); + THROW_IF_WIN32_ERROR(StartTrace(&m_traceHandle, m_sessionName.c_str(), eventTraceProperties)); + Enable(EVENT_CONTROL_CODE_ENABLE_PROVIDER); + + m_tracing = true; + + m_flushing_thread = std::thread([this] { FlushWorker(); }); + } + + void ETWTrace::Stop() + { + if (!m_tracing) + { + return; + } + + Enable(EVENT_CONTROL_CODE_DISABLE_PROVIDER); + + // ControlTrace with EVENT_TRACE_CONTROL_STOP on the trace handle, + // which is equivalent to calling CloseTrace() on the trace handle. + Control(EVENT_TRACE_CONTROL_STOP); + + m_traceHandle = INVALID_PROCESSTRACE_HANDLE; + m_eventTracePropertiesBuffer.reset(); + m_tracing = false; + m_terminate_flushing_thread.notify_one(); + m_flushing_thread.join(); + } + + void ETWTrace::Control(ULONG traceControlCode) + { + auto eventTraceProperties = reinterpret_cast(m_eventTracePropertiesBuffer.get()); + const ULONG result = ControlTrace(m_traceHandle, m_sessionName.c_str(), eventTraceProperties, traceControlCode); + THROW_IF_FAILED(HRESULT_FROM_WIN32(result)); + } + + void ETWTrace::Enable(ULONG eventControlCode) + { + // Control the main provider + THROW_IF_WIN32_ERROR(EnableTraceEx2(m_traceHandle, &m_providerGUID, eventControlCode, TRACE_LEVEL_VERBOSE, 0, 0, 0, nullptr)); + } + + void ETWTrace::FlushWorker() + { + std::unique_lock lock(m_mutex); + while (m_tracing) + { + m_terminate_flushing_thread.wait_for(lock, + std::chrono::seconds(30), + [this]() { return !m_tracing.load(); }); + Flush(); + } + } + } +} \ No newline at end of file diff --git a/src/common/Telemetry/EtwTrace/EtwTrace.h b/src/common/Telemetry/EtwTrace/EtwTrace.h new file mode 100644 index 000000000000..46b3e37c405d --- /dev/null +++ b/src/common/Telemetry/EtwTrace/EtwTrace.h @@ -0,0 +1,54 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#pragma once +#include "pch.h" + +#include +#include +#include +#include + +namespace Shared +{ + namespace Trace + { + class ETWTrace + { + public: + static inline const wchar_t* PowerToysProviderGUID = L"{38e8889b-9731-53f5-e901-e8a7c1753074}"; + + ETWTrace(); + ETWTrace(const std::wstring& etlFileNameOverride); + ~ETWTrace(); + + void UpdateState(bool tracing); + void Flush(); + + private: + void CreateEtwFolderIfNeeded(); + void InitEventTraceProperties(); + void Start(); + void Stop(); + void Control(const ULONG traceControlCode); + void Enable(const ULONG eventControlCode); + void FlushWorker(); + + GUID m_providerGUID{}; + std::filesystem::path m_etwFolder; + std::wstring m_sessionName; + TRACEHANDLE m_traceHandle{ INVALID_PROCESSTRACE_HANDLE }; + std::unique_ptr m_eventTracePropertiesBuffer; + std::atomic_bool m_tracing{ false }; + std::wstring m_etlFileNameOverride{}; + std::thread m_flushing_thread; + std::condition_variable m_terminate_flushing_thread; + std::mutex m_mutex; + + static constexpr PCWSTR c_etwFolderName = L"etw"; + static constexpr PCWSTR c_etwNewFileFormattedCounter = L"-%d"; + static constexpr PCWSTR c_etwFileNameEnd = L".etl"; + }; + } +} \ No newline at end of file diff --git a/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj b/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj new file mode 100644 index 000000000000..17b3be7a2654 --- /dev/null +++ b/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj @@ -0,0 +1,51 @@ + + + + + 17.0 + Win32Proj + {8f021b46-362b-485c-bfba-ccf83e820cbd} + EtwTrace + + + + StaticLibrary + v143 + + + + + + + + + + + + + + + + + + Create + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj.filters b/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj.filters new file mode 100644 index 000000000000..9127669e7785 --- /dev/null +++ b/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + + + + + + + \ No newline at end of file diff --git a/src/common/Telemetry/EtwTrace/packages.config b/src/common/Telemetry/EtwTrace/packages.config new file mode 100644 index 000000000000..ff4b05964868 --- /dev/null +++ b/src/common/Telemetry/EtwTrace/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/common/Telemetry/EtwTrace/pch.cpp b/src/common/Telemetry/EtwTrace/pch.cpp new file mode 100644 index 000000000000..64b7eef6d6b9 --- /dev/null +++ b/src/common/Telemetry/EtwTrace/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/src/common/Telemetry/EtwTrace/pch.h b/src/common/Telemetry/EtwTrace/pch.h new file mode 100644 index 000000000000..8db0e0c1e8a3 --- /dev/null +++ b/src/common/Telemetry/EtwTrace/pch.h @@ -0,0 +1,23 @@ +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#endif //PCH_H diff --git a/src/common/Telemetry/TraceBase.h b/src/common/Telemetry/TraceBase.h new file mode 100644 index 000000000000..da722bb45744 --- /dev/null +++ b/src/common/Telemetry/TraceBase.h @@ -0,0 +1,63 @@ +#pragma once + +#include "ProjectTelemetry.h" + +#define TraceLoggingWriteWrapper(provider, eventName, ...) \ + if (IsDataDiagnosticsEnabled()) \ + { \ + TraceLoggingWrite(provider, eventName, __VA_ARGS__); \ + } + +namespace telemetry +{ + +constexpr inline const wchar_t* DataDiagnosticsRegKey = L"Software\\Classes\\PowerToys"; +constexpr inline const wchar_t* DataDiagnosticsRegValueName = L"AllowDataDiagnostics"; + +class TraceBase +{ +public: + static void RegisterProvider() + { + TraceLoggingRegister(g_hProvider); + } + + static void UnregisterProvider() + { + TraceLoggingUnregister(g_hProvider); + } + + static bool IsDataDiagnosticsEnabled() + { + HKEY key{}; + if (RegOpenKeyExW(HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + 0, + KEY_READ, + &key) != ERROR_SUCCESS) + { + return false; + } + + DWORD isDataDiagnosticsEnabled = 0; + DWORD size = sizeof(isDataDiagnosticsEnabled); + + if (RegGetValueW( + HKEY_CURRENT_USER, + DataDiagnosticsRegKey, + DataDiagnosticsRegValueName, + RRF_RT_REG_DWORD, + nullptr, + &isDataDiagnosticsEnabled, + &size) != ERROR_SUCCESS) + { + RegCloseKey(key); + return false; + } + RegCloseKey(key); + + return isDataDiagnosticsEnabled; + } +}; + +} // namespace telemetry \ No newline at end of file diff --git a/src/common/interop/Constants.cpp b/src/common/interop/Constants.cpp index 7a01cd225a29..0a7f8c029125 100644 --- a/src/common/interop/Constants.cpp +++ b/src/common/interop/Constants.cpp @@ -51,6 +51,10 @@ namespace winrt::PowerToys::Interop::implementation { return CommonSharedConstants::SHOW_COLOR_PICKER_SHARED_EVENT; } + hstring Constants::TerminateColorPickerSharedEvent() + { + return CommonSharedConstants::TERMINATE_COLOR_PICKER_SHARED_EVENT; + } hstring Constants::AdvancedPasteShowUIMessage() { return CommonSharedConstants::ADVANCED_PASTE_SHOW_UI_MESSAGE; @@ -71,10 +75,18 @@ namespace winrt::PowerToys::Interop::implementation { return CommonSharedConstants::ADVANCED_PASTE_CUSTOM_ACTION_MESSAGE; } + hstring Constants::AdvancedPasteTerminateAppMessage() + { + return CommonSharedConstants::ADVANCED_PASTE_TERMINATE_APP_MESSAGE; + } hstring Constants::ShowPowerOCRSharedEvent() { return CommonSharedConstants::SHOW_POWEROCR_SHARED_EVENT; } + hstring Constants::TerminatePowerOCRSharedEvent() + { + return CommonSharedConstants::TERMINATE_POWEROCR_SHARED_EVENT; + } hstring Constants::MouseJumpShowPreviewEvent() { return CommonSharedConstants::MOUSE_JUMP_SHOW_PREVIEW_EVENT; @@ -87,6 +99,10 @@ namespace winrt::PowerToys::Interop::implementation { return CommonSharedConstants::SHOW_PEEK_SHARED_EVENT; } + hstring Constants::TerminatePeekEvent() + { + return CommonSharedConstants::TERMINATE_PEEK_SHARED_EVENT; + } hstring Constants::PowerAccentExitEvent() { return CommonSharedConstants::POWERACCENT_EXIT_EVENT; @@ -135,6 +151,10 @@ namespace winrt::PowerToys::Interop::implementation { return CommonSharedConstants::SHOW_HOSTS_ADMIN_EVENT; } + hstring Constants::TerminateHostsSharedEvent() + { + return CommonSharedConstants::TERMINATE_HOSTS_EVENT; + } hstring Constants::CropAndLockThumbnailEvent() { return CommonSharedConstants::CROP_AND_LOCK_THUMBNAIL_EVENT; @@ -159,4 +179,8 @@ namespace winrt::PowerToys::Interop::implementation { return CommonSharedConstants::WORKSPACES_HOTKEY_EVENT; } + hstring Constants::PowerToysRunnerTerminateSettingsEvent() + { + return CommonSharedConstants::TERMINATE_SETTINGS_SHARED_EVENT; + } } diff --git a/src/common/interop/Constants.h b/src/common/interop/Constants.h index 09a884e50b55..351349959bcc 100644 --- a/src/common/interop/Constants.h +++ b/src/common/interop/Constants.h @@ -16,15 +16,19 @@ namespace winrt::PowerToys::Interop::implementation static hstring FZEToggleEvent(); static hstring ColorPickerSendSettingsTelemetryEvent(); static hstring ShowColorPickerSharedEvent(); + static hstring TerminateColorPickerSharedEvent(); static hstring AdvancedPasteShowUIMessage(); static hstring AdvancedPasteMarkdownMessage(); static hstring AdvancedPasteJsonMessage(); static hstring AdvancedPasteAdditionalActionMessage(); static hstring AdvancedPasteCustomActionMessage(); + static hstring AdvancedPasteTerminateAppMessage(); static hstring ShowPowerOCRSharedEvent(); + static hstring TerminatePowerOCRSharedEvent(); static hstring MouseJumpShowPreviewEvent(); static hstring AwakeExitEvent(); static hstring ShowPeekEvent(); + static hstring TerminatePeekEvent(); static hstring PowerAccentExitEvent(); static hstring ShortcutGuideTriggerEvent(); static hstring RegistryPreviewTriggerEvent(); @@ -37,12 +41,14 @@ namespace winrt::PowerToys::Interop::implementation static hstring SvgPreviewResizeEvent(); static hstring ShowHostsSharedEvent(); static hstring ShowHostsAdminSharedEvent(); + static hstring TerminateHostsSharedEvent(); static hstring CropAndLockThumbnailEvent(); static hstring CropAndLockReparentEvent(); static hstring ShowEnvironmentVariablesSharedEvent(); static hstring ShowEnvironmentVariablesAdminSharedEvent(); static hstring WorkspacesLaunchEditorEvent(); static hstring WorkspacesHotkeyEvent(); + static hstring PowerToysRunnerTerminateSettingsEvent(); }; } diff --git a/src/common/interop/Constants.idl b/src/common/interop/Constants.idl index 9ae489c62b86..736f7dd49bdf 100644 --- a/src/common/interop/Constants.idl +++ b/src/common/interop/Constants.idl @@ -13,15 +13,19 @@ namespace PowerToys static String FZEToggleEvent(); static String ColorPickerSendSettingsTelemetryEvent(); static String ShowColorPickerSharedEvent(); + static String TerminateColorPickerSharedEvent(); static String AdvancedPasteShowUIMessage(); static String AdvancedPasteMarkdownMessage(); static String AdvancedPasteJsonMessage(); static String AdvancedPasteAdditionalActionMessage(); static String AdvancedPasteCustomActionMessage(); + static String AdvancedPasteTerminateAppMessage(); static String ShowPowerOCRSharedEvent(); + static String TerminatePowerOCRSharedEvent(); static String MouseJumpShowPreviewEvent(); static String AwakeExitEvent(); static String ShowPeekEvent(); + static String TerminatePeekEvent(); static String PowerAccentExitEvent(); static String ShortcutGuideTriggerEvent(); static String RegistryPreviewTriggerEvent(); @@ -34,12 +38,14 @@ namespace PowerToys static String SvgPreviewResizeEvent(); static String ShowHostsSharedEvent(); static String ShowHostsAdminSharedEvent(); + static String TerminateHostsSharedEvent(); static String CropAndLockThumbnailEvent(); static String CropAndLockReparentEvent(); static String ShowEnvironmentVariablesSharedEvent(); static String ShowEnvironmentVariablesAdminSharedEvent(); static String WorkspacesLaunchEditorEvent(); static String WorkspacesHotkeyEvent(); + static String PowerToysRunnerTerminateSettingsEvent(); } } } \ No newline at end of file diff --git a/src/common/interop/shared_constants.h b/src/common/interop/shared_constants.h index c98b14310468..364bc6cf7f7f 100644 --- a/src/common/interop/shared_constants.h +++ b/src/common/interop/shared_constants.h @@ -12,6 +12,9 @@ namespace CommonSharedConstants const wchar_t APPDATA_PATH[] = L"Microsoft\\PowerToys"; + // Path to the event used by runner to terminate Settings app + const wchar_t TERMINATE_SETTINGS_SHARED_EVENT[] = L"Local\\PowerToysRunnerTerminateSettingsEvent-c34cb661-2e69-4613-a1f8-4e39c25d7ef6"; + // Path to the event used by PowerLauncher const wchar_t POWER_LAUNCHER_SHARED_EVENT[] = L"Local\\PowerToysRunInvokeEvent-30f26ad7-d36d-4c0e-ab02-68bb5ff3c4ab"; @@ -36,9 +39,13 @@ namespace CommonSharedConstants const wchar_t ADVANCED_PASTE_CUSTOM_ACTION_MESSAGE[] = L"CustomAction"; + const wchar_t ADVANCED_PASTE_TERMINATE_APP_MESSAGE[] = L"TerminateApp"; + // Path to the event used to show Color Picker const wchar_t SHOW_COLOR_PICKER_SHARED_EVENT[] = L"Local\\ShowColorPickerEvent-8c46be2a-3e05-4186-b56b-4ae986ef2525"; + const wchar_t TERMINATE_COLOR_PICKER_SHARED_EVENT[] = L"Local\\TerminateColorPickerEvent-3d676258-c4d5-424e-a87a-4be22020e813"; + const wchar_t SHORTCUT_GUIDE_TRIGGER_EVENT[] = L"Local\\ShortcutGuide-TriggerEvent-d4275ad3-2531-4d19-9252-c0becbd9b496"; const wchar_t SHORTCUT_GUIDE_EXIT_EVENT[] = L"Local\\ShortcutGuide-ExitEvent-35697cdd-a3d2-47d6-a246-34efcc73eac0"; @@ -53,18 +60,24 @@ namespace CommonSharedConstants const wchar_t SHOW_HOSTS_ADMIN_EVENT[] = L"Local\\Hosts-ShowHostsAdminEvent-60ff44e2-efd3-43bf-928a-f4d269f98bec"; + const wchar_t TERMINATE_HOSTS_EVENT[] = L"Local\\Hosts-TerminateHostsEvent-d5410d5e-45a6-4d11-bbf0-a4ec2d064888"; + // Path to the event used by Awake const wchar_t AWAKE_EXIT_EVENT[] = L"Local\\PowerToysAwakeExitEvent-c0d5e305-35fc-4fb5-83ec-f6070cfaf7fe"; // Path to the event used by AlwaysOnTop const wchar_t ALWAYS_ON_TOP_PIN_EVENT[] = L"Local\\AlwaysOnTopPinEvent-892e0aa2-cfa8-4cc4-b196-ddeb32314ce8"; + const wchar_t ALWAYS_ON_TOP_TERMINATE_EVENT[] = L"Local\\AlwaysOnTopTerminateEvent-cfdf1eae-791f-4953-8021-2f18f3837eae"; + // Path to the event used by PowerAccent const wchar_t POWERACCENT_EXIT_EVENT[] = L"Local\\PowerToysPowerAccentExitEvent-53e93389-d19a-4fbb-9b36-1981c8965e17"; // Path to the event used by PowerOCR const wchar_t SHOW_POWEROCR_SHARED_EVENT[] = L"Local\\PowerOCREvent-dc864e06-e1af-4ecc-9078-f98bee745e3a"; + const wchar_t TERMINATE_POWEROCR_SHARED_EVENT[] = L"Local\\TerminatePowerOCREvent-08e5de9d-15df-4ea8-8840-487c13435a67"; + // Path to the events used by Mouse Jump const wchar_t MOUSE_JUMP_SHOW_PREVIEW_EVENT[] = L"Local\\MouseJumpEvent-aa0be051-3396-4976-b7ba-1a9cc7d236a5"; @@ -94,6 +107,11 @@ namespace CommonSharedConstants // Path to the event used to show Peek const wchar_t SHOW_PEEK_SHARED_EVENT[] = L"Local\\ShowPeekEvent"; + // Path to the event used to terminate Peek + const wchar_t TERMINATE_PEEK_SHARED_EVENT[] = L"Local\\TerminatePeekEvent-267149fe-7ed2-427d-a3ad-9e18203c037c"; + + // Path to the event used to terminate KBM + const wchar_t TERMINATE_KBM_SHARED_EVENT[] = L"Local\\TerminateKBMSharedEvent-a787c967-55b6-47de-94d9-56f39fed839e"; // Path to the events used by CropAndLock const wchar_t CROP_AND_LOCK_REPARENT_EVENT[] = L"Local\\PowerToysCropAndLockReparentEvent-6060860a-76a1-44e8-8d0e-6355785e9c36"; diff --git a/src/common/utils/EventWaiter.h b/src/common/utils/EventWaiter.h index 304f475ade83..1a2ba89f02ba 100644 --- a/src/common/utils/EventWaiter.h +++ b/src/common/utils/EventWaiter.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include diff --git a/src/common/utils/gpo.h b/src/common/utils/gpo.h index 0f721d93d547..04e03b476764 100644 --- a/src/common/utils/gpo.h +++ b/src/common/utils/gpo.h @@ -72,6 +72,7 @@ namespace powertoys_gpo { // The registry value names for other PowerToys policies. const std::wstring POLICY_ALLOW_EXPERIMENTATION = L"AllowExperimentation"; + const std::wstring POLICY_ALLOW_DATA_DIAGNOSTICS = L"AllowDataDiagnostics"; const std::wstring POLICY_CONFIGURE_ENABLED_POWER_LAUNCHER_ALL_PLUGINS = L"PowerLauncherAllPluginsEnabledState"; const std::wstring POLICY_ALLOW_ADVANCED_PASTE_ONLINE_AI_MODELS = L"AllowPowerToysAdvancedPasteOnlineAIModels"; const std::wstring POLICY_MWB_CLIPBOARD_SHARING_ENABLED = L"MwbClipboardSharingEnabled"; @@ -487,6 +488,11 @@ namespace powertoys_gpo { return getConfiguredValue(POLICY_ALLOW_EXPERIMENTATION); } + inline gpo_rule_configured_t getAllowDataDiagnosticsValue() + { + return getConfiguredValue(POLICY_ALLOW_DATA_DIAGNOSTICS); + } + inline gpo_rule_configured_t getRunPluginEnabledValue(std::string pluginID) { if (pluginID == "" || pluginID == " ") diff --git a/src/gpo/assets/PowerToys.admx b/src/gpo/assets/PowerToys.admx index 0459a6f601c6..799b1f20f36d 100644 --- a/src/gpo/assets/PowerToys.admx +++ b/src/gpo/assets/PowerToys.admx @@ -5,7 +5,7 @@ - + @@ -22,6 +22,7 @@ + @@ -509,6 +510,16 @@ + + + + + + + + + + diff --git a/src/gpo/assets/en-US/PowerToys.adml b/src/gpo/assets/en-US/PowerToys.adml index 588ccf3d1d76..7a8f037eee5c 100644 --- a/src/gpo/assets/en-US/PowerToys.adml +++ b/src/gpo/assets/en-US/PowerToys.adml @@ -1,7 +1,7 @@ - + PowerToys PowerToys @@ -28,6 +28,7 @@ PowerToys version 0.83.0 or later PowerToys version 0.84.0 or later PowerToys version 0.85.0 or later + PowerToys version 0.86.0 or later This policy configures the enabled state for all PowerToys utilities. @@ -101,6 +102,12 @@ If disabled or not configured, the user can control this in the settings of Powe If this setting is enabled or not configured, the user can control experimentation in the PowerToys settings menu. If this setting is disabled, experimentation is not allowed. + + This policy configures whether sending of PowerToys diagnostic data is allowed. With diagnostic data sending allowed the user helps inform bug fixes, performance and improvements. + +If this setting is enabled or not configured, the user can control diagnostic data sending in the PowerToys settings menu. + +If this setting is disabled, diagnostic data sending is not allowed. This policy configures the enabled state for all PowerToys Run plugins. All plugins will have the same state. @@ -258,6 +265,7 @@ If you don't configure this policy, the user takes control over the setting and Disable user defined IP Address mapping rules Predefined IP Address mapping rules Hide template filename extension + Allow sending diagnostic data diff --git a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs index 77f85518037b..3595276c5d51 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs @@ -18,6 +18,7 @@ using ManagedCommon; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.PowerToys.Telemetry; using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using Windows.Graphics; @@ -38,6 +39,8 @@ public partial class App : Application, IDisposable { public IHost Host { get; private set; } + public ETWTrace EtwTrace { get; private set; } = new ETWTrace(); + private static readonly Dictionary AdditionalActionIPCKeys = typeof(PasteFormats).GetFields() .Where(field => field.IsLiteral) @@ -111,7 +114,11 @@ protected override void OnLaunched(LaunchActivatedEventArgs args) { RunnerHelper.WaitForPowerToysRunner(powerToysRunnerPid, () => { - Environment.Exit(0); + _dispatcherQueue.TryEnqueue(() => + { + Dispose(); + Environment.Exit(0); + }); }); } } @@ -154,6 +161,11 @@ private async Task OnNamedPipeMessage(string message) { await OnAdvancedPasteCustomActionHotkey(messageParts); } + else if (messageType == PowerToys.Interop.Constants.AdvancedPasteTerminateAppMessage()) + { + Dispose(); + Environment.Exit(0); + } } private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) @@ -244,6 +256,7 @@ protected virtual void Dispose(bool disposing) { if (disposing) { + EtwTrace?.Dispose(); window.Dispose(); } diff --git a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/MainWindow.xaml.cs b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/MainWindow.xaml.cs index 8f675e4d4ec2..6536bcfed97b 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/MainWindow.xaml.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/MainWindow.xaml.cs @@ -12,6 +12,7 @@ using AdvancedPaste.ViewModels; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using WinUIEx; @@ -96,6 +97,7 @@ private void Dispose(bool disposing) if (!_disposedValue) { _msgMonitor?.Dispose(); + (Application.Current as App).EtwTrace?.Dispose(); _disposedValue = true; } diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp index 4da030d6ba99..8bd2e0860eeb 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp @@ -384,7 +384,6 @@ class AdvancedPaste : public PowertoyModuleIface m_hProcess = sei.hProcess; } - std::optional get_pipe_name(const std::wstring& prefix) const { UUID temp_uuid; @@ -761,6 +760,8 @@ class AdvancedPaste : public PowertoyModuleIface // Destroy the powertoy and free memory virtual void destroy() override { + Disable(false); + Logger::trace("AdvancedPaste::destroy()"); delete this; } @@ -851,15 +852,21 @@ class AdvancedPaste : public PowertoyModuleIface launch_process_and_named_pipe(); }; - virtual void disable() + void Disable(bool traceEvent) { - Logger::trace("AdvancedPaste::disable()"); if (m_enabled) { + send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_TERMINATE_APP_MESSAGE); + WaitForSingleObject(m_hProcess, 1500); + m_write_pipe = nullptr; TerminateProcess(m_hProcess, 1); - Trace::AdvancedPaste_Enable(false); + + if (traceEvent) + { + Trace::AdvancedPaste_Enable(false); + } CloseHandle(m_hProcess); m_hProcess = 0; @@ -868,6 +875,12 @@ class AdvancedPaste : public PowertoyModuleIface m_enabled = false; } + virtual void disable() + { + Logger::trace("AdvancedPaste::disable()"); + Disable(true); + } + virtual bool on_hotkey(size_t hotkeyId) override { Logger::trace(L"AdvancedPaste hotkey pressed"); diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/pch.h b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/pch.h index 809b965271c8..e730ab203677 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/pch.h +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/pch.h @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include \ No newline at end of file diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/trace.cpp b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/trace.cpp index 0ae92a71875e..aa6162c465b8 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/trace.cpp +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/trace.cpp @@ -8,20 +8,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has AdvancedPaste enabled or disabled void Trace::AdvancedPaste_Enable(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "AdvancedPaste_EnableAdvancedPaste", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +22,7 @@ void Trace::AdvancedPaste_Enable(const bool enabled) noexcept // Log if the user has invoked AdvancedPaste void Trace::AdvancedPaste_Invoked(std::wstring mode) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "AdvancedPaste_InvokeAdvancedPaste", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -43,7 +33,7 @@ void Trace::AdvancedPaste_Invoked(std::wstring mode) noexcept // Log if an error occurs in AdvancedPaste void Trace::AdvancedPaste_Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "AdvancedPaste_Error", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -83,7 +73,7 @@ void Trace::AdvancedPaste_SettingsTelemetry(const PowertoyModuleIface::Hotkey& p return it != additionalActionsHotkeys.end() ? getHotkeyCStr(it->second) : L""; }; - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "AdvancedPaste_Settings", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/trace.h b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/trace.h index 7c0504d58e56..c7cee38877a8 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/trace.h +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/trace.h @@ -1,13 +1,11 @@ #pragma once +#include #include #include -class Trace +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - // Log if the user has AdvancedPaste enabled or disabled static void AdvancedPaste_Enable(const bool enabled) noexcept; diff --git a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj index 0f6c2bb1d1e9..89177bd56f2d 100644 --- a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj +++ b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj @@ -151,6 +151,9 @@ {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + diff --git a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj.filters b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj.filters index 98752f066db8..bea68db119ce 100644 --- a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj.filters +++ b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj.filters @@ -27,6 +27,7 @@ + diff --git a/src/modules/CropAndLock/CropAndLock/main.cpp b/src/modules/CropAndLock/CropAndLock/main.cpp index dc530b7769f4..79d26fc8c14d 100644 --- a/src/modules/CropAndLock/CropAndLock/main.cpp +++ b/src/modules/CropAndLock/CropAndLock/main.cpp @@ -4,16 +4,20 @@ #include "CropAndLockWindow.h" #include "ThumbnailCropAndLockWindow.h" #include "ReparentCropAndLockWindow.h" +#include "ModuleConstants.h" +#include "trace.h" + #include -#include -#include -#include + #include -#include "ModuleConstants.h" +#include #include -#include "trace.h" +#include +#include + +#include -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") namespace winrt { @@ -36,6 +40,11 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I // Initialize COM winrt::init_apartment(winrt::apartment_type::single_threaded); + Trace::CropAndLock::RegisterProvider(); + + Shared::Trace::ETWTrace trace; + trace.UpdateState(true); + // Initialize logger automatic logging of exceptions. LoggerHelpers::init_logger(NonLocalizable::ModuleKey, L"", LogSettings::cropAndLockLoggerName); InitUnhandledExceptionHandler(); @@ -107,8 +116,7 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I HANDLE m_exit_event_handle; std::thread m_event_triggers_thread; - std::function removeWindowCallback = [&](HWND windowHandle) - { + std::function removeWindowCallback = [&](HWND windowHandle) { if (!m_running) { // If we're not running, the reference to croppedWindows might no longer be valid and cause a crash at exit time, due to being called by destructors after wWinMain returns. @@ -122,8 +130,7 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I } }; - std::function ProcessCommand = [&](CropAndLockType mode) - { + std::function ProcessCommand = [&](CropAndLockType mode) { std::function windowCroppedCallback = [&, mode](HWND targetWindow, RECT cropRect) { auto targetInfo = util::WindowInfo(targetWindow); // TODO: Fix WindowInfo.h to not contain the null char at the end. @@ -196,7 +203,7 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I m_event_triggers_thread = std::thread([&]() { MSG msg; - HANDLE event_handles[3] = {m_reparent_event_handle, m_thumbnail_event_handle, m_exit_event_handle}; + HANDLE event_handles[3] = { m_reparent_event_handle, m_thumbnail_event_handle, m_exit_event_handle }; while (m_running) { DWORD dwEvt = MsgWaitForMultipleObjects(3, event_handles, false, INFINITE, QS_ALLINPUT); @@ -258,6 +265,10 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I DispatchMessageW(&msg); } + trace.Flush(); + + Trace::CropAndLock::UnregisterProvider(); + m_running = false; // Needed to unblock MsgWaitForMultipleObjects one last time SetEvent(m_reparent_event_handle); diff --git a/src/modules/CropAndLock/CropAndLock/pch.h b/src/modules/CropAndLock/CropAndLock/pch.h index 720033cbca09..75bb5f4a616f 100644 --- a/src/modules/CropAndLock/CropAndLock/pch.h +++ b/src/modules/CropAndLock/CropAndLock/pch.h @@ -74,7 +74,6 @@ #include "WindowRectUtil.h" // PowerToys -#include #include // Application resources diff --git a/src/modules/CropAndLock/CropAndLock/trace.cpp b/src/modules/CropAndLock/CropAndLock/trace.cpp index fb5dd802c5b6..42674ec62492 100644 --- a/src/modules/CropAndLock/CropAndLock/trace.cpp +++ b/src/modules/CropAndLock/CropAndLock/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + // Telemetry strings should not be localized. #define LoggingProviderKey "Microsoft.PowerToys" @@ -11,19 +13,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::CropAndLock::Enable(bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "CropAndLock_EnableCropAndLock", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -33,7 +25,7 @@ void Trace::CropAndLock::Enable(bool enabled) noexcept void Trace::CropAndLock::ActivateReparent() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "CropAndLock_ActivateReparent", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -42,7 +34,7 @@ void Trace::CropAndLock::ActivateReparent() noexcept void Trace::CropAndLock::ActivateThumbnail() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "CropAndLock_ActivateThumbnail", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -51,7 +43,7 @@ void Trace::CropAndLock::ActivateThumbnail() noexcept void Trace::CropAndLock::CreateReparentWindow() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "CropAndLock_CreateReparentWindow", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -60,7 +52,7 @@ void Trace::CropAndLock::CreateReparentWindow() noexcept void Trace::CropAndLock::CreateThumbnailWindow() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "CropAndLock_CreateThumbnailWindow", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -84,12 +76,11 @@ void Trace::CropAndLock::SettingsTelemetry(PowertoyModuleIface::Hotkey& reparent std::wstring(thumbnailHotkey.alt ? L"Alt + " : L"") + std::wstring(L"VK ") + std::to_wstring(thumbnailHotkey.key); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "CropAndLock_Settings", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingWideString(hotKeyStrReparent.c_str(), "ReparentHotKey"), - TraceLoggingWideString(hotKeyStrThumbnail.c_str(), "ThumbnailHotkey") - ); + TraceLoggingWideString(hotKeyStrThumbnail.c_str(), "ThumbnailHotkey")); } diff --git a/src/modules/CropAndLock/CropAndLock/trace.h b/src/modules/CropAndLock/CropAndLock/trace.h index f7e1903ee62d..5a9aaa95ca4b 100644 --- a/src/modules/CropAndLock/CropAndLock/trace.h +++ b/src/modules/CropAndLock/CropAndLock/trace.h @@ -1,13 +1,12 @@ #pragma once + +#include #include class Trace { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - - class CropAndLock + class CropAndLock : public telemetry::TraceBase { public: static void Enable(bool enabled) noexcept; diff --git a/src/modules/CropAndLock/CropAndLockModuleInterface/dllmain.cpp b/src/modules/CropAndLock/CropAndLockModuleInterface/dllmain.cpp index c313d63cd75a..42c7c6da7e9e 100644 --- a/src/modules/CropAndLock/CropAndLockModuleInterface/dllmain.cpp +++ b/src/modules/CropAndLock/CropAndLockModuleInterface/dllmain.cpp @@ -40,13 +40,13 @@ BOOL APIENTRY DllMain( HMODULE /*hModule*/, switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: - Trace::RegisterProvider(); + Trace::CropAndLock::RegisterProvider(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: - Trace::UnregisterProvider(); + Trace::CropAndLock::UnregisterProvider(); break; } return TRUE; diff --git a/src/modules/CropAndLock/CropAndLockModuleInterface/pch.h b/src/modules/CropAndLock/CropAndLockModuleInterface/pch.h index 0df2e08a6f98..3914e2256155 100644 --- a/src/modules/CropAndLock/CropAndLockModuleInterface/pch.h +++ b/src/modules/CropAndLock/CropAndLockModuleInterface/pch.h @@ -6,7 +6,5 @@ #include #include #include -#include -#include #include #include diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs index bc6f5aa1dac8..e40478f2224b 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs @@ -26,6 +26,8 @@ public partial class App : Application { public IHost Host { get; } + public ETWTrace EtwTrace { get; } = new ETWTrace(); + public static T GetService() where T : class { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml index 78d46d85c77d..32c536101ee4 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml @@ -1,4 +1,4 @@ - + diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs index 7a67a1dfbf90..891fadfe1df9 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs @@ -88,5 +88,10 @@ private static IntPtr WndProc(IntPtr hWnd, NativeMethods.WindowMessage msg, IntP return NativeMethods.CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam); } + + private void Window_Closed(object sender, WindowEventArgs args) + { + (App.Current as EnvironmentVariables.App).EtwTrace?.Dispose(); + } } } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/pch.h b/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/pch.h index 6f700985673e..308dff2b3aa0 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/pch.h +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/pch.h @@ -10,7 +10,6 @@ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files #include -#include #include #include diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/trace.cpp b/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/trace.cpp index bb458c1b6d83..6cb84aed08e3 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/trace.cpp +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has Environment Variables enabled or disabled void Trace::EnableEnvironmentVariables(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "EnvironmentVariables_EnableEnvironmentVariables", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +24,7 @@ void Trace::EnableEnvironmentVariables(const bool enabled) noexcept // Log that the user tried to activate the editor void Trace::ActivateEnvironmentVariables() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "EnvironmentVariables_Activate", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/trace.h b/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/trace.h index 0898da46028d..fa37b043b561 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/trace.h +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - // Log if the user has EnvironmentVariables enabled or disabled static void EnableEnvironmentVariables(const bool enabled) noexcept; diff --git a/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj b/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj index ac0580c2a079..10478cd30c4c 100644 --- a/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj +++ b/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj @@ -128,6 +128,9 @@ MakeAppx.exe pack /d . /p $(OutDir)FileLocksmithContextMenuPackage.msix /nv {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {cc6e41ac-8174-4e8a-8d22-85dd7f4851df} diff --git a/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj.filters b/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj.filters index 5ec858582999..6646b4fc10d9 100644 --- a/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj.filters +++ b/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj.filters @@ -1,5 +1,6 @@  - + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} diff --git a/src/modules/FileLocksmith/FileLocksmithContextMenu/dllmain.cpp b/src/modules/FileLocksmith/FileLocksmithContextMenu/dllmain.cpp index 1abf0e947b28..a597b9ca80f3 100644 --- a/src/modules/FileLocksmith/FileLocksmithContextMenu/dllmain.cpp +++ b/src/modules/FileLocksmith/FileLocksmithContextMenu/dllmain.cpp @@ -1,6 +1,7 @@ // dllmain.cpp : Defines the entry point for the DLL application. #include "pch.h" +#include #include #include #include @@ -20,6 +21,7 @@ using namespace Microsoft::WRL; HINSTANCE g_hInst = 0; +Shared::Trace::ETWTrace trace(L"FileLocksmithContextMenu"); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, @@ -91,6 +93,8 @@ class __declspec(uuid("AAF1E27D-4976-49C2-8895-AAFA743C0A7E")) FileLocksmithCont IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept { + trace.UpdateState(true); + Trace::Invoked(); ipc::Writer writer; @@ -102,6 +106,9 @@ class __declspec(uuid("AAF1E27D-4976-49C2-8895-AAFA743C0A7E")) FileLocksmithCont if (HRESULT result = writer.start(); FAILED(result)) { Trace::InvokedRet(result); + + trace.Flush(); + trace.UpdateState(false); return result; } @@ -114,6 +121,10 @@ class __declspec(uuid("AAF1E27D-4976-49C2-8895-AAFA743C0A7E")) FileLocksmithCont { result = E_FAIL; Trace::InvokedRet(result); + + trace.Flush(); + trace.UpdateState(false); + return result; } @@ -140,6 +151,10 @@ class __declspec(uuid("AAF1E27D-4976-49C2-8895-AAFA743C0A7E")) FileLocksmithCont } Trace::InvokedRet(S_OK); + + trace.Flush(); + trace.UpdateState(false); + return S_OK; } diff --git a/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.cpp b/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.cpp index bc4ab945ca17..49e2e67c1958 100644 --- a/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.cpp +++ b/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.cpp @@ -152,8 +152,13 @@ IFACEMETHODIMP ExplorerCommand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UI if (!InsertMenuItem(hmenu, indexMenu, TRUE, &mii)) { + m_etwTrace.UpdateState(true); + hr = HRESULT_FROM_WIN32(GetLastError()); Trace::QueryContextMenuError(hr); + + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); } else { @@ -166,6 +171,8 @@ IFACEMETHODIMP ExplorerCommand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UI IFACEMETHODIMP ExplorerCommand::InvokeCommand(CMINVOKECOMMANDINFO* pici) { + m_etwTrace.UpdateState(true); + HRESULT hr = E_FAIL; if (FileLocksmithSettingsInstance().GetEnabled() && @@ -178,12 +185,16 @@ IFACEMETHODIMP ExplorerCommand::InvokeCommand(CMINVOKECOMMANDINFO* pici) if (HRESULT result = writer.start(); FAILED(result)) { Trace::InvokedRet(result); + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); return result; } if (HRESULT result = LaunchUI(pici, &writer); FAILED(result)) { Trace::InvokedRet(result); + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); return result; } @@ -217,6 +228,9 @@ IFACEMETHODIMP ExplorerCommand::InvokeCommand(CMINVOKECOMMANDINFO* pici) } Trace::InvokedRet(hr); + + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); return hr; } diff --git a/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.h b/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.h index d59f2661579d..143b6afd9fb8 100644 --- a/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.h +++ b/src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.h @@ -4,6 +4,8 @@ #include "FileLocksmithLib/IPC.h" +#include + #define EXPLORER_COMMAND_UUID_STR "84d68575-e186-46ad-b0cb-baeb45ee29c0" class __declspec(uuid(EXPLORER_COMMAND_UUID_STR)) ExplorerCommand : public IExplorerCommand, public IShellExtInit, public IContextMenu @@ -50,4 +52,6 @@ class __declspec(uuid(EXPLORER_COMMAND_UUID_STR)) ExplorerCommand : public IExpl std::atomic m_ref_count = 1; IDataObject* m_data_obj = NULL; std::wstring context_menu_caption; + + Shared::Trace::ETWTrace m_etwTrace{ L"FileExplorerExt" }; }; diff --git a/src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj b/src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj index 9bfad7f8a830..0c285a8bfae3 100644 --- a/src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj +++ b/src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj @@ -103,6 +103,9 @@ {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/modules/FileLocksmith/FileLocksmithLib/Trace.cpp b/src/modules/FileLocksmith/FileLocksmithLib/Trace.cpp index 98b2f9985da5..a3d8e9038e0e 100644 --- a/src/modules/FileLocksmith/FileLocksmithLib/Trace.cpp +++ b/src/modules/FileLocksmith/FileLocksmithLib/Trace.cpp @@ -1,7 +1,8 @@ #include "pch.h" #include "Trace.h" -#include "../common/Telemetry/ProjectTelemetry.h" + +#include TRACELOGGING_DEFINE_PROVIDER( g_hProvider, @@ -10,19 +11,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::EnableFileLocksmith(_In_ bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "FileLocksmith_EnableFileLocksmith", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +23,7 @@ void Trace::EnableFileLocksmith(_In_ bool enabled) noexcept void Trace::Invoked() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "FileLocksmith_Invoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -41,7 +32,7 @@ void Trace::Invoked() noexcept void Trace::InvokedRet(_In_ HRESULT hr) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "FileLocksmith_InvokedRet", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -51,7 +42,7 @@ void Trace::InvokedRet(_In_ HRESULT hr) noexcept void Trace::QueryContextMenuError(_In_ HRESULT hr) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "FileLocksmith_QueryContextMenuError", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/FileLocksmith/FileLocksmithLib/Trace.h b/src/modules/FileLocksmith/FileLocksmithLib/Trace.h index a9516b5d5cfe..98642de854d1 100644 --- a/src/modules/FileLocksmith/FileLocksmithLib/Trace.h +++ b/src/modules/FileLocksmith/FileLocksmithLib/Trace.h @@ -2,11 +2,11 @@ #include "pch.h" -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; static void EnableFileLocksmith(_In_ bool enabled) noexcept; static void Invoked() noexcept; static void InvokedRet(_In_ HRESULT hr) noexcept; diff --git a/src/modules/Hosts/Hosts/Helpers/NativeEventWaiter.cs b/src/modules/Hosts/Hosts/Helpers/NativeEventWaiter.cs new file mode 100644 index 000000000000..b63468d5539c --- /dev/null +++ b/src/modules/Hosts/Hosts/Helpers/NativeEventWaiter.cs @@ -0,0 +1,30 @@ +// 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.Threading; + +using Microsoft.UI.Dispatching; + +namespace Hosts.Helpers +{ + public static class NativeEventWaiter + { + public static void WaitForEventLoop(string eventName, Action callback) + { + var dispatcherQueue = DispatcherQueue.GetForCurrentThread(); + new Thread(() => + { + var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName); + while (true) + { + if (eventHandle.WaitOne()) + { + dispatcherQueue.TryEnqueue(() => callback()); + } + } + }).Start(); + } + } +} diff --git a/src/modules/Hosts/Hosts/HostsXAML/App.xaml.cs b/src/modules/Hosts/Hosts/HostsXAML/App.xaml.cs index cd4d8b177fe0..7c4d6c389eed 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/App.xaml.cs +++ b/src/modules/Hosts/Hosts/HostsXAML/App.xaml.cs @@ -17,7 +17,7 @@ using Microsoft.PowerToys.Telemetry; using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; - +using PowerToys.Interop; using static HostsUILib.Settings.IUserSettings; using Host = Hosts.Helpers.Host; @@ -93,6 +93,12 @@ public App() cleanupBackupThread.Start(); UnhandledException += App_UnhandledException; + + Hosts.Helpers.NativeEventWaiter.WaitForEventLoop(Constants.TerminateHostsSharedEvent(), () => + { + EtwTrace?.Dispose(); + Environment.Exit(0); + }); } /// @@ -112,6 +118,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs args) RunnerHelper.WaitForPowerToysRunner(powerToysRunnerPid, () => { Logger.LogInfo("PowerToys Runner exited. Exiting Hosts"); + EtwTrace?.Dispose(); dispatcher.TryEnqueue(App.Current.Exit); }); } @@ -133,5 +140,7 @@ private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledEx } private Window window; + + public ETWTrace EtwTrace { get; private set; } = new ETWTrace(); } } diff --git a/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml b/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml index c1229b2ec3ac..73a883f68bd7 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml +++ b/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml @@ -1,4 +1,4 @@ - diff --git a/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml.cs b/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml.cs index 3f8c01de83fe..d1632c21ee6e 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml.cs +++ b/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml.cs @@ -62,5 +62,10 @@ private void Grid_Loaded(object sender, RoutedEventArgs e) MainGrid.Children.Add(MainPage); Grid.SetRow(MainPage, 1); } + + private void WindowEx_Closed(object sender, WindowEventArgs args) + { + (Application.Current as App).EtwTrace?.Dispose(); + } } } diff --git a/src/modules/Hosts/HostsModuleInterface/dllmain.cpp b/src/modules/Hosts/HostsModuleInterface/dllmain.cpp index 85077c8dbef6..807c0829c30e 100644 --- a/src/modules/Hosts/HostsModuleInterface/dllmain.cpp +++ b/src/modules/Hosts/HostsModuleInterface/dllmain.cpp @@ -55,6 +55,8 @@ class HostsModuleInterface : public PowertoyModuleIface HANDLE m_hShowAdminEvent{}; + HANDLE m_hTerminateEvent{}; + bool is_process_running() { return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT; @@ -142,6 +144,17 @@ class HostsModuleInterface : public PowertoyModuleIface } } + m_hTerminateEvent = CreateDefaultEvent(CommonSharedConstants::TERMINATE_HOSTS_EVENT); + if (!m_hTerminateEvent) + { + Logger::error(L"Failed to create terminate hosts event"); + auto message = get_last_error_message(GetLastError()); + if (message.has_value()) + { + Logger::error(message.value()); + } + } + m_showEventWaiter = EventWaiter(CommonSharedConstants::SHOW_HOSTS_EVENT, [&](int err) { if (m_enabled && err == ERROR_SUCCESS) @@ -264,6 +277,8 @@ class HostsModuleInterface : public PowertoyModuleIface ResetEvent(m_hShowAdminEvent); } + SetEvent(m_hTerminateEvent); + WaitForSingleObject(m_hProcess, 1500); TerminateProcess(m_hProcess, 1); } diff --git a/src/modules/Hosts/HostsModuleInterface/pch.h b/src/modules/Hosts/HostsModuleInterface/pch.h index 7c6ad2a235d9..5cb4cbf823d4 100644 --- a/src/modules/Hosts/HostsModuleInterface/pch.h +++ b/src/modules/Hosts/HostsModuleInterface/pch.h @@ -2,4 +2,3 @@ #define WIN32_LEAN_AND_MEAN #include -#include \ No newline at end of file diff --git a/src/modules/Hosts/HostsModuleInterface/trace.cpp b/src/modules/Hosts/HostsModuleInterface/trace.cpp index 391917a8f2ff..104075a82977 100644 --- a/src/modules/Hosts/HostsModuleInterface/trace.cpp +++ b/src/modules/Hosts/HostsModuleInterface/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has HostsFileEditor enabled or disabled void Trace::EnableHostsFileEditor(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "HostsFileEditor_EnableHostsFileEditor", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +24,7 @@ void Trace::EnableHostsFileEditor(const bool enabled) noexcept // Log that the user tried to activate the editor void Trace::ActivateEditor() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "HostsFileEditor_Activate", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/Hosts/HostsModuleInterface/trace.h b/src/modules/Hosts/HostsModuleInterface/trace.h index 92132b7f5448..f3dc6310b5a6 100644 --- a/src/modules/Hosts/HostsModuleInterface/trace.h +++ b/src/modules/Hosts/HostsModuleInterface/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - // Log if the user has HostsFileEditor enabled or disabled static void EnableHostsFileEditor(const bool enabled) noexcept; diff --git a/src/modules/Hosts/HostsUILib/HostsMainPage.xaml.cs b/src/modules/Hosts/HostsUILib/HostsMainPage.xaml.cs index 8f3303c5ca7e..197fab4a3b63 100644 --- a/src/modules/Hosts/HostsUILib/HostsMainPage.xaml.cs +++ b/src/modules/Hosts/HostsUILib/HostsMainPage.xaml.cs @@ -32,7 +32,7 @@ public partial class HostsMainPage : Page public ICommand UpdateAdditionalLinesCommand => new RelayCommand(UpdateAdditionalLines); - public ICommand ExitCommand => new RelayCommand(() => { Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread().TryEnqueue(Application.Current.Exit); }); + public ICommand ExitCommand => new RelayCommand(() => { Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread().TryEnqueue(() => { Environment.Exit(0); }); }); public HostsMainPage(MainViewModel viewModel) { diff --git a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.cpp b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.cpp index d4f90ba678bb..214d8c0818c2 100644 --- a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.cpp +++ b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.cpp @@ -111,7 +111,11 @@ namespace winrt::PowerToys::MeasureToolCore::implementation #endif _overlayUIStates.push_back(std::move(overlayUI)); } + + trace.UpdateState(true); Trace::BoundsToolActivated(); + trace.Flush(); + trace.UpdateState(false); } void Core::StartMeasureTool(const bool horizontal, const bool vertical) @@ -160,7 +164,10 @@ namespace winrt::PowerToys::MeasureToolCore::implementation _screenCaptureThreads.emplace_back(std::move(thread)); } + trace.UpdateState(true); Trace::MeasureToolActivated(); + trace.Flush(); + trace.UpdateState(false); } void MeasureToolCore::implementation::Core::SetToolCompletionEvent(ToolSessionCompleted sessionCompletedTrigger) diff --git a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.h b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.h index 79728794a923..da0b3afb17cd 100644 --- a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.h +++ b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.h @@ -5,6 +5,7 @@ #include "OverlayUI.h" #include "Settings.h" +#include #include #include "ScreenCapturing.h" @@ -50,6 +51,7 @@ namespace winrt::PowerToys::MeasureToolCore::implementation BoundsToolState _boundsToolState; CommonState _commonState; Settings _settings; + Shared::Trace::ETWTrace trace{}; }; } diff --git a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj index b05546d9aace..5bdad6767c0a 100644 --- a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj +++ b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj @@ -125,6 +125,9 @@ {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/modules/MeasureTool/MeasureToolCore/pch.h b/src/modules/MeasureTool/MeasureToolCore/pch.h index 67ca0f9d8cdc..16cc5a1a623b 100644 --- a/src/modules/MeasureTool/MeasureToolCore/pch.h +++ b/src/modules/MeasureTool/MeasureToolCore/pch.h @@ -30,7 +30,6 @@ #include #include #include -#include // Undefine GetCurrentTime macro to prevent // conflict with Storyboard::GetCurrentTime diff --git a/src/modules/MeasureTool/MeasureToolModuleInterface/pch.h b/src/modules/MeasureTool/MeasureToolModuleInterface/pch.h index 207418a9215b..9e02b6c9ceb6 100644 --- a/src/modules/MeasureTool/MeasureToolModuleInterface/pch.h +++ b/src/modules/MeasureTool/MeasureToolModuleInterface/pch.h @@ -9,6 +9,5 @@ #include #include -#include #include #include diff --git a/src/modules/MeasureTool/MeasureToolModuleInterface/trace.cpp b/src/modules/MeasureTool/MeasureToolModuleInterface/trace.cpp index 8c1bb936059c..1a568380482b 100644 --- a/src/modules/MeasureTool/MeasureToolModuleInterface/trace.cpp +++ b/src/modules/MeasureTool/MeasureToolModuleInterface/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,19 +10,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::EnableMeasureTool(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MeasureTool_EnableMeasureTool", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -30,7 +22,7 @@ void Trace::EnableMeasureTool(const bool enabled) noexcept void Trace::BoundsToolActivated() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MeasureTool_BoundsToolActivated", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -39,7 +31,7 @@ void Trace::BoundsToolActivated() noexcept void Trace::MeasureToolActivated() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MeasureTool_MeasureToolActivated", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/MeasureTool/MeasureToolModuleInterface/trace.h b/src/modules/MeasureTool/MeasureToolModuleInterface/trace.h index e85a14bb3844..fb2019c8d541 100644 --- a/src/modules/MeasureTool/MeasureToolModuleInterface/trace.h +++ b/src/modules/MeasureTool/MeasureToolModuleInterface/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - static void EnableMeasureTool(const bool enabled) noexcept; static void BoundsToolActivated() noexcept; diff --git a/src/modules/MouseUtils/FindMyMouse/pch.h b/src/modules/MouseUtils/FindMyMouse/pch.h index 6dbc25600404..26da2455f245 100644 --- a/src/modules/MouseUtils/FindMyMouse/pch.h +++ b/src/modules/MouseUtils/FindMyMouse/pch.h @@ -15,6 +15,5 @@ #endif #include -#include #include #include diff --git a/src/modules/MouseUtils/FindMyMouse/trace.cpp b/src/modules/MouseUtils/FindMyMouse/trace.cpp index a5cfe024172d..bf79461e9a00 100644 --- a/src/modules/MouseUtils/FindMyMouse/trace.cpp +++ b/src/modules/MouseUtils/FindMyMouse/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has FindMyMouse enabled or disabled void Trace::EnableFindMyMouse(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "FindMyMouse_EnableFindMyMouse", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +24,7 @@ void Trace::EnableFindMyMouse(const bool enabled) noexcept // Log that the user activated the module by focusing the mouse pointer void Trace::MousePointerFocused() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "FindMyMouse_MousePointerFocused", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/MouseUtils/FindMyMouse/trace.h b/src/modules/MouseUtils/FindMyMouse/trace.h index 623ce601763c..59d3183b5b31 100644 --- a/src/modules/MouseUtils/FindMyMouse/trace.h +++ b/src/modules/MouseUtils/FindMyMouse/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - // Log if the user has FindMyMouse enabled or disabled static void EnableFindMyMouse(const bool enabled) noexcept; diff --git a/src/modules/MouseUtils/MouseHighlighter/pch.h b/src/modules/MouseUtils/MouseHighlighter/pch.h index bfb4a4776a48..da08f4898a29 100644 --- a/src/modules/MouseUtils/MouseHighlighter/pch.h +++ b/src/modules/MouseUtils/MouseHighlighter/pch.h @@ -16,7 +16,6 @@ #include #endif -#include #include #include #include diff --git a/src/modules/MouseUtils/MouseHighlighter/trace.cpp b/src/modules/MouseUtils/MouseHighlighter/trace.cpp index feefa17745cc..7f8d413b5aac 100644 --- a/src/modules/MouseUtils/MouseHighlighter/trace.cpp +++ b/src/modules/MouseUtils/MouseHighlighter/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has MouseHighlighter enabled or disabled void Trace::EnableMouseHighlighter(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MouseHighlighter_EnableMouseHighlighter", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +24,7 @@ void Trace::EnableMouseHighlighter(const bool enabled) noexcept // Log that the user activated the module by starting a highlighting session void Trace::StartHighlightingSession() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MouseHighlighter_StartHighlightingSession", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/MouseUtils/MouseHighlighter/trace.h b/src/modules/MouseUtils/MouseHighlighter/trace.h index 01d660bbc040..12708940e9ad 100644 --- a/src/modules/MouseUtils/MouseHighlighter/trace.h +++ b/src/modules/MouseUtils/MouseHighlighter/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - // Log if the user has MouseHighlighter enabled or disabled static void EnableMouseHighlighter(const bool enabled) noexcept; diff --git a/src/modules/MouseUtils/MouseJump/pch.h b/src/modules/MouseUtils/MouseJump/pch.h index 74abb62da1ea..575f5e935531 100644 --- a/src/modules/MouseUtils/MouseJump/pch.h +++ b/src/modules/MouseUtils/MouseJump/pch.h @@ -5,6 +5,5 @@ #include //#include -#include #include #include diff --git a/src/modules/MouseUtils/MouseJump/trace.cpp b/src/modules/MouseUtils/MouseJump/trace.cpp index 9f5380284d67..dd2399eb6866 100644 --- a/src/modules/MouseUtils/MouseJump/trace.cpp +++ b/src/modules/MouseUtils/MouseJump/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,19 +10,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::EnableJumpTool(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MouseJump_EnableJumpTool", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -30,7 +22,7 @@ void Trace::EnableJumpTool(const bool enabled) noexcept void Trace::InvokeJumpTool() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MouseJump_InvokeJumpTool", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/MouseUtils/MouseJump/trace.h b/src/modules/MouseUtils/MouseJump/trace.h index aaaa33629135..c70e2c746c81 100644 --- a/src/modules/MouseUtils/MouseJump/trace.h +++ b/src/modules/MouseUtils/MouseJump/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - static void EnableJumpTool(const bool enabled) noexcept; static void InvokeJumpTool() noexcept; diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/pch.h b/src/modules/MouseUtils/MousePointerCrosshairs/pch.h index 5fc459cbc923..124098749863 100644 --- a/src/modules/MouseUtils/MousePointerCrosshairs/pch.h +++ b/src/modules/MouseUtils/MousePointerCrosshairs/pch.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/trace.cpp b/src/modules/MouseUtils/MousePointerCrosshairs/trace.cpp index afc9844bc5a7..00924f030d6e 100644 --- a/src/modules/MouseUtils/MousePointerCrosshairs/trace.cpp +++ b/src/modules/MouseUtils/MousePointerCrosshairs/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has MousePointerCrosshairs enabled or disabled void Trace::EnableMousePointerCrosshairs(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MousePointerCrosshairs_EnableMousePointerCrosshairs", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +24,7 @@ void Trace::EnableMousePointerCrosshairs(const bool enabled) noexcept // Log that the user activated the module by having the crosshairs be drawn void Trace::StartDrawingCrosshairs() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MousePointerCrosshairs_StartDrawingCrosshairs", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/trace.h b/src/modules/MouseUtils/MousePointerCrosshairs/trace.h index d7373e5347e8..b60fc3333633 100644 --- a/src/modules/MouseUtils/MousePointerCrosshairs/trace.h +++ b/src/modules/MouseUtils/MousePointerCrosshairs/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - // Log if the user has MousePointerCrosshairs enabled or disabled static void EnableMousePointerCrosshairs(const bool enabled) noexcept; diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.ShutdownWithPowerToys.cs b/src/modules/MouseWithoutBorders/App/Class/Common.ShutdownWithPowerToys.cs index 8a562e3b706f..7c0dd4eb9b21 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Common.ShutdownWithPowerToys.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Common.ShutdownWithPowerToys.cs @@ -3,9 +3,10 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; +using MouseWithoutBorders.Class; using Logger = MouseWithoutBorders.Core.Logger; @@ -13,12 +14,13 @@ namespace MouseWithoutBorders { internal class ShutdownWithPowerToys { - public static void WaitForPowerToysRunner() + public static void WaitForPowerToysRunner(ETWTrace etwTrace) { try { RunnerHelper.WaitForPowerToysRunnerExitFallback(() => { + etwTrace?.Dispose(); Common.MainForm.Quit(true, false); }); } diff --git a/src/modules/MouseWithoutBorders/App/Class/Program.cs b/src/modules/MouseWithoutBorders/App/Class/Program.cs index 91ed60874ffb..ac33da9ae983 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Program.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Program.cs @@ -57,6 +57,8 @@ private static void Main() ManagedCommon.Logger.InitializeLogger("\\MouseWithoutBorders\\Logs"); Logger.Log(Application.ProductName + " Started!"); + ETWTrace etwTrace = new ETWTrace(); + if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMouseWithoutBordersEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) { Logger.Log("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); @@ -117,7 +119,7 @@ private static void Main() } } - ShutdownWithPowerToys.WaitForPowerToysRunner(); + ShutdownWithPowerToys.WaitForPowerToysRunner(etwTrace); if (firstArg != string.Empty) { @@ -225,6 +227,8 @@ private static void Main() var formScreen = new FrmScreen(); Application.Run(formScreen); + + etwTrace?.Dispose(); } catch (Exception e) { diff --git a/src/modules/MouseWithoutBorders/App/Helper/Program.cs b/src/modules/MouseWithoutBorders/App/Helper/Program.cs index 7a3ae0424b9b..874a0ac2a41f 100644 --- a/src/modules/MouseWithoutBorders/App/Helper/Program.cs +++ b/src/modules/MouseWithoutBorders/App/Helper/Program.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; namespace MouseWithoutBorders { @@ -38,8 +39,11 @@ private static void Main() return; } + ETWTrace etwTrace = new ETWTrace(); + RunnerHelper.WaitForPowerToysRunnerExitFallback(() => { + etwTrace?.Dispose(); Application.Exit(); }); @@ -76,6 +80,8 @@ private static void Main() dotForm = new FormDot(); Application.Run(FormHelper = new FormHelper()); + + etwTrace?.Dispose(); } } } diff --git a/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp b/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp index d2203e6ff5a5..463d52723077 100644 --- a/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp +++ b/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp @@ -22,13 +22,13 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpRese { case DLL_PROCESS_ATTACH: g_hInst_MouseWithoutBorders = hModule; - Trace::RegisterProvider(); + Trace::MouseWithoutBorders::RegisterProvider(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: - Trace::UnregisterProvider(); + Trace::MouseWithoutBorders::UnregisterProvider(); break; } return TRUE; diff --git a/src/modules/MouseWithoutBorders/ModuleInterface/pch.h b/src/modules/MouseWithoutBorders/ModuleInterface/pch.h index cb0737a69da5..0270a7bc3934 100644 --- a/src/modules/MouseWithoutBorders/ModuleInterface/pch.h +++ b/src/modules/MouseWithoutBorders/ModuleInterface/pch.h @@ -9,8 +9,6 @@ #include #include #include -#include -#include #include #include diff --git a/src/modules/MouseWithoutBorders/ModuleInterface/trace.cpp b/src/modules/MouseWithoutBorders/ModuleInterface/trace.cpp index fb2f631bc6c7..7986ceefa41f 100644 --- a/src/modules/MouseWithoutBorders/ModuleInterface/trace.cpp +++ b/src/modules/MouseWithoutBorders/ModuleInterface/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + // Telemetry strings should not be localized. #define LoggingProviderKey "Microsoft.PowerToys" @@ -14,19 +16,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::MouseWithoutBorders::Enable(bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventEnableMouseWithoutBordersKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -36,7 +28,7 @@ void Trace::MouseWithoutBorders::Enable(bool enabled) noexcept void Trace::MouseWithoutBorders::ToggleServiceRegistration(bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MouseWithoutBorders_ToggleServiceRegistration", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -46,7 +38,7 @@ void Trace::MouseWithoutBorders::ToggleServiceRegistration(bool enabled) noexcep void Trace::MouseWithoutBorders::Activate() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MouseWithoutBorders_Activate", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -56,7 +48,7 @@ void Trace::MouseWithoutBorders::Activate() noexcept // Log that the user tried to activate the editor void Trace::MouseWithoutBorders::AddFirewallRule() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "MouseWithoutBorders_AddFirewallRule", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/MouseWithoutBorders/ModuleInterface/trace.h b/src/modules/MouseWithoutBorders/ModuleInterface/trace.h index 1f9099eaaea2..ecd27cbd2d9f 100644 --- a/src/modules/MouseWithoutBorders/ModuleInterface/trace.h +++ b/src/modules/MouseWithoutBorders/ModuleInterface/trace.h @@ -1,12 +1,11 @@ #pragma once +#include + class Trace { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - - class MouseWithoutBorders + class MouseWithoutBorders : public telemetry::TraceBase { public: static void Enable(bool enabled) noexcept; diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj b/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj index 9444e849c0b7..8d2e61757922 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj +++ b/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj @@ -167,6 +167,9 @@ MakeAppx.exe pack /d . /p $(OutDir)NewPlusPackage.msix /nv {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu/dll_main.cpp b/src/modules/NewPlus/NewShellExtensionContextMenu/dll_main.cpp index 5ad3537bb271..878673826b1e 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu/dll_main.cpp +++ b/src/modules/NewPlus/NewShellExtensionContextMenu/dll_main.cpp @@ -4,7 +4,10 @@ #include "dll_main.h" #include "trace.h" +#include + HMODULE module_instance_handle = 0; +Shared::Trace::ETWTrace trace(L"NewPlusShellExtension"); BOOL APIENTRY DllMain(HMODULE module_handle, DWORD ul_reason_for_call, LPVOID reserved) { diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu/dll_main.h b/src/modules/NewPlus/NewShellExtensionContextMenu/dll_main.h index f6c4284a105d..9e980caa0db5 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu/dll_main.h +++ b/src/modules/NewPlus/NewShellExtensionContextMenu/dll_main.h @@ -1,3 +1,6 @@ #pragma once -extern HMODULE module_instance_handle; \ No newline at end of file +#include + +extern HMODULE module_instance_handle; +extern Shared::Trace::ETWTrace trace; \ No newline at end of file diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_sub_menu.cpp b/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_sub_menu.cpp index 148dffd952ad..47f93beac757 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_sub_menu.cpp +++ b/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_sub_menu.cpp @@ -7,6 +7,7 @@ using namespace Microsoft::WRL; // // Sub context menu command enumerator shell_context_sub_menu::shell_context_sub_menu(const ComPtr site_of_folder) { + trace.UpdateState(true); this->site_of_folder = site_of_folder; // Determine the New+ Template folder location diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_sub_menu_item.cpp b/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_sub_menu_item.cpp index 99378f468acd..12e5f9cf5c18 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_sub_menu_item.cpp +++ b/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_sub_menu_item.cpp @@ -63,8 +63,11 @@ IFACEMETHODIMP shell_context_sub_menu_item::GetState(_In_opt_ IShellItemArray* s IFACEMETHODIMP shell_context_sub_menu_item::Invoke(_In_opt_ IShellItemArray*, _In_opt_ IBindCtx*) noexcept { + HRESULT hr = S_OK; try { + trace.UpdateState(true); + // Determine target path of where context menu was displayed const auto target_path_name = utilities::get_path_from_unknown_site(site_of_folder); @@ -90,16 +93,19 @@ IFACEMETHODIMP shell_context_sub_menu_item::Invoke(_In_opt_ IShellItemArray*, _I this->template_entry->enter_rename_mode(site_of_folder, target_final_fullpath); Trace::EventCopyTemplateResult(S_OK); - - return S_OK; } catch (const std::exception& ex) { Trace::EventCopyTemplateResult(S_FALSE); Logger::error(ex.what()); + + hr = S_FALSE; } - return S_FALSE; + trace.Flush(); + trace.UpdateState(false); + + return hr; } IFACEMETHODIMP shell_context_sub_menu_item::GetFlags(_Out_ EXPCMDFLAGS* returned_flags) diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu/trace.cpp b/src/modules/NewPlus/NewShellExtensionContextMenu/trace.cpp index 0def37502486..3a2c8c8c91b7 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu/trace.cpp +++ b/src/modules/NewPlus/NewShellExtensionContextMenu/trace.cpp @@ -10,19 +10,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::EventToggleOnOff(_In_ const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "NewPlus_EventToggleOnOff", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +22,7 @@ void Trace::EventToggleOnOff(_In_ const bool enabled) noexcept void Trace::EventChangedTemplateLocation() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "NewPlus_ChangedTemplateLocation", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -41,7 +31,7 @@ void Trace::EventChangedTemplateLocation() noexcept void Trace::EventShowTemplateItems(const size_t number_of_templates) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "NewPlus_EventShowTemplateItems", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -51,7 +41,7 @@ void Trace::EventShowTemplateItems(const size_t number_of_templates) noexcept void Trace::EventCopyTemplate(_In_ const std::wstring template_file_extension) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "NewPlus_EventCopyTemplate", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -61,7 +51,7 @@ void Trace::EventCopyTemplate(_In_ const std::wstring template_file_extension) n void Trace::EventCopyTemplateResult(_In_ const HRESULT hr) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "NewPlus_EventCopyTemplateResult", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu/trace.h b/src/modules/NewPlus/NewShellExtensionContextMenu/trace.h index 2d87e88588e5..7c21086642fc 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu/trace.h +++ b/src/modules/NewPlus/NewShellExtensionContextMenu/trace.h @@ -2,11 +2,11 @@ #include "pch.h" -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; static void EventToggleOnOff(_In_ const bool new_enabled_state) noexcept; static void EventChangedTemplateLocation() noexcept; static void EventShowTemplateItems(_In_ const size_t number_of_templates) noexcept; diff --git a/src/modules/PowerOCR/PowerOCR/App.xaml.cs b/src/modules/PowerOCR/PowerOCR/App.xaml.cs index eab9acd8cd04..77987ab5cdc6 100644 --- a/src/modules/PowerOCR/PowerOCR/App.xaml.cs +++ b/src/modules/PowerOCR/PowerOCR/App.xaml.cs @@ -6,10 +6,12 @@ using System.Globalization; using System.Threading; using System.Windows; - +using Common.UI; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; using PowerOCR.Keyboard; using PowerOCR.Settings; +using PowerToys.Interop; namespace PowerOCR; @@ -22,6 +24,7 @@ public partial class App : Application, IDisposable private EventMonitor? eventMonitor; private Mutex? _instanceMutex; private int _powerToysRunnerPid; + private ETWTrace etwTrace = new ETWTrace(); private CancellationTokenSource NativeThreadCTS { get; set; } @@ -43,12 +46,19 @@ public App() } NativeThreadCTS = new CancellationTokenSource(); + + NativeEventWaiter.WaitForEventLoop( + Constants.TerminatePowerOCRSharedEvent(), + this.Shutdown, + this.Dispatcher, + NativeThreadCTS.Token); } public void Dispose() { GC.SuppressFinalize(this); keyboardMonitor?.Dispose(); + etwTrace?.Dispose(); } private void Application_Startup(object sender, StartupEventArgs e) diff --git a/src/modules/PowerOCR/PowerOCRModuleInterface/dllmain.cpp b/src/modules/PowerOCR/PowerOCRModuleInterface/dllmain.cpp index 1eebf010ee8e..b9695d6d355d 100644 --- a/src/modules/PowerOCR/PowerOCRModuleInterface/dllmain.cpp +++ b/src/modules/PowerOCR/PowerOCRModuleInterface/dllmain.cpp @@ -69,6 +69,8 @@ class PowerOCR : public PowertoyModuleIface // Handle to event used to invoke PowerOCR HANDLE m_hInvokeEvent; + // Handle to event used to terminate PowerOCR + HANDLE m_hTerminateEvent; void parse_hotkey(PowerToysSettings::PowerToyValues& settings) { @@ -160,6 +162,7 @@ class PowerOCR : public PowertoyModuleIface app_key = PowerOcrConstants::ModuleKey; LoggerHelpers::init_logger(app_key, L"ModuleInterface", "TextExtractor"); m_hInvokeEvent = CreateDefaultEvent(CommonSharedConstants::SHOW_POWEROCR_SHARED_EVENT); + m_hTerminateEvent = CreateDefaultEvent(CommonSharedConstants::TERMINATE_POWEROCR_SHARED_EVENT); init_settings(); } @@ -249,6 +252,8 @@ class PowerOCR : public PowertoyModuleIface if (m_enabled) { ResetEvent(m_hInvokeEvent); + SetEvent(m_hTerminateEvent); + WaitForSingleObject(m_hProcess, 1500); TerminateProcess(m_hProcess, 1); } diff --git a/src/modules/PowerOCR/PowerOCRModuleInterface/pch.h b/src/modules/PowerOCR/PowerOCRModuleInterface/pch.h index eddac0fdc1f3..329705f63b47 100644 --- a/src/modules/PowerOCR/PowerOCRModuleInterface/pch.h +++ b/src/modules/PowerOCR/PowerOCRModuleInterface/pch.h @@ -2,6 +2,5 @@ #include #include #include -#include #include #include \ No newline at end of file diff --git a/src/modules/PowerOCR/PowerOCRModuleInterface/trace.cpp b/src/modules/PowerOCR/PowerOCRModuleInterface/trace.cpp index 67512707261b..979619b91552 100644 --- a/src/modules/PowerOCR/PowerOCRModuleInterface/trace.cpp +++ b/src/modules/PowerOCR/PowerOCRModuleInterface/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has PowerOCR enabled or disabled void Trace::EnablePowerOCR(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerOCR_EnablePowerOCR", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/PowerOCR/PowerOCRModuleInterface/trace.h b/src/modules/PowerOCR/PowerOCRModuleInterface/trace.h index a68576c302c2..b8e428994e34 100644 --- a/src/modules/PowerOCR/PowerOCRModuleInterface/trace.h +++ b/src/modules/PowerOCR/PowerOCRModuleInterface/trace.h @@ -1,10 +1,10 @@ #pragma once -class Trace + +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - // Log if the user has PowerOCR enabled or disabled static void EnablePowerOCR(const bool enabled) noexcept; }; diff --git a/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj b/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj index 68ef97516d39..045be94f2bda 100644 --- a/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj +++ b/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj @@ -158,6 +158,9 @@ {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/modules/ShortcutGuide/ShortcutGuide/main.cpp b/src/modules/ShortcutGuide/ShortcutGuide/main.cpp index 4cd5d78a72ed..713446403bd3 100644 --- a/src/modules/ShortcutGuide/ShortcutGuide/main.cpp +++ b/src/modules/ShortcutGuide/ShortcutGuide/main.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include "shortcut_guide.h" #include "target_state.h" #include "ShortcutGuideConstants.h" @@ -48,6 +50,9 @@ int WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE /*hPrevInst winrt::init_apartment(); LoggerHelpers::init_logger(ShortcutGuideConstants::ModuleKey, L"ShortcutGuide", LogSettings::shortcutGuideLoggerName); + Shared::Trace::ETWTrace trace; + trace.UpdateState(true); + if (powertoys_gpo::getConfiguredShortcutGuideEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) { Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); @@ -132,6 +137,8 @@ int WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE /*hPrevInst window.ShowWindow(); run_message_loop(); + + trace.Flush(); Trace::UnregisterProvider(); return 0; } diff --git a/src/modules/ShortcutGuide/ShortcutGuide/pch.h b/src/modules/ShortcutGuide/ShortcutGuide/pch.h index 7cfa22c4fab5..9ec2bbcb4184 100644 --- a/src/modules/ShortcutGuide/ShortcutGuide/pch.h +++ b/src/modules/ShortcutGuide/ShortcutGuide/pch.h @@ -25,6 +25,5 @@ #include #include #include -#include #include #include \ No newline at end of file diff --git a/src/modules/ShortcutGuide/ShortcutGuide/trace.cpp b/src/modules/ShortcutGuide/ShortcutGuide/trace.cpp index b68e7bbcada3..f2a414d6ac5b 100644 --- a/src/modules/ShortcutGuide/ShortcutGuide/trace.cpp +++ b/src/modules/ShortcutGuide/ShortcutGuide/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,19 +10,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::SendGuideSession(const __int64 duration_ms, const wchar_t* close_type) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "ShortcutGuide_GuideSession", TraceLoggingInt64(duration_ms, "DurationInMs"), @@ -32,7 +24,7 @@ void Trace::SendGuideSession(const __int64 duration_ms, const wchar_t* close_typ void Trace::SendSettings(ShortcutGuideSettings settings) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "ShortcutGuide_Settings", TraceLoggingWideString(settings.hotkey.c_str(), "Hotkey"), diff --git a/src/modules/ShortcutGuide/ShortcutGuide/trace.h b/src/modules/ShortcutGuide/ShortcutGuide/trace.h index 97f9d75bc827..a3446a857078 100644 --- a/src/modules/ShortcutGuide/ShortcutGuide/trace.h +++ b/src/modules/ShortcutGuide/ShortcutGuide/trace.h @@ -1,11 +1,11 @@ #pragma once #include "ShortcutGuideSettings.h" -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; static void SendGuideSession(const __int64 duration_ms, const wchar_t* close_type) noexcept; static void SendSettings(ShortcutGuideSettings settings) noexcept; }; diff --git a/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/pch.h b/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/pch.h index 799a9214a101..37cb34a58ac2 100644 --- a/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/pch.h +++ b/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/pch.h @@ -2,7 +2,6 @@ #define NOMINMAX #include #include -#include #include #include #include \ No newline at end of file diff --git a/src/modules/Workspaces/WorkspacesEditor/App.xaml.cs b/src/modules/Workspaces/WorkspacesEditor/App.xaml.cs index df86a35ed9b3..669230b74490 100644 --- a/src/modules/Workspaces/WorkspacesEditor/App.xaml.cs +++ b/src/modules/Workspaces/WorkspacesEditor/App.xaml.cs @@ -9,6 +9,7 @@ using Common.UI; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; using WorkspacesEditor.Utils; using WorkspacesEditor.ViewModels; @@ -31,6 +32,8 @@ public partial class App : Application, IDisposable private bool _isDisposed; + private ETWTrace etwTrace = new ETWTrace(); + public App() { WorkspacesEditorIO = new WorkspacesEditorIO(); @@ -135,6 +138,7 @@ protected virtual void Dispose(bool disposing) { ThemeManager?.Dispose(); _instanceMutex?.Dispose(); + etwTrace?.Dispose(); } _isDisposed = true; diff --git a/src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs b/src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs index 63bcb15016cc..a0a7f96a069f 100644 --- a/src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs +++ b/src/modules/Workspaces/WorkspacesEditor/MainWindow.xaml.cs @@ -8,6 +8,7 @@ using System.Windows.Interop; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; using WorkspacesEditor.Utils; using WorkspacesEditor.ViewModels; diff --git a/src/modules/Workspaces/WorkspacesLauncher/WorkspacesLauncher.vcxproj b/src/modules/Workspaces/WorkspacesLauncher/WorkspacesLauncher.vcxproj index 8ff482677c0e..9d4fc4bcabb6 100644 --- a/src/modules/Workspaces/WorkspacesLauncher/WorkspacesLauncher.vcxproj +++ b/src/modules/Workspaces/WorkspacesLauncher/WorkspacesLauncher.vcxproj @@ -155,6 +155,9 @@ {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {b31fcc55-b5a4-4ea7-b414-2dceae6af332} diff --git a/src/modules/Workspaces/WorkspacesLauncher/main.cpp b/src/modules/Workspaces/WorkspacesLauncher/main.cpp index 3e7c8c7db1b6..09f63785b11d 100644 --- a/src/modules/Workspaces/WorkspacesLauncher/main.cpp +++ b/src/modules/Workspaces/WorkspacesLauncher/main.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #include @@ -14,6 +16,7 @@ #include #include +#include const std::wstring moduleName = L"Workspaces\\WorkspacesLauncher"; const std::wstring internalPath = L""; @@ -22,7 +25,12 @@ const std::wstring instanceMutexName = L"Local\\PowerToys_WorkspacesLauncher_Ins int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cmdShow) { LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::workspacesLauncherLoggerName); - InitUnhandledExceptionHandler(); + InitUnhandledExceptionHandler(); + + Trace::Workspaces::RegisterProvider(); + + Shared::Trace::ETWTrace trace{}; + trace.UpdateState(true); if (powertoys_gpo::getConfiguredWorkspacesEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) { @@ -60,7 +68,7 @@ int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cm GetModuleFileNameW(nullptr, exe_path.get(), exe_path_size); const auto modulePath = get_module_folderpath(); - + std::string cmdLineStr(cmdline); std::wstring cmdLineWStr(cmdLineStr.begin(), cmdLineStr.end()); @@ -78,7 +86,7 @@ int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cm } SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - + Logger::trace(L"Invoke point: {}", cmdArgs.invokePoint); // read workspaces @@ -105,12 +113,12 @@ int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cm formattedMessage = fmt::format(GET_RESOURCE_STRING(IDS_INCORRECT_FILE_ERROR), file); break; } - + MessageBox(NULL, formattedMessage.c_str(), GET_RESOURCE_STRING(IDS_WORKSPACES).c_str(), MB_ICONERROR | MB_OK); return 1; } } - + if (projectToLaunch.id.empty()) { auto file = WorkspacesData::WorkspacesFile(); @@ -177,7 +185,7 @@ int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cm } } - // update the file before launching, so WorkspacesWindowArranger and WorkspacesLauncherUI could get updated app paths + // update the file before launching, so WorkspacesWindowArranger and WorkspacesLauncherUI could get updated app paths if (updatedApps || updatedIds) { for (int i = 0; i < workspaces.size(); i++) @@ -193,7 +201,14 @@ int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cm } // launch - Launcher launcher(projectToLaunch, workspaces, cmdArgs.invokePoint); + { + Launcher launcher(projectToLaunch, workspaces, cmdArgs.invokePoint); + } + + trace.Flush(); + trace.UpdateState(false); + + Trace::Workspaces::UnregisterProvider(); Logger::trace("Finished"); CoUninitialize(); diff --git a/src/modules/Workspaces/WorkspacesLib/trace.cpp b/src/modules/Workspaces/WorkspacesLib/trace.cpp index 280217505883..5b80fb260177 100644 --- a/src/modules/Workspaces/WorkspacesLib/trace.cpp +++ b/src/modules/Workspaces/WorkspacesLib/trace.cpp @@ -13,19 +13,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::Workspaces::Enable(bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Workspaces_Enable", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -77,7 +67,7 @@ void Trace::Workspaces::Launch(bool success, errorStr += exeName + L":" + errorMessage + L"; "; } - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Workspaces_LaunchEvent", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/Workspaces/WorkspacesLib/trace.h b/src/modules/Workspaces/WorkspacesLib/trace.h index d5569ba0b0f6..addb4bf2453a 100644 --- a/src/modules/Workspaces/WorkspacesLib/trace.h +++ b/src/modules/Workspaces/WorkspacesLib/trace.h @@ -5,13 +5,12 @@ #include #include +#include + class Trace { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - - class Workspaces + class Workspaces : public telemetry::TraceBase { public: static void Enable(bool enabled) noexcept; diff --git a/src/modules/Workspaces/WorkspacesModuleInterface/dllmain.cpp b/src/modules/Workspaces/WorkspacesModuleInterface/dllmain.cpp index 21ccd1926114..90c898fc5f1d 100644 --- a/src/modules/Workspaces/WorkspacesModuleInterface/dllmain.cpp +++ b/src/modules/Workspaces/WorkspacesModuleInterface/dllmain.cpp @@ -38,7 +38,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lp switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: - Trace::RegisterProvider(); + Trace::Workspaces::RegisterProvider(); break; case DLL_THREAD_ATTACH: @@ -46,7 +46,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lp break; case DLL_PROCESS_DETACH: - Trace::UnregisterProvider(); + Trace::Workspaces::UnregisterProvider(); break; } return TRUE; diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp index b9ec910c62f7..491a0bdf4272 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp +++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp @@ -32,10 +32,11 @@ bool isExcluded(HWND window) return check_excluded_app(window, processPath, AlwaysOnTopSettings::settings().excludedApps); } -AlwaysOnTop::AlwaysOnTop(bool useLLKH) : +AlwaysOnTop::AlwaysOnTop(bool useLLKH, DWORD mainThreadId) : SettingsObserver({SettingId::FrameEnabled, SettingId::Hotkey, SettingId::ExcludeApps}), m_hinstance(reinterpret_cast(&__ImageBase)), - m_useCentralizedLLKH(useLLKH) + m_useCentralizedLLKH(useLLKH), + m_mainThreadId(mainThreadId) { s_instance = this; DPIAware::EnableDPIAwarenessForThisProcess(); @@ -282,6 +283,7 @@ void AlwaysOnTop::RegisterLLKH() } m_hPinEvent = CreateEventW(nullptr, false, false, CommonSharedConstants::ALWAYS_ON_TOP_PIN_EVENT); + m_hTerminateEvent = CreateEventW(nullptr, false, false, CommonSharedConstants::ALWAYS_ON_TOP_TERMINATE_EVENT); if (!m_hPinEvent) { @@ -289,11 +291,20 @@ void AlwaysOnTop::RegisterLLKH() return; } - m_thread = std::thread([this]() { + if (!m_hTerminateEvent) + { + Logger::warn(L"Failed to create terminateEvent. {}", get_last_error_or_default(GetLastError())); + return; + } + + HANDLE handles[2] = { m_hPinEvent, + m_hTerminateEvent }; + + m_thread = std::thread([this, handles]() { MSG msg; while (m_running) { - DWORD dwEvt = MsgWaitForMultipleObjects(1, &m_hPinEvent, false, INFINITE, QS_ALLINPUT); + DWORD dwEvt = MsgWaitForMultipleObjects(2, handles, false, INFINITE, QS_ALLINPUT); if (!m_running) { break; @@ -307,6 +318,9 @@ void AlwaysOnTop::RegisterLLKH() } break; case WAIT_OBJECT_0 + 1: + PostThreadMessage(m_mainThreadId, WM_QUIT, 0, 0); + break; + case WAIT_OBJECT_0 + 2: if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.h b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.h index dc41a12d67ea..da14d508b2c1 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.h +++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.h @@ -13,7 +13,7 @@ class AlwaysOnTop : public SettingsObserver { public: - AlwaysOnTop(bool useLLKH); + AlwaysOnTop(bool useLLKH, DWORD mainThreadId); ~AlwaysOnTop(); protected: @@ -48,6 +48,8 @@ class AlwaysOnTop : public SettingsObserver HINSTANCE m_hinstance; std::map> m_topmostWindows{}; HANDLE m_hPinEvent; + HANDLE m_hTerminateEvent; + DWORD m_mainThreadId; std::thread m_thread; const bool m_useCentralizedLLKH; bool m_running = true; diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj index 95e051238ecf..bf3e5c685191 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj +++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj @@ -170,6 +170,9 @@ {1d5be09d-78c0-4fd7-af00-ae7c1af7c525} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + diff --git a/src/modules/alwaysontop/AlwaysOnTop/main.cpp b/src/modules/alwaysontop/AlwaysOnTop/main.cpp index 8b7d901c7d8c..417525a852d4 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/main.cpp +++ b/src/modules/alwaysontop/AlwaysOnTop/main.cpp @@ -1,11 +1,12 @@ #include "pch.h" +#include #include #include #include #include -#include +#include #include #include @@ -17,6 +18,9 @@ const std::wstring instanceMutexName = L"Local\\PowerToys_AlwaysOnTop_InstanceMu int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ int nCmdShow) { + Shared::Trace::ETWTrace trace; + trace.UpdateState(true); + winrt::init_apartment(); LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::alwaysOnTopLoggerName); @@ -39,10 +43,11 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, return 0; } + auto mainThreadId = GetCurrentThreadId(); + std::wstring pid = std::wstring(lpCmdLine); if (!pid.empty()) { - auto mainThreadId = GetCurrentThreadId(); ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) { if (err != ERROR_SUCCESS) { @@ -58,13 +63,15 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, }); } - Trace::RegisterProvider(); + Trace::AlwaysOnTop::RegisterProvider(); - AlwaysOnTop app(!pid.empty()); + AlwaysOnTop app(!pid.empty(), mainThreadId); run_message_loop(); - Trace::UnregisterProvider(); - + Trace::AlwaysOnTop::UnregisterProvider(); + + trace.Flush(); + return 0; } diff --git a/src/modules/alwaysontop/AlwaysOnTop/pch.h b/src/modules/alwaysontop/AlwaysOnTop/pch.h index 848c90fea23d..d3a92e228ffa 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/pch.h +++ b/src/modules/alwaysontop/AlwaysOnTop/pch.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #include diff --git a/src/modules/alwaysontop/AlwaysOnTop/trace.cpp b/src/modules/alwaysontop/AlwaysOnTop/trace.cpp index ae32849bbf13..fb3739f4df91 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/trace.cpp +++ b/src/modules/alwaysontop/AlwaysOnTop/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + // Telemetry strings should not be localized. #define LoggingProviderKey "Microsoft.PowerToys" @@ -16,19 +18,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::AlwaysOnTop::Enable(bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventEnableAlwaysOnTopKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -38,7 +30,7 @@ void Trace::AlwaysOnTop::Enable(bool enabled) noexcept void Trace::AlwaysOnTop::PinWindow() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventPinWindowKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -47,7 +39,7 @@ void Trace::AlwaysOnTop::PinWindow() noexcept void Trace::AlwaysOnTop::UnpinWindow() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventUnpinWindowKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/alwaysontop/AlwaysOnTop/trace.h b/src/modules/alwaysontop/AlwaysOnTop/trace.h index 23c88d3c01ea..05ac601101f2 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/trace.h +++ b/src/modules/alwaysontop/AlwaysOnTop/trace.h @@ -1,12 +1,11 @@ #pragma once +#include + class Trace { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - - class AlwaysOnTop + class AlwaysOnTop : public telemetry::TraceBase { public: static void Enable(bool enabled) noexcept; diff --git a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp index 83158813c683..84cf9ed94928 100644 --- a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp +++ b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp @@ -35,7 +35,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lp switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: - Trace::RegisterProvider(); + Trace::AlwaysOnTop::RegisterProvider(); break; case DLL_THREAD_ATTACH: @@ -43,7 +43,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lp break; case DLL_PROCESS_DETACH: - Trace::UnregisterProvider(); + Trace::AlwaysOnTop::UnregisterProvider(); break; } return TRUE; @@ -174,6 +174,7 @@ class AlwaysOnTopModuleInterface : public PowertoyModuleIface app_name = L"AlwaysOnTop"; //TODO: localize app_key = NonLocalizable::ModuleKey; m_hPinEvent = CreateDefaultEvent(CommonSharedConstants::ALWAYS_ON_TOP_PIN_EVENT); + m_hTerminateEvent = CreateDefaultEvent(CommonSharedConstants::ALWAYS_ON_TOP_TERMINATE_EVENT); init_settings(); } @@ -221,6 +222,12 @@ class AlwaysOnTopModuleInterface : public PowertoyModuleIface Trace::AlwaysOnTop::Enable(false); } + SetEvent(m_hTerminateEvent); + + // Wait for 1.5 seconds for the process to end correctly and stop etw tracer + WaitForSingleObject(m_hProcess, 1500); + + // If process is still running, terminate it if (m_hProcess) { TerminateProcess(m_hProcess, 0); @@ -294,6 +301,7 @@ class AlwaysOnTopModuleInterface : public PowertoyModuleIface // Handle to event used to pin/unpin windows HANDLE m_hPinEvent; + HANDLE m_hTerminateEvent; }; extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() diff --git a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/pch.h b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/pch.h index d70de4e4d436..9dc1f70972c0 100644 --- a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/pch.h +++ b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/pch.h @@ -5,7 +5,5 @@ #include #include #include -#include -#include #include #include diff --git a/src/modules/awake/Awake/Program.cs b/src/modules/awake/Awake/Program.cs index 2dd22db874bb..08995479d444 100644 --- a/src/modules/awake/Awake/Program.cs +++ b/src/modules/awake/Awake/Program.cs @@ -22,6 +22,7 @@ using Awake.Properties; using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.PowerToys.Telemetry; namespace Awake { @@ -30,6 +31,7 @@ internal sealed class Program private static Mutex? _mutex; private static FileSystemWatcher? _watcher; private static SettingsUtils? _settingsUtils; + private static ETWTrace _etwTrace = new ETWTrace(); private static bool _startedFromPowerToys; @@ -177,6 +179,7 @@ private static bool ExitHandler(ControlType ctrlType) private static void Exit(string message, int exitCode) { + _etwTrace?.Dispose(); Logger.LogInfo(message); Manager.CompleteExit(exitCode); } diff --git a/src/modules/awake/AwakeModuleInterface/pch.h b/src/modules/awake/AwakeModuleInterface/pch.h index eddac0fdc1f3..329705f63b47 100644 --- a/src/modules/awake/AwakeModuleInterface/pch.h +++ b/src/modules/awake/AwakeModuleInterface/pch.h @@ -2,6 +2,5 @@ #include #include #include -#include #include #include \ No newline at end of file diff --git a/src/modules/awake/AwakeModuleInterface/trace.cpp b/src/modules/awake/AwakeModuleInterface/trace.cpp index fe90aa26588f..971084e4abac 100644 --- a/src/modules/awake/AwakeModuleInterface/trace.cpp +++ b/src/modules/awake/AwakeModuleInterface/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has Awake enabled or disabled void Trace::EnableAwake(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Awake_EnableAwake", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/awake/AwakeModuleInterface/trace.h b/src/modules/awake/AwakeModuleInterface/trace.h index 40a903b98a9f..95a9a4e46e0b 100644 --- a/src/modules/awake/AwakeModuleInterface/trace.h +++ b/src/modules/awake/AwakeModuleInterface/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - // Log if the user has Awake enabled or disabled static void EnableAwake(const bool enabled) noexcept; }; diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.h b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.h index 96a774ab2ad3..8706bb4cf9c9 100644 --- a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.h +++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.h @@ -11,6 +11,4 @@ // Windows Header Files #include -#include - #endif //PCH_H diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.cpp b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.cpp index 255c46ea9944..c136909f32e8 100644 --- a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.cpp +++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has CmdNotFound enabled or disabled void Trace::EnableCmdNotFoundGpo(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "CmdNotFound_EnableCmdNotFound", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.h b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.h index 4294c510a64d..6fb84c5f1002 100644 --- a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.h +++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - // Log if the user has CmdNotFound enabled or disabled static void EnableCmdNotFoundGpo(const bool enabled) noexcept; }; diff --git a/src/modules/colorPicker/ColorPicker/dllmain.cpp b/src/modules/colorPicker/ColorPicker/dllmain.cpp index ae235a668608..cf7ebec6a0ea 100644 --- a/src/modules/colorPicker/ColorPicker/dllmain.cpp +++ b/src/modules/colorPicker/ColorPicker/dllmain.cpp @@ -67,6 +67,8 @@ class ColorPicker : public PowertoyModuleIface // Handle to event used to invoke ColorPicker HANDLE m_hInvokeEvent; + HANDLE m_hAppTerminateEvent; + void parse_hotkey(PowerToysSettings::PowerToyValues& settings) { auto settingsObject = settings.get_raw_json(); @@ -158,6 +160,7 @@ class ColorPicker : public PowertoyModuleIface LoggerHelpers::init_logger(app_key, L"ModuleInterface", "ColorPicker"); send_telemetry_event = CreateDefaultEvent(CommonSharedConstants::COLOR_PICKER_SEND_SETTINGS_TELEMETRY_EVENT); m_hInvokeEvent = CreateDefaultEvent(CommonSharedConstants::SHOW_COLOR_PICKER_SHARED_EVENT); + m_hAppTerminateEvent = CreateDefaultEvent(CommonSharedConstants::TERMINATE_COLOR_PICKER_SHARED_EVENT); init_settings(); } @@ -249,6 +252,10 @@ class ColorPicker : public PowertoyModuleIface { ResetEvent(send_telemetry_event); ResetEvent(m_hInvokeEvent); + + SetEvent(m_hAppTerminateEvent); + WaitForSingleObject(m_hProcess, 1500); + TerminateProcess(m_hProcess, 1); } diff --git a/src/modules/colorPicker/ColorPicker/pch.h b/src/modules/colorPicker/ColorPicker/pch.h index eddac0fdc1f3..329705f63b47 100644 --- a/src/modules/colorPicker/ColorPicker/pch.h +++ b/src/modules/colorPicker/ColorPicker/pch.h @@ -2,6 +2,5 @@ #include #include #include -#include #include #include \ No newline at end of file diff --git a/src/modules/colorPicker/ColorPicker/trace.cpp b/src/modules/colorPicker/ColorPicker/trace.cpp index 285cea034ef0..61ddb9b3e1a5 100644 --- a/src/modules/colorPicker/ColorPicker/trace.cpp +++ b/src/modules/colorPicker/ColorPicker/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if ColorPicker is enabled or disabled void Trace::EnableColorPicker(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "ColorPicker_EnableColorPicker", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/colorPicker/ColorPicker/trace.h b/src/modules/colorPicker/ColorPicker/trace.h index b13366400818..594239cf34fb 100644 --- a/src/modules/colorPicker/ColorPicker/trace.h +++ b/src/modules/colorPicker/ColorPicker/trace.h @@ -1,10 +1,10 @@ #pragma once -class Trace + +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - // Log if ColorPicker is enabled or disabled static void EnableColorPicker(const bool enabled) noexcept; diff --git a/src/modules/colorPicker/ColorPickerUI/App.xaml.cs b/src/modules/colorPicker/ColorPickerUI/App.xaml.cs index 98646583be83..0621fbc4b98d 100644 --- a/src/modules/colorPicker/ColorPickerUI/App.xaml.cs +++ b/src/modules/colorPicker/ColorPickerUI/App.xaml.cs @@ -10,6 +10,7 @@ using ColorPicker.Mouse; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; namespace ColorPickerUI { @@ -18,6 +19,8 @@ namespace ColorPickerUI /// public partial class App : Application, IDisposable { + public ETWTrace EtwTrace { get; private set; } = new ETWTrace(); + private Mutex _instanceMutex; private static string[] _args; private int _powerToysRunnerPid; @@ -96,6 +99,7 @@ protected virtual void Dispose(bool disposing) if (disposing) { _instanceMutex?.Dispose(); + EtwTrace?.Dispose(); } disposedValue = true; diff --git a/src/modules/colorPicker/ColorPickerUI/ColorEditorWindow.xaml.cs b/src/modules/colorPicker/ColorPickerUI/ColorEditorWindow.xaml.cs index c135f8236290..eb94d86d1ec8 100644 --- a/src/modules/colorPicker/ColorPickerUI/ColorEditorWindow.xaml.cs +++ b/src/modules/colorPicker/ColorPickerUI/ColorEditorWindow.xaml.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Windows; using ColorPicker.Helpers; using Common.UI; diff --git a/src/modules/colorPicker/ColorPickerUI/ViewModels/MainViewModel.cs b/src/modules/colorPicker/ColorPickerUI/ViewModels/MainViewModel.cs index 63772b7963b9..518f253456cc 100644 --- a/src/modules/colorPicker/ColorPickerUI/ViewModels/MainViewModel.cs +++ b/src/modules/colorPicker/ColorPickerUI/ViewModels/MainViewModel.cs @@ -57,6 +57,12 @@ public MainViewModel( _userSettings = userSettings; _keyboardMonitor = keyboardMonitor; + NativeEventWaiter.WaitForEventLoop( + Constants.TerminateColorPickerSharedEvent(), + Application.Current.Shutdown, + Application.Current.Dispatcher, + exitToken); + NativeEventWaiter.WaitForEventLoop( Constants.ShowColorPickerSharedEvent(), _appStateHandler.StartUserSession, diff --git a/src/modules/fancyzones/FancyZones/FancyZones.vcxproj b/src/modules/fancyzones/FancyZones/FancyZones.vcxproj index d61eeb60fddf..b54ee19e3454 100644 --- a/src/modules/fancyzones/FancyZones/FancyZones.vcxproj +++ b/src/modules/fancyzones/FancyZones/FancyZones.vcxproj @@ -146,6 +146,9 @@ {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {f9c68edf-ac74-4b77-9af1-005d9c9f6a99} diff --git a/src/modules/fancyzones/FancyZones/FancyZonesApp.cpp b/src/modules/fancyzones/FancyZones/FancyZonesApp.cpp index afa0bf610c6f..97faec65d5dc 100644 --- a/src/modules/fancyzones/FancyZones/FancyZonesApp.cpp +++ b/src/modules/fancyzones/FancyZones/FancyZonesApp.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,14 @@ FancyZonesApp::FancyZonesApp(const std::wstring& appName, const std::wstring& ap InitializeWinhookEventIds(); m_app = MakeFancyZones(reinterpret_cast(&__ImageBase), std::bind(&FancyZonesApp::DisableModule, this)); + m_mainThreadId = GetCurrentThreadId(); + m_exitEventWaiter = EventWaiter(CommonSharedConstants::FZE_EXIT_EVENT, [&](int err) { + if (err == ERROR_SUCCESS) + { + DisableModule(); + } + }); + InitHooks(); s_instance = this; @@ -111,7 +120,7 @@ void FancyZonesApp::InitHooks() void FancyZonesApp::DisableModule() noexcept { - PostQuitMessage(0); + PostThreadMessage(m_mainThreadId, WM_QUIT, 0, 0); } void FancyZonesApp::HandleWinHookEvent(WinHookEvent* data) noexcept diff --git a/src/modules/fancyzones/FancyZones/FancyZonesApp.h b/src/modules/fancyzones/FancyZones/FancyZonesApp.h index b66ba5b540be..44c6a306a9a2 100644 --- a/src/modules/fancyzones/FancyZones/FancyZonesApp.h +++ b/src/modules/fancyzones/FancyZones/FancyZonesApp.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -15,11 +16,14 @@ class FancyZonesApp private: static inline FancyZonesApp* s_instance = nullptr; static inline HHOOK s_llKeyboardHook = nullptr; - + winrt::com_ptr m_app; HWINEVENTHOOK m_objectLocationWinEventHook = nullptr; std::vector m_staticWinEventHooks; + EventWaiter m_exitEventWaiter; + DWORD m_mainThreadId; + void DisableModule() noexcept; void InitHooks(); diff --git a/src/modules/fancyzones/FancyZones/main.cpp b/src/modules/fancyzones/FancyZones/main.cpp index 3112df7fbbd4..4001673ea364 100644 --- a/src/modules/fancyzones/FancyZones/main.cpp +++ b/src/modules/fancyzones/FancyZones/main.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include #include #include @@ -25,6 +27,9 @@ const std::wstring instanceMutexName = L"Local\\PowerToys_FancyZones_InstanceMut int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ int nCmdShow) { + Shared::Trace::ETWTrace trace{}; + trace.UpdateState(true); + winrt::init_apartment(); LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::fancyZonesLoggerName); @@ -82,6 +87,8 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, run_message_loop(); Trace::UnregisterProvider(); - + + trace.Flush(); + return 0; } diff --git a/src/modules/fancyzones/FancyZones/pch.h b/src/modules/fancyzones/FancyZones/pch.h index 472d051e2502..291159e4e8cf 100644 --- a/src/modules/fancyzones/FancyZones/pch.h +++ b/src/modules/fancyzones/FancyZones/pch.h @@ -1,7 +1,6 @@ #pragma once #define WIN32_LEAN_AND_MEAN #include -#include #include #include #include diff --git a/src/modules/fancyzones/FancyZonesLib/pch.h b/src/modules/fancyzones/FancyZonesLib/pch.h index 70a402b0fa03..d201dabd0c0f 100644 --- a/src/modules/fancyzones/FancyZonesLib/pch.h +++ b/src/modules/fancyzones/FancyZonesLib/pch.h @@ -8,11 +8,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include diff --git a/src/modules/fancyzones/FancyZonesLib/trace.cpp b/src/modules/fancyzones/FancyZonesLib/trace.cpp index 4c6024fe5aeb..69e341197a26 100644 --- a/src/modules/fancyzones/FancyZonesLib/trace.cpp +++ b/src/modules/fancyzones/FancyZonesLib/trace.cpp @@ -10,6 +10,8 @@ #include "FancyZonesLib/FancyZonesDataTypes.h" #include "FancyZonesLib/util.h" +#include + // Telemetry strings should not be localized. #define LoggingProviderKey "Microsoft.PowerToys" @@ -108,19 +110,9 @@ ZoneSetInfo GetZoneSetInfo(_In_opt_ Layout* layout, const LayoutAssignedWindows& return info; } -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::FancyZones::EnableFancyZones(bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventEnableFancyZonesKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -130,7 +122,7 @@ void Trace::FancyZones::EnableFancyZones(bool enabled) noexcept void Trace::FancyZones::OnKeyDown(DWORD vkCode, bool win, bool control, bool inMoveSize) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventKeyDownKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -211,7 +203,7 @@ void Trace::FancyZones::DataChanged() noexcept activeZoneSetInfo += L", custom zone data was deleted"; } } - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventZoneSettingsChangedKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -226,7 +218,7 @@ void Trace::FancyZones::DataChanged() noexcept void Trace::FancyZones::EditorLaunched(int value) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventEditorLaunchKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -237,7 +229,7 @@ void Trace::FancyZones::EditorLaunched(int value) noexcept // Log if an error occurs in FZ void Trace::FancyZones::Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "FancyZones_Error", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -249,7 +241,7 @@ void Trace::FancyZones::Error(const DWORD errorCode, std::wstring errorMessage, void Trace::FancyZones::QuickLayoutSwitched(bool shortcutUsed) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventQuickLayoutSwitchKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -260,7 +252,7 @@ void Trace::FancyZones::QuickLayoutSwitched(bool shortcutUsed) noexcept void Trace::FancyZones::SnapNewWindowIntoZone(Layout* activeLayout, const LayoutAssignedWindows& layoutWindows) noexcept { auto const zoneInfo = GetZoneSetInfo(activeLayout, layoutWindows); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventSnapNewWindowIntoZone, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -273,7 +265,7 @@ void Trace::FancyZones::SnapNewWindowIntoZone(Layout* activeLayout, const Layout void Trace::FancyZones::KeyboardSnapWindowToZone(Layout* activeLayout, const LayoutAssignedWindows& layoutWindows) noexcept { auto const zoneInfo = GetZoneSetInfo(activeLayout, layoutWindows); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventKeyboardSnapWindowToZone, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -299,7 +291,7 @@ void Trace::SettingsTelemetry(const Settings& settings) noexcept auto nextTabHotkeyStr = HotKeyToString(settings.nextTabHotkey); auto prevTabHotkeyStr = HotKeyToString(settings.prevTabHotkey); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventSettingsKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -337,7 +329,7 @@ void Trace::SettingsTelemetry(const Settings& settings) noexcept void Trace::VirtualDesktopChanged() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventDesktopChangedKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -346,7 +338,7 @@ void Trace::VirtualDesktopChanged() noexcept void Trace::WorkArea::KeyUp(WPARAM wParam) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventWorkAreaKeyUpKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -357,7 +349,7 @@ void Trace::WorkArea::KeyUp(WPARAM wParam) noexcept void Trace::WorkArea::MoveOrResizeStarted(_In_opt_ Layout* activeLayout, const LayoutAssignedWindows& layoutWindows) noexcept { auto const zoneInfo = GetZoneSetInfo(activeLayout, layoutWindows); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventMoveOrResizeStartedKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -370,7 +362,7 @@ void Trace::WorkArea::MoveOrResizeStarted(_In_opt_ Layout* activeLayout, const L void Trace::WorkArea::MoveOrResizeEnd(_In_opt_ Layout* activeLayout, const LayoutAssignedWindows& layoutWindows) noexcept { auto const zoneInfo = GetZoneSetInfo(activeLayout, layoutWindows); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventMoveOrResizeEndedKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -383,7 +375,7 @@ void Trace::WorkArea::MoveOrResizeEnd(_In_opt_ Layout* activeLayout, const Layou void Trace::WorkArea::CycleActiveZoneSet(_In_opt_ Layout* activeLayout, const LayoutAssignedWindows& layoutWindows, InputMode mode) noexcept { auto const zoneInfo = GetZoneSetInfo(activeLayout, layoutWindows); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, EventCycleActiveZoneSetKey, ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/fancyzones/FancyZonesLib/trace.h b/src/modules/fancyzones/FancyZonesLib/trace.h index 3bef5cc8c154..db4206fd1f07 100644 --- a/src/modules/fancyzones/FancyZonesLib/trace.h +++ b/src/modules/fancyzones/FancyZonesLib/trace.h @@ -1,16 +1,15 @@ #pragma once +#include + struct Settings; class Layout; class LayoutAssignedWindows; -class Trace +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - - class FancyZones + class FancyZones : public telemetry::TraceBase { public: static void EnableFancyZones(bool enabled) noexcept; @@ -26,7 +25,7 @@ class Trace static void SettingsTelemetry(const Settings& settings) noexcept; static void VirtualDesktopChanged() noexcept; - class WorkArea + class WorkArea : public telemetry::TraceBase { public: enum class InputMode diff --git a/src/modules/fancyzones/FancyZonesModuleInterface/dllmain.cpp b/src/modules/fancyzones/FancyZonesModuleInterface/dllmain.cpp index 40d0aea08f57..f138c4320020 100644 --- a/src/modules/fancyzones/FancyZonesModuleInterface/dllmain.cpp +++ b/src/modules/fancyzones/FancyZonesModuleInterface/dllmain.cpp @@ -205,8 +205,9 @@ class FancyZonesModuleInterface : public PowertoyModuleIface if (m_hProcess) { - TerminateProcess(m_hProcess, 0); SendFZECloseEvent(); + WaitForSingleObject(m_hProcess, 1500); + TerminateProcess(m_hProcess, 0); m_hProcess = nullptr; } } diff --git a/src/modules/fancyzones/FancyZonesModuleInterface/pch.h b/src/modules/fancyzones/FancyZonesModuleInterface/pch.h index d70de4e4d436..9dc1f70972c0 100644 --- a/src/modules/fancyzones/FancyZonesModuleInterface/pch.h +++ b/src/modules/fancyzones/FancyZonesModuleInterface/pch.h @@ -5,7 +5,5 @@ #include #include #include -#include -#include #include #include diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj index f1c2e8975ee6..72f540c0dc25 100644 --- a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj +++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj @@ -1,5 +1,6 @@ - + 16.0 @@ -83,6 +84,7 @@ + diff --git a/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj b/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj index 913e885fa557..e3303f759b94 100644 --- a/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj +++ b/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj @@ -131,6 +131,9 @@ MakeAppx.exe pack /d . /p $(OutDir)ImageResizerContextMenuPackage.msix /nv {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {18b3db45-4ffe-4d01-97d6-5223feee1853} diff --git a/src/modules/imageresizer/ImageResizerContextMenu/dllmain.cpp b/src/modules/imageresizer/ImageResizerContextMenu/dllmain.cpp index 347475fd9014..31335d59a35a 100644 --- a/src/modules/imageresizer/ImageResizerContextMenu/dllmain.cpp +++ b/src/modules/imageresizer/ImageResizerContextMenu/dllmain.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,7 @@ using namespace Microsoft::WRL; HINSTANCE g_hInst = 0; +Shared::Trace::ETWTrace trace(L"ImageResizerContextMenu"); #define BUFSIZE 4096 * 4 @@ -134,6 +136,7 @@ class __declspec(uuid("8F491918-259F-451A-950F-8C3EBF4864AF")) ImageResizerConte IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept try { + trace.UpdateState(true); Trace::Invoked(); HRESULT hr = S_OK; @@ -145,6 +148,9 @@ class __declspec(uuid("8F491918-259F-451A-950F-8C3EBF4864AF")) ImageResizerConte Trace::InvokedRet(hr); + trace.UpdateState(false); + trace.Flush(); + return hr; } CATCH_RETURN(); diff --git a/src/modules/imageresizer/ImageResizerLib/pch.h b/src/modules/imageresizer/ImageResizerLib/pch.h index dcca9b830bbb..3664d7390e67 100644 --- a/src/modules/imageresizer/ImageResizerLib/pch.h +++ b/src/modules/imageresizer/ImageResizerLib/pch.h @@ -13,6 +13,4 @@ #include #include -#include - #endif //PCH_H diff --git a/src/modules/imageresizer/ImageResizerLib/trace.cpp b/src/modules/imageresizer/ImageResizerLib/trace.cpp index 352af3676a02..1c0caef2c354 100644 --- a/src/modules/imageresizer/ImageResizerLib/trace.cpp +++ b/src/modules/imageresizer/ImageResizerLib/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,19 +10,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::EnableImageResizer(_In_ bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "ImageResizer_EnableImageResizer", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -28,10 +20,9 @@ void Trace::EnableImageResizer(_In_ bool enabled) noexcept TraceLoggingBoolean(enabled, "Enabled")); } - void Trace::Invoked() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "ImageResizer_Invoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -40,7 +31,7 @@ void Trace::Invoked() noexcept void Trace::InvokedRet(_In_ HRESULT hr) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "ImageResizer_InvokedRet", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -50,7 +41,7 @@ void Trace::InvokedRet(_In_ HRESULT hr) noexcept void Trace::QueryContextMenuError(_In_ HRESULT hr) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "ImageResizer_QueryContextMenuError", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/imageresizer/ImageResizerLib/trace.h b/src/modules/imageresizer/ImageResizerLib/trace.h index 9ff1e49f4e97..a337e70b033d 100644 --- a/src/modules/imageresizer/ImageResizerLib/trace.h +++ b/src/modules/imageresizer/ImageResizerLib/trace.h @@ -1,10 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; static void EnableImageResizer(_In_ bool enabled) noexcept; static void Invoked() noexcept; static void InvokedRet(_In_ HRESULT hr) noexcept; diff --git a/src/modules/imageresizer/dll/ContextMenuHandler.cpp b/src/modules/imageresizer/dll/ContextMenuHandler.cpp index dd86eed5fbb1..32eced160820 100644 --- a/src/modules/imageresizer/dll/ContextMenuHandler.cpp +++ b/src/modules/imageresizer/dll/ContextMenuHandler.cpp @@ -161,8 +161,13 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu, if (!InsertMenuItem(hmenu, indexMenu, TRUE, &mii)) { + m_etwTrace.UpdateState(true); + hr = HRESULT_FROM_WIN32(GetLastError()); Trace::QueryContextMenuError(hr); + + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); } else { @@ -193,6 +198,8 @@ HRESULT CContextMenuHandler::GetCommandString(UINT_PTR idCmd, UINT uType, _In_ U HRESULT CContextMenuHandler::InvokeCommand(_In_ CMINVOKECOMMANDINFO* pici) { + m_etwTrace.UpdateState(true); + BOOL fUnicode = FALSE; Trace::Invoked(); HRESULT hr = E_FAIL; @@ -216,6 +223,10 @@ HRESULT CContextMenuHandler::InvokeCommand(_In_ CMINVOKECOMMANDINFO* pici) hr = ResizePictures(pici, nullptr); } Trace::InvokedRet(hr); + + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); + return hr; } @@ -427,8 +438,14 @@ HRESULT __stdcall CContextMenuHandler::EnumSubCommands(IEnumExplorerCommand** pp // psiItemArray contains the list of files that have been selected when the context menu entry is invoked HRESULT __stdcall CContextMenuHandler::Invoke(IShellItemArray* psiItemArray, IBindCtx* /*pbc*/) { + m_etwTrace.UpdateState(true); + Trace::Invoked(); HRESULT hr = ResizePictures(nullptr, psiItemArray); Trace::InvokedRet(hr); + + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); + return hr; } diff --git a/src/modules/imageresizer/dll/ContextMenuHandler.h b/src/modules/imageresizer/dll/ContextMenuHandler.h index ba1465df88a9..abcadfa972cf 100644 --- a/src/modules/imageresizer/dll/ContextMenuHandler.h +++ b/src/modules/imageresizer/dll/ContextMenuHandler.h @@ -5,6 +5,7 @@ #include "pch.h" #include "Generated Files/resource.h" #include "ImageResizerExt_i.h" +#include #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms." @@ -53,6 +54,7 @@ class ATL_NO_VTABLE __declspec(uuid("51B4D7E5-7568-4234-B4BB-47FB3C016A69")) CCo HBITMAP m_hbmpIcon = nullptr; std::wstring context_menu_caption; std::wstring context_menu_caption_here; + Shared::Trace::ETWTrace m_etwTrace{ L"ImageResizerExt" }; }; OBJECT_ENTRY_AUTO(__uuidof(ContextMenuHandler), CContextMenuHandler) \ No newline at end of file diff --git a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj index 90bcd8e357e8..df038e2c4312 100644 --- a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj +++ b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj @@ -80,12 +80,14 @@ false - + + false - + + Create @@ -120,6 +122,9 @@ {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/modules/imageresizer/dll/pch.h b/src/modules/imageresizer/dll/pch.h index 4fef14e85a2a..a6dd9999a9a0 100644 --- a/src/modules/imageresizer/dll/pch.h +++ b/src/modules/imageresizer/dll/pch.h @@ -22,4 +22,3 @@ #include #include -#include diff --git a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp index 260e4c1f5cee..5b18b791f06e 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp @@ -80,7 +80,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, std::wstring keysForShortcutToEdit = L""; std::wstring action = L""; - // do some parsing of the cmdline arg to see if we need to behave different // like, single edit mode, or "delete" mode. // These extra args are from "OpenEditor" in the KeyboardManagerViewModel diff --git a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.vcxproj index 149ec0201ab1..1cc89c157bfc 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.vcxproj @@ -132,6 +132,9 @@ {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditKeyboardWindow.cpp b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditKeyboardWindow.cpp index 6bf0994e3fe4..3597107808d8 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditKeyboardWindow.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditKeyboardWindow.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include @@ -426,11 +428,15 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan void CreateEditKeyboardWindow(HINSTANCE hInst, KBMEditor::KeyboardManagerState& keyboardManagerState, MappingConfiguration& mappingConfiguration) { + Shared::Trace::ETWTrace trace; + trace.UpdateState(true); + // Move implementation into the separate method so resources get destroyed correctly CreateEditKeyboardWindowImpl(hInst, keyboardManagerState, mappingConfiguration); // Calling ClearXamlIslands() outside of the message loop is not enough to prevent // Microsoft.UI.XAML.dll from crashing during deinitialization, see https://github.com/microsoft/PowerToys/issues/10906 + trace.Flush(); Logger::trace("Terminating process {}", GetCurrentProcessId()); Logger::flush(); TerminateProcess(GetCurrentProcess(), 0); diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditShortcutsWindow.cpp b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditShortcutsWindow.cpp index c85c36cde274..0a2f044765d2 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditShortcutsWindow.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditShortcutsWindow.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include "KeyboardManagerState.h" #include "Dialog.h" #include "KeyDropDownControl.h" @@ -447,11 +449,15 @@ inline void CreateEditShortcutsWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMa void CreateEditShortcutsWindow(HINSTANCE hInst, KBMEditor::KeyboardManagerState& keyboardManagerState, MappingConfiguration& mappingConfiguration, std::wstring keysForShortcutToEdit, std::wstring action) { + Shared::Trace::ETWTrace trace; + trace.UpdateState(true); + // Move implementation into the separate method so resources get destroyed correctly CreateEditShortcutsWindowImpl(hInst, keyboardManagerState, mappingConfiguration, keysForShortcutToEdit, action); // Calling ClearXamlIslands() outside of the message loop is not enough to prevent // Microsoft.UI.XAML.dll from crashing during deinitialization, see https://github.com/microsoft/PowerToys/issues/10906 + trace.Flush(); Logger::trace("Terminating process {}", GetCurrentProcessId()); Logger::flush(); TerminateProcess(GetCurrentProcess(), 0); diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/pch.h b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/pch.h index ffc3ff39aa2a..316ab36e42ab 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/pch.h +++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/pch.h @@ -29,8 +29,6 @@ #include #include -#include - #include //#include diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/trace.cpp b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/trace.cpp index 290b11cc4124..54ec7539b1bc 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/trace.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log number of key remaps when the user uses Edit Keyboard and saves settings void Trace::KeyRemapCount(const DWORD keyToKeyCount, const DWORD keyToShortcutCount, const DWORD keyToTextCount) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_KeyRemapCount", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -35,7 +27,7 @@ void Trace::KeyRemapCount(const DWORD keyToKeyCount, const DWORD keyToShortcutCo // Log number of os level shortcut remaps when the user uses Edit Shortcuts and saves settings void Trace::OSLevelShortcutRemapCount(const DWORD shortcutToShortcutCount, const DWORD shortcutToKeyCount) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_OSLevelShortcutRemapCount", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -48,7 +40,7 @@ void Trace::OSLevelShortcutRemapCount(const DWORD shortcutToShortcutCount, const // Log number of app specific shortcut remaps when the user uses Edit Shortcuts and saves settings void Trace::AppSpecificShortcutRemapCount(const DWORD shortcutToShortcutCount, const DWORD shortcutToKeyCount) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_AppSpecificShortcutRemapCount", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -61,7 +53,7 @@ void Trace::AppSpecificShortcutRemapCount(const DWORD shortcutToShortcutCount, c // Log if an error occurs in KBM void Trace::Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_Error", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/trace.h b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/trace.h index b91f5b625b9e..9c219bf8e885 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/trace.h +++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - // Log number of key remaps when the user uses Edit Keyboard and saves settings static void KeyRemapCount(const DWORD keyToKeyCount, const DWORD keyToShortcutCount, const DWORD keyToTextCount) noexcept; diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorTest/pch.h b/src/modules/keyboardmanager/KeyboardManagerEditorTest/pch.h index 6364eacd4827..4cf0be54c253 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorTest/pch.h +++ b/src/modules/keyboardmanager/KeyboardManagerEditorTest/pch.h @@ -1,7 +1,6 @@ #pragma once #define WIN32_LEAN_AND_MEAN #include -#include #include #include #include diff --git a/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj index 55d97e0b0057..fd7b4a97c3b5 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj @@ -67,6 +67,9 @@ {6955446d-23f7-4023-9bb3-8657f904af99} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {e496b7fc-1e99-4bab-849b-0e8367040b02} diff --git a/src/modules/keyboardmanager/KeyboardManagerEngine/main.cpp b/src/modules/keyboardmanager/KeyboardManagerEngine/main.cpp index 31417e9c235f..5969ed6cfd1a 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngine/main.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEngine/main.cpp @@ -1,4 +1,6 @@ #include "pch.h" +#include +#include #include #include #include @@ -8,6 +10,7 @@ #include #include #include +#include const std::wstring instanceMutexName = L"Local\\PowerToys_KBMEngine_InstanceMutex"; @@ -19,6 +22,9 @@ int WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/, winrt::init_apartment(); LoggerHelpers::init_logger(KeyboardManagerConstants::ModuleName, L"Engine", LogSettings::keyboardManagerLoggerName); + Shared::Trace::ETWTrace trace; + trace.UpdateState(true); + if (powertoys_gpo::getConfiguredKeyboardManagerEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) { Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); @@ -42,9 +48,15 @@ int WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/, Trace::RegisterProvider(); std::wstring pid = std::wstring(lpCmdLine); + + auto mainThreadId = GetCurrentThreadId(); + + EventWaiter ev = EventWaiter(CommonSharedConstants::TERMINATE_KBM_SHARED_EVENT, [&](int) { + PostThreadMessage(mainThreadId, WM_QUIT, 0, 0); + }); + if (!pid.empty()) { - auto mainThreadId = GetCurrentThreadId(); ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) { if (err != ERROR_SUCCESS) { @@ -73,5 +85,7 @@ int WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/, kbm.StopLowlevelKeyboardHook(); Trace::UnregisterProvider(); + trace.Flush(); + return 0; } diff --git a/src/modules/keyboardmanager/KeyboardManagerEngine/pch.h b/src/modules/keyboardmanager/KeyboardManagerEngine/pch.h index 472d051e2502..291159e4e8cf 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngine/pch.h +++ b/src/modules/keyboardmanager/KeyboardManagerEngine/pch.h @@ -1,7 +1,6 @@ #pragma once #define WIN32_LEAN_AND_MEAN #include -#include #include #include #include diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/pch.h b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/pch.h index ded05a85a7bd..817bab9a85f0 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/pch.h +++ b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/pch.h @@ -1,7 +1,6 @@ #pragma once #define WIN32_LEAN_AND_MEAN #include -#include #include #include #include diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.cpp b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.cpp index fd112552833c..ab3e49cb870f 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.cpp @@ -2,6 +2,8 @@ #include "trace.h" #include +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -9,74 +11,64 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if a key to key remap has been invoked today. void Trace::DailyKeyToKeyRemapInvoked() noexcept { - TraceLoggingWrite( - g_hProvider, - "KeyboardManager_DailyKeyToKeyRemapInvoked", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWriteWrapper( + g_hProvider, + "KeyboardManager_DailyKeyToKeyRemapInvoked", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } // Log if a key to shortcut remap has been invoked today. void Trace::DailyKeyToShortcutRemapInvoked() noexcept { - TraceLoggingWrite( - g_hProvider, - "KeyboardManager_DailyKeyToShortcutRemapInvoked", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWriteWrapper( + g_hProvider, + "KeyboardManager_DailyKeyToShortcutRemapInvoked", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } // Log if a shortcut to key remap has been invoked today. void Trace::DailyShortcutToKeyRemapInvoked() noexcept { - TraceLoggingWrite( - g_hProvider, - "KeyboardManager_DailyShortcutToKeyRemapInvoked", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWriteWrapper( + g_hProvider, + "KeyboardManager_DailyShortcutToKeyRemapInvoked", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } // Log if a shortcut to shortcut remap has been invoked today. void Trace::DailyShortcutToShortcutRemapInvoked() noexcept { - TraceLoggingWrite( - g_hProvider, - "KeyboardManager_DailyShortcutToShortcutRemapInvoked", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWriteWrapper( + g_hProvider, + "KeyboardManager_DailyShortcutToShortcutRemapInvoked", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } // Log if an app specific shortcut to key remap has been invoked today. void Trace::DailyAppSpecificShortcutToKeyRemapInvoked() noexcept { - TraceLoggingWrite( - g_hProvider, - "KeyboardManager_DailyAppSpecificShortcutToKeyRemapInvoked", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWriteWrapper( + g_hProvider, + "KeyboardManager_DailyAppSpecificShortcutToKeyRemapInvoked", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } // Log if an app specific shortcut to shortcut remap has been invoked today. void Trace::DailyAppSpecificShortcutToShortcutRemapInvoked() noexcept { - TraceLoggingWrite( - g_hProvider, - "KeyboardManager_DailyAppSpecificShortcutToShortcutRemapInvoked", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWriteWrapper( + g_hProvider, + "KeyboardManager_DailyAppSpecificShortcutToShortcutRemapInvoked", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } // Log if a key remap has been invoked (not being used currently, due to being garrulous) @@ -84,7 +76,7 @@ void Trace::KeyRemapInvoked(bool isKeyToKey) noexcept { if (isKeyToKey) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_KeyToKeyRemapInvoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -92,7 +84,7 @@ void Trace::KeyRemapInvoked(bool isKeyToKey) noexcept } else { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_KeyToShortcutRemapInvoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -107,7 +99,7 @@ void Trace::ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific) { if (isShortcutToShortcut) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_AppSpecificShortcutToShortcutRemapInvoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -115,7 +107,7 @@ void Trace::ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific) } else { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_AppSpecificShortcutToKeyRemapInvoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -126,7 +118,7 @@ void Trace::ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific) { if (isShortcutToShortcut) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_OSLevelShortcutToShortcutRemapInvoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -134,7 +126,7 @@ void Trace::ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific) } else { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_OSLevelShortcutToKeyRemapInvoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -144,7 +136,7 @@ void Trace::ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific) } // Function to return a human readable string for the shortcut -std::wstring GetShortcutHumanReadableString(Shortcut const & shortcut, LayoutMap& keyboardMap) +std::wstring GetShortcutHumanReadableString(Shortcut const& shortcut, LayoutMap& keyboardMap) { std::wstring humanReadableShortcut = L""; if (shortcut.winKey != ModifierKey::Disabled) @@ -184,7 +176,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce if (keyRemap.second.index() == 0) // 0 - Remapping to key { DWORD keyRemappedTo = std::get(keyRemap.second); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_KeyRemapConfigurationLoaded", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -192,13 +184,12 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce TraceLoggingInt64(keyRemap.first, "KeyRemapFrom"), TraceLoggingInt64(keyRemappedTo, "KeyRemapTo"), TraceLoggingWideString(keyboardMap.GetKeyName(keyRemap.first).c_str(), "HumanRemapFrom"), - TraceLoggingWideString(keyboardMap.GetKeyName(keyRemappedTo).c_str(), "HumanRemapTo") - ); + TraceLoggingWideString(keyboardMap.GetKeyName(keyRemappedTo).c_str(), "HumanRemapTo")); } else if (keyRemap.second.index() == 1) // 1 - Remapping to shortcut { Shortcut shortcutRemappedTo = std::get(keyRemap.second); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_KeyRemapConfigurationLoaded", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -210,8 +201,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce TraceLoggingInt8(static_cast(shortcutRemappedTo.altKey), "ModifierRemapToAlt"), TraceLoggingInt8(static_cast(shortcutRemappedTo.shiftKey), "ModifierRemapToShift"), TraceLoggingWideString(keyboardMap.GetKeyName(keyRemap.first).c_str(), "HumanRemapFrom"), - TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedTo, keyboardMap).c_str(), "HumanRemapTo") - ); + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedTo, keyboardMap).c_str(), "HumanRemapTo")); } } @@ -221,7 +211,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce if (shortcutRemap.second.targetShortcut.index() == 0) // 0 - Remapping to key { DWORD keyRemappedTo = std::get(shortcutRemap.second.targetShortcut); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_ShortcutRemapConfigurationLoaded", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -245,7 +235,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce // Don't include Start app or Open URI mappings in this telemetry. continue; } - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_ShortcutRemapConfigurationLoaded", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -263,8 +253,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce TraceLoggingInt8(static_cast(shortcutRemappedTo.altKey), "ModifierRemapToAlt"), TraceLoggingInt8(static_cast(shortcutRemappedTo.shiftKey), "ModifierRemapToShift"), TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedFrom, keyboardMap).c_str(), "HumanRemapFrom"), - TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedTo, keyboardMap).c_str(), "HumanRemapTo") - ); + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedTo, keyboardMap).c_str(), "HumanRemapTo")); } } @@ -277,7 +266,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce if (shortcutRemap.second.targetShortcut.index() == 0) // 0 - Remapping to key { DWORD keyRemappedTo = std::get(shortcutRemap.second.targetShortcut); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_AppSpecificShortcutRemapConfigurationLoaded", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -292,8 +281,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce TraceLoggingInt64(keyRemappedTo, "KeyRemapTo"), TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedFrom, keyboardMap).c_str(), "HumanRemapFrom"), TraceLoggingWideString(keyboardMap.GetKeyName(keyRemappedTo).c_str(), "HumanRemapTo"), - TraceLoggingWideString(appName.c_str(), "TargetApp") - ); + TraceLoggingWideString(appName.c_str(), "TargetApp")); } else if (shortcutRemap.second.targetShortcut.index() == 1) // 1 - Remapping to shortcut { @@ -303,7 +291,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce // Don't include Start app or Open URI mappings in this telemetry. continue; } - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_AppSpecificShortcutRemapConfigurationLoaded", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -322,8 +310,7 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce TraceLoggingInt8(static_cast(shortcutRemappedTo.shiftKey), "ModifierRemapToShift"), TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedFrom, keyboardMap).c_str(), "HumanRemapFrom"), TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedTo, keyboardMap).c_str(), "HumanRemapTo"), - TraceLoggingWideString(appName.c_str(), "TargetApp") - ); + TraceLoggingWideString(appName.c_str(), "TargetApp")); } } } @@ -332,18 +319,17 @@ void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexce // Log an error while trying to send remappings telemetry. void Trace::ErrorSendingKeyAndShortcutRemapLoadedConfiguration() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_ErrorSendingKeyAndShortcutRemapLoadedConfiguration", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } - // Log if an error occurs in KBM void Trace::Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_Error", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.h b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.h index 9408a38e0e6b..8a91eef9c434 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.h +++ b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.h @@ -2,12 +2,11 @@ #include "State.h" -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - // Log if a key to key remap has been invoked today. static void DailyKeyToKeyRemapInvoked() noexcept; diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineTest/pch.h b/src/modules/keyboardmanager/KeyboardManagerEngineTest/pch.h index 6364eacd4827..4cf0be54c253 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineTest/pch.h +++ b/src/modules/keyboardmanager/KeyboardManagerEngineTest/pch.h @@ -1,7 +1,6 @@ #pragma once #define WIN32_LEAN_AND_MEAN #include -#include #include #include #include diff --git a/src/modules/keyboardmanager/common/pch.h b/src/modules/keyboardmanager/common/pch.h index e01018e71e22..48c81b6cafc5 100644 --- a/src/modules/keyboardmanager/common/pch.h +++ b/src/modules/keyboardmanager/common/pch.h @@ -6,4 +6,3 @@ #include #include #include -#include \ No newline at end of file diff --git a/src/modules/keyboardmanager/dll/dllmain.cpp b/src/modules/keyboardmanager/dll/dllmain.cpp index e76fd5f7166f..11fe77628167 100644 --- a/src/modules/keyboardmanager/dll/dllmain.cpp +++ b/src/modules/keyboardmanager/dll/dllmain.cpp @@ -8,6 +8,7 @@ #include #include #include +#include BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) { @@ -42,6 +43,8 @@ class KeyboardManager : public PowertoyModuleIface HANDLE m_hProcess = nullptr; + HANDLE m_hTerminateEngineEvent = nullptr; + public: // Constructor KeyboardManager() @@ -51,6 +54,17 @@ class KeyboardManager : public PowertoyModuleIface std::filesystem::path oldLogPath(PTSettingsHelper::get_module_save_folder_location(app_key)); oldLogPath.append("Logs"); LoggerHelpers::delete_old_log_folder(oldLogPath); + + m_hTerminateEngineEvent = CreateDefaultEvent(CommonSharedConstants::TERMINATE_KBM_SHARED_EVENT); + if (!m_hTerminateEngineEvent) + { + Logger::error(L"Failed to create terminate Engine event"); + auto message = get_last_error_message(GetLastError()); + if (message.has_value()) + { + Logger::error(message.value()); + } + } }; // Destroy the powertoy and free memory @@ -158,6 +172,9 @@ class KeyboardManager : public PowertoyModuleIface if (m_hProcess) { + SetEvent(m_hTerminateEngineEvent); + WaitForSingleObject(m_hProcess, 1500); + TerminateProcess(m_hProcess, 0); m_hProcess = nullptr; } diff --git a/src/modules/keyboardmanager/dll/pch.h b/src/modules/keyboardmanager/dll/pch.h index c4c30cb1ea2f..350550e299e8 100644 --- a/src/modules/keyboardmanager/dll/pch.h +++ b/src/modules/keyboardmanager/dll/pch.h @@ -1,7 +1,6 @@ #pragma once #define WIN32_LEAN_AND_MEAN #include -#include #include #include #include diff --git a/src/modules/keyboardmanager/dll/trace.cpp b/src/modules/keyboardmanager/dll/trace.cpp index 798204cae805..82057baefb0d 100644 --- a/src/modules/keyboardmanager/dll/trace.cpp +++ b/src/modules/keyboardmanager/dll/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has KBM enabled or disabled - Can also be used to see how often users have to restart the keyboard hook void Trace::EnableKeyboardManager(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "KeyboardManager_EnableKeyboardManager", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/keyboardmanager/dll/trace.h b/src/modules/keyboardmanager/dll/trace.h index fab670a364d4..55e5ff686797 100644 --- a/src/modules/keyboardmanager/dll/trace.h +++ b/src/modules/keyboardmanager/dll/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - // Log if the user has KBM enabled or disabled - Can also be used to see how often users have to restart the keyboard hook static void EnableKeyboardManager(const bool enabled) noexcept; }; diff --git a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj index fc1f8a1c859f..8dc2df71bfff 100644 --- a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj +++ b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj @@ -1,5 +1,6 @@ - + @@ -46,14 +47,12 @@ - Create - diff --git a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj.filters b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj.filters index 81c3649d1e57..5e8c2b660576 100644 --- a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj.filters +++ b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj.filters @@ -3,11 +3,9 @@ - - Generated Files diff --git a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp index e140fb728e1f..99c492c394b5 100644 --- a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp +++ b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp @@ -2,7 +2,6 @@ #include #include #include -#include "trace.h" #include "Generated Files/resource.h" #include #include @@ -34,13 +33,11 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lp switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: - Trace::RegisterProvider(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: - Trace::UnregisterProvider(); break; } diff --git a/src/modules/launcher/Microsoft.Launcher/pch.h b/src/modules/launcher/Microsoft.Launcher/pch.h index 46fc911b44a3..c7e646b15e59 100644 --- a/src/modules/launcher/Microsoft.Launcher/pch.h +++ b/src/modules/launcher/Microsoft.Launcher/pch.h @@ -3,6 +3,5 @@ #include #include #include -#include #include #include \ No newline at end of file diff --git a/src/modules/launcher/Microsoft.Launcher/trace.cpp b/src/modules/launcher/Microsoft.Launcher/trace.cpp deleted file mode 100644 index 3e5c2083a957..000000000000 --- a/src/modules/launcher/Microsoft.Launcher/trace.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "pch.h" -#include "trace.h" - -TRACELOGGING_DEFINE_PROVIDER( - g_hProvider, - "Microsoft.PowerToys", - // {38e8889b-9731-53f5-e901-e8a7c1753074} - (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), - TraceLoggingOptionProjectTelemetry()); - -void Trace::RegisterProvider() { - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() { - TraceLoggingUnregister(g_hProvider); -} diff --git a/src/modules/launcher/Microsoft.Launcher/trace.h b/src/modules/launcher/Microsoft.Launcher/trace.h deleted file mode 100644 index 1a260e88249d..000000000000 --- a/src/modules/launcher/Microsoft.Launcher/trace.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -class Trace { -public: - static void RegisterProvider(); - static void UnregisterProvider(); -}; diff --git a/src/modules/launcher/PowerLauncher/App.xaml.cs b/src/modules/launcher/PowerLauncher/App.xaml.cs index 86255f3ad7ae..f110bf714208 100644 --- a/src/modules/launcher/PowerLauncher/App.xaml.cs +++ b/src/modules/launcher/PowerLauncher/App.xaml.cs @@ -46,6 +46,7 @@ public partial class App : IDisposable, ISingleInstanceApp private SettingWindowViewModel _settingsVM; private StringMatcher _stringMatcher; private SettingsReader _settingsReader; + private ETWTrace etwTrace = new ETWTrace(); // To prevent two disposals running at the same time. private static readonly object _disposingLock = new object(); @@ -101,6 +102,8 @@ public static void Main() () => { Log.Warn("RunExitEvent was signaled. Exiting PowerToys", typeof(App)); + application.etwTrace?.Dispose(); + application.etwTrace = null; ExitPowerToys(application); }, Application.Current.Dispatcher, @@ -111,6 +114,8 @@ public static void Main() RunnerHelper.WaitForPowerToysRunner(powerToysPid, () => { Log.Info($"Runner with pid={powerToysPid} exited. Exiting PowerToys Run", typeof(App)); + application.etwTrace?.Dispose(); + application.etwTrace = null; ExitPowerToys(application); }); } diff --git a/src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs b/src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs index 6df56d6f464b..a433b00e4320 100644 --- a/src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs +++ b/src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs @@ -26,6 +26,8 @@ public partial class App : Application, IApp { public static int PowerToysPID { get; set; } + public ETWTrace EtwTrace { get; private set; } = new ETWTrace(); + public IHost Host { get; @@ -100,12 +102,18 @@ protected override void OnLaunched(LaunchActivatedEventArgs args) { RunnerHelper.WaitForPowerToysRunner(powerToysRunnerPid, () => { + EtwTrace?.Dispose(); Environment.Exit(0); }); } } NativeEventWaiter.WaitForEventLoop(Constants.ShowPeekEvent(), OnPeekHotkey); + NativeEventWaiter.WaitForEventLoop(Constants.TerminatePeekEvent(), () => + { + EtwTrace?.Dispose(); + Environment.Exit(0); + }); } private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) diff --git a/src/modules/peek/peek/dllmain.cpp b/src/modules/peek/peek/dllmain.cpp index cef7c1cf9ec7..5fd4da8039cf 100644 --- a/src/modules/peek/peek/dllmain.cpp +++ b/src/modules/peek/peek/dllmain.cpp @@ -13,8 +13,8 @@ extern "C" IMAGE_DOS_HEADER __ImageBase; -BOOL APIENTRY DllMain(HMODULE /*hModule*/, - DWORD ul_reason_for_call, +BOOL APIENTRY DllMain(HMODULE /*hModule*/, + DWORD ul_reason_for_call, LPVOID /*lpReserved*/) { switch (ul_reason_for_call) @@ -65,6 +65,7 @@ class Peek : public PowertoyModuleIface DWORD m_processPid = 0; HANDLE m_hInvokeEvent; + HANDLE m_hTerminateEvent; // Load the settings file. void init_settings() @@ -163,7 +164,7 @@ class Peek : public PowertoyModuleIface { return false; } - if (wcsncmp(className, L"Progman", MAX_PATH) !=0 && wcsncmp(className, L"WorkerW", MAX_PATH) != 0) + if (wcsncmp(className, L"Progman", MAX_PATH) != 0 && wcsncmp(className, L"WorkerW", MAX_PATH) != 0) { return false; } @@ -239,7 +240,7 @@ class Peek : public PowertoyModuleIface } DWORD pid{}; - if (GetWindowThreadProcessId(foregroundWindowHandle, &pid)!=0) + if (GetWindowThreadProcessId(foregroundWindowHandle, &pid) != 0) { // If the foreground window is the Peek window, send activation signal. if (m_processPid != 0 && pid == m_processPid) @@ -321,6 +322,7 @@ class Peek : public PowertoyModuleIface init_settings(); m_hInvokeEvent = CreateDefaultEvent(CommonSharedConstants::SHOW_PEEK_SHARED_EVENT); + m_hTerminateEvent = CreateDefaultEvent(CommonSharedConstants::TERMINATE_PEEK_SHARED_EVENT); }; ~Peek() @@ -402,6 +404,8 @@ class Peek : public PowertoyModuleIface if (m_enabled) { ResetEvent(m_hInvokeEvent); + SetEvent(m_hTerminateEvent); + WaitForSingleObject(m_hProcess, 1500); auto result = TerminateProcess(m_hProcess, 1); if (result == 0) { diff --git a/src/modules/peek/peek/pch.h b/src/modules/peek/peek/pch.h index eddac0fdc1f3..329705f63b47 100644 --- a/src/modules/peek/peek/pch.h +++ b/src/modules/peek/peek/pch.h @@ -2,6 +2,5 @@ #include #include #include -#include #include #include \ No newline at end of file diff --git a/src/modules/peek/peek/trace.cpp b/src/modules/peek/peek/trace.cpp index 1089b41ef8a4..529abb94f339 100644 --- a/src/modules/peek/peek/trace.cpp +++ b/src/modules/peek/peek/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has Peek enabled or disabled void Trace::EnablePeek(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Peek_EnablePeek", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +24,7 @@ void Trace::EnablePeek(const bool enabled) noexcept // Log if the user has invoked Peek void Trace::PeekInvoked() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Peek_InvokePeek", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -49,7 +41,7 @@ void Trace::SettingsTelemetry(PowertoyModuleIface::Hotkey& hotkey) noexcept std::wstring(hotkey.alt ? L"Alt + " : L"") + std::wstring(L"VK ") + std::to_wstring(hotkey.key); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Peek_Settings", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/peek/peek/trace.h b/src/modules/peek/peek/trace.h index 49cd45c32c21..c250fc6b456a 100644 --- a/src/modules/peek/peek/trace.h +++ b/src/modules/peek/peek/trace.h @@ -1,12 +1,11 @@ #pragma once #include -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - // Log if the user has Peek enabled or disabled static void EnablePeek(const bool enabled) noexcept; diff --git a/src/modules/poweraccent/PowerAccent.UI/App.xaml.cs b/src/modules/poweraccent/PowerAccent.UI/App.xaml.cs index af86d06edd84..297b5f2f7b88 100644 --- a/src/modules/poweraccent/PowerAccent.UI/App.xaml.cs +++ b/src/modules/poweraccent/PowerAccent.UI/App.xaml.cs @@ -7,6 +7,7 @@ using System.Windows; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; namespace PowerAccent.UI { @@ -17,6 +18,7 @@ public partial class App : Application, IDisposable { private static Mutex _mutex; private bool _disposed; + private ETWTrace _etwTrace = new ETWTrace(); protected override void OnStartup(StartupEventArgs e) { @@ -47,6 +49,7 @@ protected virtual void Dispose(bool disposing) if (disposing) { _mutex?.Dispose(); + _etwTrace?.Dispose(); } _disposed = true; diff --git a/src/modules/poweraccent/PowerAccentModuleInterface/pch.h b/src/modules/poweraccent/PowerAccentModuleInterface/pch.h index eddac0fdc1f3..329705f63b47 100644 --- a/src/modules/poweraccent/PowerAccentModuleInterface/pch.h +++ b/src/modules/poweraccent/PowerAccentModuleInterface/pch.h @@ -2,6 +2,5 @@ #include #include #include -#include #include #include \ No newline at end of file diff --git a/src/modules/poweraccent/PowerAccentModuleInterface/trace.cpp b/src/modules/poweraccent/PowerAccentModuleInterface/trace.cpp index c5f15cc21625..8a063ea99fc8 100644 --- a/src/modules/poweraccent/PowerAccentModuleInterface/trace.cpp +++ b/src/modules/poweraccent/PowerAccentModuleInterface/trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,19 +10,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::EnablePowerAccent(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerAccent_EnablePowerAccent", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/poweraccent/PowerAccentModuleInterface/trace.h b/src/modules/poweraccent/PowerAccentModuleInterface/trace.h index 42b812f5358e..4d729f76832c 100644 --- a/src/modules/poweraccent/PowerAccentModuleInterface/trace.h +++ b/src/modules/poweraccent/PowerAccentModuleInterface/trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - // Log if the user has PowerAccent enabled or disabled static void EnablePowerAccent(const bool enabled) noexcept; }; diff --git a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj index fb102292795c..af3c71ad8e55 100644 --- a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj +++ b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj @@ -132,6 +132,9 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {51920f1f-c28c-4adf-8660-4238766796c2} diff --git a/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp b/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp index d3fe2af629b1..ce5669fde81d 100644 --- a/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp +++ b/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp @@ -18,6 +18,7 @@ #include "Generated Files/resource.h" +#include #include #include #include @@ -32,6 +33,7 @@ using namespace Microsoft::WRL; HINSTANCE g_hInst = 0; +Shared::Trace::ETWTrace trace(L"PowerRenameContextMenu"); #define BUFSIZE 4096 * 4 @@ -203,6 +205,8 @@ class __declspec(uuid("1861E28B-A1F0-4EF4-A1FE-4C8CA88E2174")) PowerRenameContex { if (CSettingsInstance().GetEnabled()) { + trace.UpdateState(true); + Trace::Invoked(); // Set the application path based on the location of the dll std::wstring path = get_module_folderpath(g_hInst); @@ -258,6 +262,9 @@ class __declspec(uuid("1861E28B-A1F0-4EF4-A1FE-4C8CA88E2174")) PowerRenameContex } Trace::InvokedRet(S_OK); + trace.Flush(); + trace.UpdateState(false); + return S_OK; } diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj index 192a1528bdcd..c41e461acb49 100644 --- a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj +++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj @@ -188,6 +188,9 @@ {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj.filters b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj.filters index 10ef9ed4ee1f..bc242e488683 100644 --- a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj.filters +++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj.filters @@ -65,7 +65,4 @@ - - - \ No newline at end of file diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.cpp b/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.cpp index d1c747fc65c1..46463af14e02 100644 --- a/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.cpp +++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include #include #include @@ -104,6 +106,8 @@ namespace winrt::PowerRenameUI::implementation MainWindow::MainWindow() : m_allSelected{ true }, m_managerEvents{ this } { + Trace::RegisterProvider(); + auto windowNative{ this->try_as<::IWindowNative>() }; winrt::check_bool(windowNative); windowNative->get_WindowHandle(&m_window); @@ -211,6 +215,8 @@ namespace winrt::PowerRenameUI::implementation InitializeComponent(); + m_etwTrace.UpdateState(true); + listView_ExplorerItems().ApplyTemplate(); #ifdef ENABLE_RECYCLING_VIRTUALIZATION_MODE if (auto scrollViewer = FindScrollViewer(listView_ExplorerItems()); scrollViewer) @@ -313,6 +319,11 @@ namespace winrt::PowerRenameUI::implementation { LastRunSettingsInstance().UpdateLastWindowSize(m_updatedWindowSize->first, m_updatedWindowSize->second); } + + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); + + Trace::UnregisterProvider(); } void MainWindow::InvalidateItemListViewState() diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.h b/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.h index d1edf5b226de..8c70194f1b45 100644 --- a/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.h +++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.h @@ -5,6 +5,8 @@ #include "winrt/Windows.UI.Xaml.Interop.h" #include "winrt/Windows.UI.Xaml.Controls.Primitives.h" +#include + #include "MainWindow.g.h" #include "PatternSnippet.h" #include "ExplorerItem.h" @@ -143,6 +145,8 @@ namespace winrt::PowerRenameUI::implementation void SetCheckboxesFromFlags(DWORD flags); void UpdateCounts(); + Shared::Trace::ETWTrace m_etwTrace{}; + HWND m_window{}; bool m_disableCountUpdate = false; diff --git a/src/modules/powerrename/dll/PowerRenameExt.cpp b/src/modules/powerrename/dll/PowerRenameExt.cpp index 9e9f2910e79b..5659f3a51c5a 100644 --- a/src/modules/powerrename/dll/PowerRenameExt.cpp +++ b/src/modules/powerrename/dll/PowerRenameExt.cpp @@ -133,6 +133,8 @@ HRESULT CPowerRenameMenu::InvokeCommand(_In_ LPCMINVOKECOMMANDINFO pici) HRESULT CPowerRenameMenu::RunPowerRename(CMINVOKECOMMANDINFO* pici, IShellItemArray* psiItemArray) { + m_etwTrace.UpdateState(true); + HRESULT hr = E_FAIL; if (CSettingsInstance().GetEnabled() && @@ -246,6 +248,9 @@ HRESULT CPowerRenameMenu::RunPowerRename(CMINVOKECOMMANDINFO* pici, IShellItemAr } Trace::InvokedRet(hr); + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); + return hr; } @@ -295,6 +300,8 @@ HRESULT __stdcall CPowerRenameMenu::Invoke(IShellItemArray* psiItemArray, IBindC swprintf_s(buffer, L"%d", GetCurrentProcessId()); MessageBoxW(nullptr, buffer, L"PID", MB_OK); #endif + m_etwTrace.UpdateState(true); + Trace::Invoked(); InvokeStruct* pInvokeData = new (std::nothrow) InvokeStruct; HRESULT hr = E_OUTOFMEMORY; @@ -311,6 +318,9 @@ HRESULT __stdcall CPowerRenameMenu::Invoke(IShellItemArray* psiItemArray, IBindC hr = RunPowerRename(nullptr, psiItemArray); } Trace::InvokedRet(hr); + + m_etwTrace.Flush(); + m_etwTrace.UpdateState(false); return S_OK; } diff --git a/src/modules/powerrename/dll/PowerRenameExt.h b/src/modules/powerrename/dll/PowerRenameExt.h index e2ffcda85cd3..3d0ca78b9f3e 100644 --- a/src/modules/powerrename/dll/PowerRenameExt.h +++ b/src/modules/powerrename/dll/PowerRenameExt.h @@ -1,6 +1,8 @@ #pragma once #include "pch.h" +#include + class __declspec(uuid("0440049F-D1DC-4E46-B27B-98393D79486B")) CPowerRenameMenu : public IShellExtInit, public IContextMenu, @@ -70,4 +72,6 @@ class __declspec(uuid("0440049F-D1DC-4E46-B27B-98393D79486B")) CPowerRenameMenu HBITMAP m_hbmpIcon = nullptr; CComPtr m_spdo; std::wstring context_menu_caption; + + Shared::Trace::ETWTrace m_etwTrace{ L"PowerRenameExt" }; }; diff --git a/src/modules/powerrename/dll/PowerRenameExt.vcxproj b/src/modules/powerrename/dll/PowerRenameExt.vcxproj index a994c2514812..ead9518f3567 100644 --- a/src/modules/powerrename/dll/PowerRenameExt.vcxproj +++ b/src/modules/powerrename/dll/PowerRenameExt.vcxproj @@ -60,6 +60,9 @@ {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/modules/powerrename/lib/pch.h b/src/modules/powerrename/lib/pch.h index 7a12102fbe35..c5a4711a037c 100644 --- a/src/modules/powerrename/lib/pch.h +++ b/src/modules/powerrename/lib/pch.h @@ -29,6 +29,4 @@ #include #include -#include - #include diff --git a/src/modules/powerrename/lib/trace.cpp b/src/modules/powerrename/lib/trace.cpp index f04a085df0f5..9f1446c65304 100644 --- a/src/modules/powerrename/lib/trace.cpp +++ b/src/modules/powerrename/lib/trace.cpp @@ -2,26 +2,18 @@ #include "trace.h" #include "Settings.h" -TRACELOGGING_DEFINE_PROVIDER( - g_hProvider, - "Microsoft.PowerToys", - // {38e8889b-9731-53f5-e901-e8a7c1753074} - (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), - TraceLoggingOptionProjectTelemetry()); - -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} +#include -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} +TRACELOGGING_DEFINE_PROVIDER( + g_hProvider, + "Microsoft.PowerToys", + // {38e8889b-9731-53f5-e901-e8a7c1753074} + (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), + TraceLoggingOptionProjectTelemetry()); void Trace::Invoked() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerRename_Invoked", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -30,7 +22,7 @@ void Trace::Invoked() noexcept void Trace::InvokedRet(_In_ HRESULT hr) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerRename_InvokedRet", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -40,7 +32,7 @@ void Trace::InvokedRet(_In_ HRESULT hr) noexcept void Trace::EnablePowerRename(_In_ bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerRename_EnablePowerRename", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -50,7 +42,7 @@ void Trace::EnablePowerRename(_In_ bool enabled) noexcept void Trace::UIShownRet(_In_ HRESULT hr) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerRename_UIShownRet", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -60,7 +52,7 @@ void Trace::UIShownRet(_In_ HRESULT hr) noexcept void Trace::RenameOperation(_In_ UINT totalItemCount, _In_ UINT selectedItemCount, _In_ UINT renameItemCount, _In_ DWORD flags, _In_ PCWSTR extensionList) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerRename_RenameOperation", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -74,7 +66,7 @@ void Trace::RenameOperation(_In_ UINT totalItemCount, _In_ UINT selectedItemCoun void Trace::SettingsChanged() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerRename_SettingsChanged", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/powerrename/lib/trace.h b/src/modules/powerrename/lib/trace.h index 9019c9c8ae9c..0a3a0af24645 100644 --- a/src/modules/powerrename/lib/trace.h +++ b/src/modules/powerrename/lib/trace.h @@ -1,9 +1,9 @@ #pragma once -class Trace { +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; static void Invoked() noexcept; static void InvokedRet(_In_ HRESULT hr) noexcept; static void EnablePowerRename(_In_ bool enabled) noexcept; diff --git a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs index 67c6d9f42e72..2fd96930a21d 100644 --- a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs +++ b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs @@ -4,8 +4,6 @@ using Common; using Microsoft.PowerToys.FilePreviewCommon; -using Microsoft.PowerToys.PreviewHandler.Gcode.Telemetry.Events; -using Microsoft.PowerToys.Telemetry; namespace Microsoft.PowerToys.PreviewHandler.Gcode { @@ -86,13 +84,6 @@ public override void DoPreview(T dataSource) 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) { @@ -162,14 +153,6 @@ private void AddTextBoxControl(string message) /// 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/Telemetry/Events/GcodeFileHandlerLoaded.cs b/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFileHandlerLoaded.cs deleted file mode 100644 index c1d1fba40a2e..000000000000 --- a/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFileHandlerLoaded.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index 9e9a232e04b5..000000000000 --- a/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFilePreviewError.cs +++ /dev/null @@ -1,26 +0,0 @@ -// 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 deleted file mode 100644 index 693e314e401d..000000000000 --- a/src/modules/previewpane/GcodePreviewHandler/Telemetry/Events/GcodeFilePreviewed.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 89f480c792c1..bb4b1f869d8c 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs +++ b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs @@ -9,8 +9,6 @@ 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; @@ -217,25 +215,9 @@ public override void DoPreview(T dataSource) { } }); - - try - { - PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewed()); - } - catch - { // Should not crash if sending telemetry is failing. Ignore the exception. - } } - catch (Exception ex) + catch (Exception) { - 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/Telemetry/Events/MarkdownFileHandlerLoaded.cs b/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFileHandlerLoaded.cs deleted file mode 100644 index dec9852dec63..000000000000 --- a/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFileHandlerLoaded.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index 95268b1619c8..000000000000 --- a/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFilePreviewError.cs +++ /dev/null @@ -1,23 +0,0 @@ -// 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 deleted file mode 100644 index e38d2d38ca4f..000000000000 --- a/src/modules/previewpane/MarkdownPreviewHandler/Telemetry/Events/MarkdownFilePreviewed.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 406856798569..f9b5069e8835 100644 --- a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs +++ b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs @@ -1,17 +1,8 @@ // 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; @@ -158,25 +149,9 @@ public override void DoPreview(T dataSource) memStream.Dispose(); } } - - try - { - PowerToysTelemetry.Log.WriteEvent(new PdfFilePreviewed()); - } - catch - { // Should not crash if sending telemetry is failing. Ignore the exception. - } } - catch (Exception ex) + catch (Exception) { - 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/Telemetry/Events/PdfFileHandlerLoaded.cs b/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFileHandlerLoaded.cs deleted file mode 100644 index fc2ac2881b24..000000000000 --- a/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFileHandlerLoaded.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index 73dec9126513..000000000000 --- a/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFilePreviewError.cs +++ /dev/null @@ -1,23 +0,0 @@ -// 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 deleted file mode 100644 index 0a223a24b2f5..000000000000 --- a/src/modules/previewpane/PdfPreviewHandler/Telemetry/Events/PdfFilePreviewed.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/QoiPreviewHandlerControl.cs b/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandlerControl.cs index 047a3e614fa9..29bf8d2d7d3a 100644 --- a/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandlerControl.cs +++ b/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandlerControl.cs @@ -4,8 +4,6 @@ using Common; using Microsoft.PowerToys.FilePreviewCommon; -using Microsoft.PowerToys.PreviewHandler.Qoi.Telemetry.Events; -using Microsoft.PowerToys.Telemetry; namespace Microsoft.PowerToys.PreviewHandler.Qoi { @@ -73,13 +71,6 @@ public override void DoPreview(T dataSource) 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) { @@ -149,14 +140,6 @@ private void AddTextBoxControl(string message) /// 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 deleted file mode 100644 index cdc4516fd954..000000000000 --- a/src/modules/previewpane/QoiPreviewHandler/Telemetry/Events/QoiFilePreviewError.cs +++ /dev/null @@ -1,26 +0,0 @@ -// 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 deleted file mode 100644 index 273ec8caf074..000000000000 --- a/src/modules/previewpane/QoiPreviewHandler/Telemetry/Events/QoiFilePreviewed.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/SvgPreviewControl.cs b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs index 095c985896fd..931946dc0b2b 100644 --- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs +++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs @@ -2,14 +2,11 @@ // 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; @@ -142,15 +139,8 @@ public override void DoPreview(T dataSource) svgData = SvgPreviewHandlerHelper.SwapNamespaces(svgData); svgData = SvgPreviewHandlerHelper.AddStyleSVG(svgData); } - catch (Exception ex) + catch (Exception) { - try - { - PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewError { Message = ex.Message }); - } - catch - { // Should not crash if sending telemetry is failing. Ignore the exception. - } } try @@ -167,13 +157,6 @@ public override void DoPreview(T dataSource) 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) { @@ -301,14 +284,6 @@ private void AddTextBoxControl(string message) /// 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 deleted file mode 100644 index aaea992ba97a..000000000000 --- a/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFileHandlerLoaded.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index daed4355020e..000000000000 --- a/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFilePreviewError.cs +++ /dev/null @@ -1,26 +0,0 @@ -// 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 deleted file mode 100644 index 5348bcd4660c..000000000000 --- a/src/modules/previewpane/SvgPreviewHandler/Telemetry/Events/SvgFilePreviewed.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/modules/previewpane/powerpreview/pch.h b/src/modules/previewpane/powerpreview/pch.h index cace4c2c9456..2f130e79fa94 100644 --- a/src/modules/previewpane/powerpreview/pch.h +++ b/src/modules/previewpane/powerpreview/pch.h @@ -4,5 +4,4 @@ #include #include #include -#include diff --git a/src/modules/previewpane/powerpreview/powerpreview.cpp b/src/modules/previewpane/powerpreview/powerpreview.cpp index 1eef1f0398a1..84d2a590dc3a 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.cpp +++ b/src/modules/previewpane/powerpreview/powerpreview.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/src/modules/previewpane/powerpreview/trace.cpp b/src/modules/previewpane/powerpreview/trace.cpp index 903ecff48738..6bd46ed45b1e 100644 --- a/src/modules/previewpane/powerpreview/trace.cpp +++ b/src/modules/previewpane/powerpreview/trace.cpp @@ -2,6 +2,8 @@ #include "trace.h" #include +#include + /* * * This file captures the telemetry for the File Explorer Custom Renders project. @@ -19,19 +21,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::EnabledPowerPreview(bool enabled) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerPreview_Enabled", TraceLoggingBoolean(enabled, "Enabled"), @@ -42,7 +34,7 @@ void Trace::EnabledPowerPreview(bool enabled) void Trace::PowerPreviewSettingsUpdated(LPCWSTR SettingsName, bool oldState, bool newState, bool globalState) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerPreview_TweakUISettings_SuccessfullyUpdatedSettings", TraceLoggingWideString(SettingsName, "Previewer_Settings_Name"), @@ -56,7 +48,7 @@ void Trace::PowerPreviewSettingsUpdated(LPCWSTR SettingsName, bool oldState, boo void Trace::PowerPreviewSettingsUpdateFailed(LPCWSTR SettingsName, bool oldState, bool newState, bool globalState) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerPreview_TweakUISettings_FailedUpdatingSettings", TraceLoggingWideString(SettingsName, "Previewer_Settings_Name"), @@ -70,7 +62,7 @@ void Trace::PowerPreviewSettingsUpdateFailed(LPCWSTR SettingsName, bool oldState void Trace::SetConfigInvalidJSON(const char* exceptionMessage) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerPreview_TweakUISettings_SetConfig__InvalidJSONGiven", TraceLoggingString(exceptionMessage, "ExceptionMessage"), @@ -81,7 +73,7 @@ void Trace::SetConfigInvalidJSON(const char* exceptionMessage) void Trace::Destroyed() { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerPreview_TweakUISettings_Destroyed", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -89,9 +81,9 @@ void Trace::Destroyed() TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } -void Trace::InitSetErrorLoadingFile(const char* exceptionMessage) +void Trace::InitSetErrorLoadingFile(const char* exceptionMessage) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "PowerPreview_TweakUISettings_InitSet__ErrorLoadingFile", TraceLoggingString(exceptionMessage, "ExceptionMessage"), @@ -99,4 +91,3 @@ void Trace::InitSetErrorLoadingFile(const char* exceptionMessage) TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } - diff --git a/src/modules/previewpane/powerpreview/trace.h b/src/modules/previewpane/powerpreview/trace.h index 6899bcdec17d..8cd33fee52d2 100644 --- a/src/modules/previewpane/powerpreview/trace.h +++ b/src/modules/previewpane/powerpreview/trace.h @@ -1,10 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); static void SetConfigInvalidJSON(const char* exceptionMessage); static void InitSetErrorLoadingFile(const char* exceptionMessage); static void EnabledPowerPreview(bool enabled); diff --git a/src/modules/registrypreview/RegistryPreview/MainWindow.Events.cs b/src/modules/registrypreview/RegistryPreview/MainWindow.Events.cs index 34de7f175220..abcbbfd09b07 100644 --- a/src/modules/registrypreview/RegistryPreview/MainWindow.Events.cs +++ b/src/modules/registrypreview/RegistryPreview/MainWindow.Events.cs @@ -28,6 +28,7 @@ public void Window_Closed(object sender, WindowEventArgs args) { // Save window placement SaveWindowPlacementFile(settingsFolder, windowPlacementFile); + (Application.Current as App).EtwTrace?.Dispose(); } } } diff --git a/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml.cs b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml.cs index a6a3898f0f3b..6930d8bc9879 100644 --- a/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml.cs +++ b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml.cs @@ -6,6 +6,7 @@ using System.Web; using ManagedCommon; +using Microsoft.PowerToys.Telemetry; using Microsoft.UI.Xaml; using Microsoft.Windows.AppLifecycle; using Windows.ApplicationModel.Activation; @@ -111,5 +112,7 @@ protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs ar public static string AppFilename; #pragma warning restore CA2211 // Non-constant fields should not be visible #pragma warning restore SA1401 // Fields should be private + + public ETWTrace EtwTrace { get; private set; } = new ETWTrace(); } } diff --git a/src/modules/registrypreview/RegistryPreviewExt/Trace.cpp b/src/modules/registrypreview/RegistryPreviewExt/Trace.cpp index 7dda85e43eaa..870669606b9e 100644 --- a/src/modules/registrypreview/RegistryPreviewExt/Trace.cpp +++ b/src/modules/registrypreview/RegistryPreviewExt/Trace.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -8,20 +10,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has enabled or disabled the app void Trace::EnableRegistryPreview(_In_ bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "RegistryPreview_EnableRegistryPreview", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -32,7 +24,7 @@ void Trace::EnableRegistryPreview(_In_ bool enabled) noexcept // Log that the user tried to activate the app void Trace::ActivateEditor() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "RegistryPreview_Activate", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), diff --git a/src/modules/registrypreview/RegistryPreviewExt/Trace.h b/src/modules/registrypreview/RegistryPreviewExt/Trace.h index d2cda345d8d9..7e08386e9cd4 100644 --- a/src/modules/registrypreview/RegistryPreviewExt/Trace.h +++ b/src/modules/registrypreview/RegistryPreviewExt/Trace.h @@ -1,11 +1,10 @@ #pragma once -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); - // Log if the user has enabled or disabled the app static void EnableRegistryPreview(const bool enabled) noexcept; diff --git a/src/modules/registrypreview/RegistryPreviewExt/pch.h b/src/modules/registrypreview/RegistryPreviewExt/pch.h index be72eb015e0e..6b4ad38c1095 100644 --- a/src/modules/registrypreview/RegistryPreviewExt/pch.h +++ b/src/modules/registrypreview/RegistryPreviewExt/pch.h @@ -9,7 +9,6 @@ #include -#include #include //#include #include diff --git a/src/modules/videoconference/VideoConferenceModule/pch.h b/src/modules/videoconference/VideoConferenceModule/pch.h index 3f4849aa4497..7c614d9a5c65 100644 --- a/src/modules/videoconference/VideoConferenceModule/pch.h +++ b/src/modules/videoconference/VideoConferenceModule/pch.h @@ -21,5 +21,3 @@ #include #include - -#include diff --git a/src/modules/videoconference/VideoConferenceModule/trace.cpp b/src/modules/videoconference/VideoConferenceModule/trace.cpp index 889cca2a15c4..043c6b30e74b 100644 --- a/src/modules/videoconference/VideoConferenceModule/trace.cpp +++ b/src/modules/videoconference/VideoConferenceModule/trace.cpp @@ -2,6 +2,8 @@ #include "trace.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -9,20 +11,10 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - // Log if the user has VCM enabled or disabled void Trace::EnableVideoConference(const bool enabled) noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "VideoConference_EnableVideoConference", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), @@ -34,7 +26,7 @@ void Trace::SettingsChanged(const struct VideoConferenceSettings& settings) noex { bool CustomOverlayImage = (settings.imageOverlayPath.length() > 0); - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "VideoConference_SettingsChanged", TraceLoggingWideString(settings.toolbarPositionString.c_str(), "ToolbarPosition"), @@ -47,7 +39,7 @@ void Trace::SettingsChanged(const struct VideoConferenceSettings& settings) noex void Trace::MicrophoneMuted() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "VideoConference_MicrophoneMuted", TraceLoggingBoolean(true, "MicrophoneMuted"), @@ -58,7 +50,7 @@ void Trace::MicrophoneMuted() noexcept void Trace::CameraMuted() noexcept { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "VideoConference_CameraMuted", TraceLoggingBoolean(true, "CameraMuted"), diff --git a/src/modules/videoconference/VideoConferenceModule/trace.h b/src/modules/videoconference/VideoConferenceModule/trace.h index 5d42709be288..0a9f193e6951 100644 --- a/src/modules/videoconference/VideoConferenceModule/trace.h +++ b/src/modules/videoconference/VideoConferenceModule/trace.h @@ -1,11 +1,11 @@ #pragma once #include "VideoConferenceModule.h" -class Trace +#include + +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; static void EnableVideoConference(const bool enabled) noexcept; static void SettingsChanged(const struct VideoConferenceSettings &settings) noexcept; static void MicrophoneMuted() noexcept; diff --git a/src/runner/general_settings.cpp b/src/runner/general_settings.cpp index 9925308507a8..9e3b170feb19 100644 --- a/src/runner/general_settings.cpp +++ b/src/runner/general_settings.cpp @@ -65,7 +65,7 @@ json::JsonObject load_general_settings() show_new_updates_toast_notification = loaded.GetNamedBoolean(L"show_new_updates_toast_notification", true); download_updates_automatically = loaded.GetNamedBoolean(L"download_updates_automatically", true) && check_user_is_admin(); show_whats_new_after_updates = loaded.GetNamedBoolean(L"show_whats_new_after_updates", true); - enable_experimentation = loaded.GetNamedBoolean(L"enable_experimentation",true); + enable_experimentation = loaded.GetNamedBoolean(L"enable_experimentation", true); enable_warnings_elevated_apps = loaded.GetNamedBoolean(L"enable_warnings_elevated_apps", true); return loaded; @@ -241,8 +241,7 @@ void start_enabled_powertoys() { std::wstring disable_module_name{ static_cast(disabled_element.Key()) }; - if (powertoys_gpo_configuration.find(disable_module_name)!=powertoys_gpo_configuration.end() - && (powertoys_gpo_configuration[disable_module_name]==powertoys_gpo::gpo_rule_configured_enabled || powertoys_gpo_configuration[disable_module_name]==powertoys_gpo::gpo_rule_configured_disabled)) + if (powertoys_gpo_configuration.find(disable_module_name) != powertoys_gpo_configuration.end() && (powertoys_gpo_configuration[disable_module_name] == powertoys_gpo::gpo_rule_configured_enabled || powertoys_gpo_configuration[disable_module_name] == powertoys_gpo::gpo_rule_configured_disabled)) { // If gpo forces the enabled setting, no need to check the setting for this PowerToy. It will be applied later on this function. continue; diff --git a/src/runner/main.cpp b/src/runner/main.cpp index dd35697e09f1..bd7cabdec792 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -303,6 +304,9 @@ toast_notification_handler_result toast_notification_handler(const std::wstring_ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR lpCmdLine, int /*nCmdShow*/) { + Shared::Trace::ETWTrace trace{}; + trace.UpdateState(true); + Gdiplus::GdiplusStartupInput gpStartupInput; ULONG_PTR gpToken; GdiplusStartup(&gpToken, &gpStartupInput, NULL); @@ -437,6 +441,13 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR l openScoobe = false; } + bool dataDiagnosticsDisabledByGpo = powertoys_gpo::getAllowDataDiagnosticsValue() == powertoys_gpo::gpo_rule_configured_disabled; + if (dataDiagnosticsDisabledByGpo) + { + Logger::info(L"Data diagnostics: Data diagnostics is disabled by GPO."); + PTSettingsHelper::save_data_diagnostics(false); + } + if (elevated && with_dont_elevate_arg && !run_elevated_setting) { Logger::info("Scheduling restart as non elevated"); @@ -473,6 +484,9 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR l result = -1; } + trace.Flush(); + trace.UpdateState(false); + // We need to release the mutexes to be able to restart the application if (msi_mutex) { @@ -481,6 +495,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR l if (is_restart_scheduled()) { + modules().clear(); if (!restart_if_scheduled()) { // If it's not possible to restart non-elevated due to some condition in the user's configuration, user should start PowerToys manually. diff --git a/src/runner/pch.h b/src/runner/pch.h index a01e93cc176f..537bef12d647 100644 --- a/src/runner/pch.h +++ b/src/runner/pch.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/src/runner/runner.vcxproj b/src/runner/runner.vcxproj index 90129f37f27c..a55396a71a67 100644 --- a/src/runner/runner.vcxproj +++ b/src/runner/runner.vcxproj @@ -107,6 +107,9 @@ {1d5be09d-78c0-4fd7-af00-ae7c1af7c525} + + {8f021b46-362b-485c-bfba-ccf83e820cbd} + {98537082-0fdb-40de-abd8-0dc5a4269bab} diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp index 6430824bb144..7e56622443e0 100644 --- a/src/runner/settings_window.cpp +++ b/src/runner/settings_window.cpp @@ -6,6 +6,7 @@ #include "powertoy_module.h" #include +#include #include "tray_icon.h" #include "general_settings.h" #include "restart_elevated.h" @@ -34,6 +35,7 @@ TwoWayPipeMessageIPC* current_settings_ipc = NULL; std::mutex ipc_mutex; std::atomic_bool g_isLaunchInProgress = false; std::atomic_bool isUpdateCheckThreadRunning = false; +HANDLE g_terminateSettingsEvent = CreateEventW(nullptr, false, false, CommonSharedConstants::TERMINATE_SETTINGS_SHARED_EVENT); json::JsonObject get_power_toys_settings() { @@ -622,9 +624,11 @@ void close_settings_window() { if (g_settings_process_id != 0) { + SetEvent(g_terminateSettingsEvent); wil::unique_handle proc{ OpenProcess(PROCESS_TERMINATE, false, g_settings_process_id) }; if (proc) { + WaitForSingleObject(proc.get(), 1500); TerminateProcess(proc.get(), 0); } } diff --git a/src/runner/trace.cpp b/src/runner/trace.cpp index 8c0dd74b5048..1c15092679c8 100644 --- a/src/runner/trace.cpp +++ b/src/runner/trace.cpp @@ -3,6 +3,8 @@ #include "general_settings.h" +#include + TRACELOGGING_DEFINE_PROVIDER( g_hProvider, "Microsoft.PowerToys", @@ -10,19 +12,9 @@ TRACELOGGING_DEFINE_PROVIDER( (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), TraceLoggingOptionProjectTelemetry()); -void Trace::RegisterProvider() -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() -{ - TraceLoggingUnregister(g_hProvider); -} - void Trace::EventLaunch(const std::wstring& versionNumber, bool isProcessElevated) { - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "Runner_Launch", TraceLoggingWideString(versionNumber.c_str(), "Version"), @@ -48,7 +40,7 @@ void Trace::SettingsChanged(const GeneralSettings& settings) } } - TraceLoggingWrite( + TraceLoggingWriteWrapper( g_hProvider, "GeneralSettingsChanged", TraceLoggingBoolean(settings.isStartupEnabled, "RunAtStartup"), diff --git a/src/runner/trace.h b/src/runner/trace.h index fe337723d736..3170fa665abe 100644 --- a/src/runner/trace.h +++ b/src/runner/trace.h @@ -1,12 +1,12 @@ #pragma once +#include + struct GeneralSettings; -class Trace +class Trace : public telemetry::TraceBase { public: - static void RegisterProvider(); - static void UnregisterProvider(); static void EventLaunch(const std::wstring& versionNumber, bool isProcessElevated); static void SettingsChanged(const GeneralSettings& settings); }; diff --git a/src/settings-ui/Settings.UI/Helpers/ETLConverter.cs b/src/settings-ui/Settings.UI/Helpers/ETLConverter.cs new file mode 100644 index 000000000000..a4b8b57ae823 --- /dev/null +++ b/src/settings-ui/Settings.UI/Helpers/ETLConverter.cs @@ -0,0 +1,102 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using ManagedCommon; + +namespace Microsoft.PowerToys.Settings.UI.Helpers +{ + public class ETLConverter + { + private const int TracerptConversionTimeout = 60000; // 60 seconds in milliseconds + private const string ETLConversionOutputFormat = "xml"; // Assuming XML output format + + private readonly string etwDirPath; + + private readonly string tracerptPath; + + public ETLConverter(string etwDirPath, string tracerptPath) + { + this.etwDirPath = etwDirPath; + this.tracerptPath = tracerptPath; + } + + private bool ETLConversionsFailed { get; set; } + + public async Task ConvertDiagnosticsETLsAsync(CancellationToken cancellationToken = default) + { + var etlConversionTasks = new List(); + var directoryInfo = new DirectoryInfo(etwDirPath); + + foreach (var fileInfo in directoryInfo.GetFiles("*.etl", SearchOption.AllDirectories)) + { + var task = Task.Run(() => ConvertETLAsync(fileInfo.FullName, cancellationToken), cancellationToken); + etlConversionTasks.Add(task); + } + + try + { + await Task.WhenAll(etlConversionTasks); + } + catch (Exception) + { + ETLConversionsFailed = true; + } + + if (ETLConversionsFailed) + { + throw new InvalidOperationException("One or more ETL conversions failed."); + } + } + + private void ConvertETLAsync(string etlFilePathToConvert, CancellationToken cancellationToken) + { + var outputFilePath = Path.ChangeExtension(etlFilePathToConvert, $".{ETLConversionOutputFormat}"); + + if (File.Exists(outputFilePath)) + { + File.Delete(outputFilePath); + } + + var tracerPtArguments = $"\"{etlFilePathToConvert}\" -o \"{outputFilePath}\" -lr -y -of {ETLConversionOutputFormat}"; + + var startInfo = new ProcessStartInfo + { + FileName = tracerptPath + "\\tracerpt.exe", + Arguments = tracerPtArguments, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + }; + + using (var process = Process.Start(startInfo)) + { + if (process == null) + { + Logger.LogError("Failed to start tracerpt process."); + } + + var processExited = process.WaitForExit(TracerptConversionTimeout); + + if (!processExited) + { + process.Kill(); + Logger.LogError("ETL conversion process timed out."); + } + + var exitCode = process.ExitCode; + if (exitCode != 0) + { + Logger.LogError($"ETL conversion failed with exit code {exitCode}."); + } + } + } + } +} diff --git a/src/settings-ui/Settings.UI/Helpers/NativeEventWaiter.cs b/src/settings-ui/Settings.UI/Helpers/NativeEventWaiter.cs new file mode 100644 index 000000000000..0aee5d3fd6c7 --- /dev/null +++ b/src/settings-ui/Settings.UI/Helpers/NativeEventWaiter.cs @@ -0,0 +1,30 @@ +// 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.Threading; + +using Microsoft.UI.Dispatching; + +namespace Microsoft.PowerToys.Settings.UI.Helpers +{ + public static class NativeEventWaiter + { + public static void WaitForEventLoop(string eventName, Action callback) + { + var dispatcherQueue = DispatcherQueue.GetForCurrentThread(); + new Thread(() => + { + var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName); + while (true) + { + if (eventHandle.WaitOne()) + { + dispatcherQueue.TryEnqueue(() => callback()); + } + } + }).Start(); + } + } +} diff --git a/src/settings-ui/Settings.UI/Helpers/StartProcessHelper.cs b/src/settings-ui/Settings.UI/Helpers/StartProcessHelper.cs index 816b6bcc6393..70157075acf3 100644 --- a/src/settings-ui/Settings.UI/Helpers/StartProcessHelper.cs +++ b/src/settings-ui/Settings.UI/Helpers/StartProcessHelper.cs @@ -11,6 +11,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers public static class StartProcessHelper { public const string ColorsSettings = "ms-settings:colors"; + public const string DiagnosticsAndFeedback = "ms-settings:privacy-feedback"; public static string AnimationsSettings => OSVersionHelper.IsWindows11() ? "ms-settings:easeofaccess-visualeffects" diff --git a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs index 4c44dd250b50..85f64f62cc79 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs @@ -70,6 +70,8 @@ private enum Arguments public static Action IPCMessageReceivedCallback { get; set; } + public ETWTrace EtwTrace { get; private set; } = new ETWTrace(); + /// /// Initializes a new instance of the class. /// Initializes the singleton application object. This is the first line of authored code @@ -88,6 +90,13 @@ public App() InitializeComponent(); UnhandledException += App_UnhandledException; + + NativeEventWaiter.WaitForEventLoop( + Constants.PowerToysRunnerTerminateSettingsEvent(), () => + { + EtwTrace?.Dispose(); + Environment.Exit(0); + }); } private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) diff --git a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml index b6456d5eb079..b04c800bca21 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml @@ -5,6 +5,8 @@ xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls" + xmlns:ui="using:CommunityToolkit.WinUI" mc:Ignorable="d"> @@ -17,6 +19,35 @@ + + + + + + + + + + + + + + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml.cs index d43bda83bfd2..ba4595ea0687 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml.cs @@ -2,9 +2,11 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using global::PowerToys.GPOWrapper; using Microsoft.PowerToys.Settings.UI.OOBE.Enums; using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel; using Microsoft.PowerToys.Settings.UI.Views; +using Microsoft.PowerToys.Telemetry; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; @@ -14,9 +16,46 @@ public sealed partial class OobeOverview : Page { public OobePowerToysModule ViewModel { get; set; } + private bool _enableDataDiagnostics; + + public bool EnableDataDiagnostics + { + get + { + return _enableDataDiagnostics; + } + + set + { + if (_enableDataDiagnostics != value) + { + _enableDataDiagnostics = value; + + DataDiagnosticsSettings.SetEnabledValue(_enableDataDiagnostics); + + this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () => + { + ShellPage.ShellHandler?.SignalGeneralDataUpdate(); + }); + } + } + } + + public bool ShowDataDiagnosticsSetting => GetIsDataDiagnosticsInfoBarEnabled(); + + private bool GetIsDataDiagnosticsInfoBarEnabled() + { + var isDataDiagnosticsGpoDisallowed = GPOWrapper.GetAllowDataDiagnosticsValue() == GpoRuleConfigured.Disabled; + + return !isDataDiagnosticsGpoDisallowed; + } + public OobeOverview() { this.InitializeComponent(); + + _enableDataDiagnostics = DataDiagnosticsSettings.GetEnabledValue(); + ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Overview]); DataContext = ViewModel; } @@ -31,6 +70,16 @@ private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedE ViewModel.LogOpeningSettingsEvent(); } + private void GeneralSettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) + { + if (OobeShellPage.OpenMainWindowCallback != null) + { + OobeShellPage.OpenMainWindowCallback(typeof(GeneralPage)); + } + + ViewModel.LogOpeningSettingsEvent(); + } + protected override void OnNavigatedTo(NavigationEventArgs e) { ViewModel.LogOpeningModuleEvent(); diff --git a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeWhatsNew.xaml b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeWhatsNew.xaml index 06c3b29067f5..febd14186a96 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeWhatsNew.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeWhatsNew.xaml @@ -6,18 +6,66 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls" + xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls" + xmlns:ui="using:CommunityToolkit.WinUI" Loaded="Page_Loaded" mc:Ignorable="d"> + + + + + + + + + + + + + + + + + + + + + +