main.cpp
1 #include "pch.h" 2 3 #include <common/utils/logger_helper.h> 4 #include <common/utils/ProcessWaiter.h> 5 #include <common/utils/window.h> 6 #include <common/utils/UnhandledExceptionHandler.h> 7 #include <common/utils/gpo.h> 8 9 #include <common/Telemetry/EtwTrace/EtwTrace.h> 10 11 #include <AlwaysOnTop.h> 12 #include <trace.h> 13 14 // Non-localizable 15 const std::wstring moduleName = L"AlwaysOnTop"; 16 const std::wstring internalPath = L""; 17 const std::wstring instanceMutexName = L"Local\\PowerToys_AlwaysOnTop_InstanceMutex"; 18 19 int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ int nCmdShow) 20 { 21 Shared::Trace::ETWTrace trace; 22 trace.UpdateState(true); 23 24 winrt::init_apartment(); 25 LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::alwaysOnTopLoggerName); 26 27 if (powertoys_gpo::getConfiguredAlwaysOnTopEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) 28 { 29 Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); 30 return 0; 31 } 32 33 InitUnhandledExceptionHandler(); 34 35 auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str()); 36 if (mutex == nullptr) 37 { 38 Logger::error(L"Failed to create mutex. {}", get_last_error_or_default(GetLastError())); 39 } 40 41 if (GetLastError() == ERROR_ALREADY_EXISTS) 42 { 43 return 0; 44 } 45 46 auto mainThreadId = GetCurrentThreadId(); 47 48 std::wstring pid = std::wstring(lpCmdLine); 49 if (!pid.empty()) 50 { 51 ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) { 52 if (err != ERROR_SUCCESS) 53 { 54 Logger::error(L"Failed to wait for parent process exit. {}", get_last_error_or_default(err)); 55 } 56 else 57 { 58 Logger::trace(L"PowerToys runner exited."); 59 } 60 61 Logger::trace(L"Exiting AlwaysOnTop"); 62 PostThreadMessage(mainThreadId, WM_QUIT, 0, 0); 63 }); 64 } 65 66 Trace::AlwaysOnTop::RegisterProvider(); 67 68 AlwaysOnTop app(!pid.empty(), mainThreadId); 69 70 run_message_loop(); 71 72 Trace::AlwaysOnTop::UnregisterProvider(); 73 74 trace.Flush(); 75 76 return 0; 77 }