diff --git a/PowerToys.sln b/PowerToys.sln
index a441e261d1c..d43dbf7f119 100644
--- a/PowerToys.sln
+++ b/PowerToys.sln
@@ -618,6 +618,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkspacesEditor", "src\mod
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WorkspacesLauncher", "src\modules\Workspaces\WorkspacesLauncher\WorkspacesLauncher.vcxproj", "{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EtwTrace", "src\common\EtwTrace\EtwTrace.csproj", "{036A27C6-0DF3-4398-B051-D9F992E68BCF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
@@ -2720,6 +2722,18 @@ Global
{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96}.Release|x64.Build.0 = Release|x64
{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96}.Release|x86.ActiveCfg = Release|x64
{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96}.Release|x86.Build.0 = Release|x64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Debug|ARM64.Build.0 = Debug|ARM64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Debug|x64.ActiveCfg = Debug|x64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Debug|x64.Build.0 = Debug|x64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Debug|x86.ActiveCfg = Debug|x64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Debug|x86.Build.0 = Debug|x64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Release|ARM64.ActiveCfg = Release|ARM64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Release|ARM64.Build.0 = Release|ARM64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Release|x64.ActiveCfg = Release|x64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Release|x64.Build.0 = Release|x64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Release|x86.ActiveCfg = Release|x64
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF}.Release|x86.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2946,6 +2960,7 @@ Global
{3D63307B-9D27-44FD-B033-B26F39245B85} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{367D7543-7DBA-4381-99F1-BF6142A996C4} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
+ {036A27C6-0DF3-4398-B051-D9F992E68BCF} = {1AFB6476-670D-4E80-A464-657E01DFF482}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
diff --git a/src/common/EtwTrace/EtwTrace.csproj b/src/common/EtwTrace/EtwTrace.csproj
new file mode 100644
index 00000000000..813d09efa1b
--- /dev/null
+++ b/src/common/EtwTrace/EtwTrace.csproj
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ WinExe
+ false
+ false
+ true
+
+ true
+ ..\..\..\$(Platform)\$(Configuration)
+ PowerToys.EtwTrace
+ PowerToys EtwTrace
+ EtwTrace
+
+
+
+
+
+
+
+
+
diff --git a/src/common/EtwTrace/Program.cs b/src/common/EtwTrace/Program.cs
new file mode 100644
index 00000000000..8f97d240253
--- /dev/null
+++ b/src/common/EtwTrace/Program.cs
@@ -0,0 +1,41 @@
+// 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 System.Windows.Forms;
+using ManagedCommon;
+using Microsoft.PowerToys.Telemetry;
+
+namespace EtwTrace
+{
+ internal static class Program
+ {
+ private static ManualResetEvent quitEvent = new ManualResetEvent(false);
+
+ public static void Main(string[] args)
+ {
+ if (args.Length == 0)
+ {
+ return;
+ }
+
+ int runnerPid = -1;
+ if (!int.TryParse(args[0], out runnerPid))
+ {
+ return;
+ }
+
+ ETWTrace eTWTrace = new ETWTrace();
+ eTWTrace.Start();
+
+ RunnerHelper.WaitForPowerToysRunner(runnerPid, () =>
+ {
+ eTWTrace.Dispose();
+ quitEvent.Set();
+ });
+
+ quitEvent.WaitOne();
+ }
+ }
+}
diff --git a/src/modules/CropAndLock/CropAndLock/main.cpp b/src/modules/CropAndLock/CropAndLock/main.cpp
index 3fd18cdaa8c..5e29bbf0f90 100644
--- a/src/modules/CropAndLock/CropAndLock/main.cpp
+++ b/src/modules/CropAndLock/CropAndLock/main.cpp
@@ -15,8 +15,6 @@
#include
#include
-#include
-
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
namespace winrt
@@ -199,9 +197,6 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I
}
m_event_triggers_thread = std::thread([&]() {
- Shared::Trace::ETWTrace trace;
- trace.UpdateState(true);
-
MSG msg;
HANDLE event_handles[3] = {m_reparent_event_handle, m_thumbnail_event_handle, m_exit_event_handle};
while (m_running)
@@ -255,8 +250,6 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I
break;
}
}
- trace.Flush();
- trace.UpdateState(false);
});
// Message pump
diff --git a/src/modules/alwaysontop/AlwaysOnTop/main.cpp b/src/modules/alwaysontop/AlwaysOnTop/main.cpp
index 13e84a9711f..240e995264f 100644
--- a/src/modules/alwaysontop/AlwaysOnTop/main.cpp
+++ b/src/modules/alwaysontop/AlwaysOnTop/main.cpp
@@ -6,8 +6,6 @@
#include
#include
-#include
-
#include
#include
@@ -18,9 +16,6 @@ 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);
@@ -70,8 +65,5 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
Trace::AlwaysOnTop::UnregisterProvider();
- trace.Flush();
- trace.UpdateState(false);
-
return 0;
}
diff --git a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp
index ec540fd6d6a..654f7eb2dbe 100644
--- a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp
+++ b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp
@@ -221,7 +221,7 @@ class AlwaysOnTopModuleInterface : public PowertoyModuleIface
Trace::AlwaysOnTop::Enable(false);
}
- // Wait for 1.5 seconds for the process to end process correctly and stop etw tracer
+ // 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
diff --git a/src/modules/colorPicker/ColorPickerUI/App.xaml.cs b/src/modules/colorPicker/ColorPickerUI/App.xaml.cs
index ca1809c8037..96c7de5e48e 100644
--- a/src/modules/colorPicker/ColorPickerUI/App.xaml.cs
+++ b/src/modules/colorPicker/ColorPickerUI/App.xaml.cs
@@ -17,7 +17,6 @@ namespace ColorPickerUI
///
public partial class App : Application, IDisposable
{
- private ETWTrace etwTrace = new ETWTrace();
private Mutex _instanceMutex;
private static string[] _args;
private int _powerToysRunnerPid;
@@ -30,7 +29,6 @@ public partial class App : Application, IDisposable
protected override void OnStartup(StartupEventArgs e)
{
- etwTrace.Start();
NativeThreadCTS = new CancellationTokenSource();
ExitToken = NativeThreadCTS.Token;
@@ -84,7 +82,6 @@ protected virtual void Dispose(bool disposing)
if (disposing)
{
_instanceMutex?.Dispose();
- etwTrace?.Dispose();
}
disposedValue = true;
diff --git a/src/modules/fancyzones/FancyZones/main.cpp b/src/modules/fancyzones/FancyZones/main.cpp
index 0510aedb55c..4984ed7af3d 100644
--- a/src/modules/fancyzones/FancyZones/main.cpp
+++ b/src/modules/fancyzones/FancyZones/main.cpp
@@ -27,9 +27,6 @@ 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{ L"{38e8889b-9731-53f5-e901-e8a7c1753074}" };
- trace.UpdateState(true);
-
winrt::init_apartment();
LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::fancyZonesLoggerName);
@@ -87,9 +84,5 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
run_message_loop();
Trace::UnregisterProvider();
-
- trace.UpdateState(false);
- trace.Flush();
-
return 0;
}
diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/App.xaml.cpp b/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/App.xaml.cpp
index 03c17b770fa..415acad0d44 100644
--- a/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/App.xaml.cpp
+++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/App.xaml.cpp
@@ -12,8 +12,6 @@
#include
#include
-#include
-
using namespace winrt;
using namespace winrt::Microsoft::UI::Xaml;
using namespace winrt::Microsoft::UI::Xaml::Controls;
@@ -55,9 +53,6 @@ App::App()
/// Details about the launch request and process.
void App::OnLaunched(LaunchActivatedEventArgs const&)
{
- Shared::Trace::ETWTrace trace{ L"{38e8889b-9731-53f5-e901-e8a7c1753074}" };
- trace.UpdateState(true);
-
LoggerHelpers::init_logger(moduleName, L"", LogSettings::powerRenameLoggerName);
if (powertoys_gpo::getConfiguredPowerRenameEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled)
@@ -195,7 +190,4 @@ void App::OnLaunched(LaunchActivatedEventArgs const&)
window = make();
window.Activate();
-
- trace.UpdateState(false);
- trace.Flush();
}
\ No newline at end of file
diff --git a/src/runner/main.cpp b/src/runner/main.cpp
index 8e6b9414987..4531e07f055 100644
--- a/src/runner/main.cpp
+++ b/src/runner/main.cpp
@@ -14,7 +14,6 @@
#include
#include
-#include
#include
#include
#include
@@ -91,6 +90,43 @@ void open_menu_from_another_instance(std::optional settings_window)
PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, msg);
}
+DWORD g_etw_trace_process_id = 0;
+
+void run_etw_trace()
+{
+ PROCESS_INFORMATION process_info = { 0 };
+
+ // Arg 1: executable path.
+ std::wstring executable_path = get_module_folderpath();
+
+ executable_path.append(L"\\PowerToys.EtwTrace.exe");
+
+ // Arg 2: process pid.
+ DWORD powertoys_pid = GetCurrentProcessId();
+
+ std::wstring executable_args = fmt::format(L"\"{}\" {}",
+ executable_path,
+ std::to_wstring(powertoys_pid));
+
+ STARTUPINFO startup_info = { sizeof(startup_info) };
+ if (!CreateProcessW(executable_path.c_str(),
+ executable_args.data(),
+ nullptr,
+ nullptr,
+ FALSE,
+ 0,
+ nullptr,
+ nullptr,
+ &startup_info,
+ &process_info))
+ {
+ // error
+ }
+
+ g_etw_trace_process_id = process_info.dwProcessId;
+
+}
+
int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow, bool openOobe, bool openScoobe, bool showRestartNotificationAfterUpdate)
{
Logger::info("Runner is starting. Elevated={} openOobe={} openScoobe={} showRestartNotificationAfterUpdate={}", isProcessElevated, openOobe, openScoobe, showRestartNotificationAfterUpdate);
@@ -303,9 +339,6 @@ 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{ L"{38e8889b-9731-53f5-e901-e8a7c1753074}" };
- trace.UpdateState(true);
-
Gdiplus::GdiplusStartupInput gpStartupInput;
ULONG_PTR gpToken;
GdiplusStartup(&gpToken, &gpStartupInput, NULL);
@@ -324,6 +357,8 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR l
L"(ML;;NX;;;LW)"; // Integrity label on No execute up for Low mandatory level
initializeCOMSecurity(securityDescriptor);
+ run_etw_trace();
+
int n_cmd_args = 0;
LPWSTR* cmd_arg_list = CommandLineToArgvW(GetCommandLineW(), &n_cmd_args);
switch (should_run_in_special_mode(n_cmd_args, cmd_arg_list))
@@ -483,9 +518,6 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR l
result = -1;
}
- trace.UpdateState(false);
- trace.Flush();
-
// We need to release the mutexes to be able to restart the application
if (msi_mutex)
{
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/MainWindow.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/MainWindow.xaml.cs
index 0ad4a938ed7..c665e3a21ad 100644
--- a/src/settings-ui/Settings.UI/SettingsXAML/MainWindow.xaml.cs
+++ b/src/settings-ui/Settings.UI/SettingsXAML/MainWindow.xaml.cs
@@ -20,12 +20,8 @@ namespace Microsoft.PowerToys.Settings.UI
///
/// An empty window that can be used on its own or navigated to within a Frame.
///
- public sealed partial class MainWindow : WindowEx, IDisposable
+ public sealed partial class MainWindow : WindowEx
{
- private ETWTrace etwTrace = new ETWTrace();
-
- private bool _disposed;
-
public MainWindow(bool createHidden = false)
{
var bootTime = new System.Diagnostics.Stopwatch();
@@ -214,7 +210,6 @@ private void Window_Closed(object sender, WindowEventArgs args)
if (App.GetOobeWindow() == null)
{
App.ClearSettingsWindow();
- Dispose();
}
else
{
@@ -245,26 +240,5 @@ internal void EnsurePageIsSelected()
{
ShellPage.EnsurePageIsSelected();
}
-
- public void Dispose(bool disposing)
- {
- if (_disposed)
- {
- return;
- }
-
- if (disposing)
- {
- etwTrace?.Dispose();
- }
-
- _disposed = true;
- }
-
- public void Dispose()
- {
- Dispose(disposing: true);
- GC.SuppressFinalize(this);
- }
}
}