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  }