/ src / modules / Workspaces / WorkspacesLib / WindowUtils.cpp
WindowUtils.cpp
  1  #include "pch.h"
  2  #include "WindowUtils.h"
  3  #include <filesystem>
  4  
  5  #include <appmodel.h>
  6  
  7  #include <shellapi.h>
  8  #include <ShlObj.h>
  9  #include <shobjidl.h>
 10  #include <tlhelp32.h>
 11  #include <wrl.h>
 12  #include <propkey.h>
 13  
 14  #include <wil/com.h>
 15  
 16  #include <common/logger/logger.h>
 17  #include <common/utils/winapi_error.h>
 18  
 19  #include <WorkspacesLib/AppUtils.h>
 20  #include <WorkspacesLib/CommandLineArgsHelper.h>
 21  #include <WorkspacesLib/StringUtils.h>
 22  
 23  namespace Utils
 24  {
 25      std::wstring GetAUMIDFromProcessId(DWORD processId)
 26      {
 27          HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
 28          if (hProcess == NULL)
 29          {
 30              Logger::error(L"Failed to open process handle. Error: {}", get_last_error_or_default(GetLastError()));
 31              return {};
 32          }
 33  
 34          // Get the package full name for the process
 35          UINT32 packageFullNameLength = 0;
 36          LONG rc = GetPackageFullName(hProcess, &packageFullNameLength, nullptr);
 37          if (rc != ERROR_INSUFFICIENT_BUFFER)
 38          {
 39              Logger::error(L"Failed to get package full name length. Error code: {}", rc);
 40              CloseHandle(hProcess);
 41              return {};
 42          }
 43  
 44          std::vector<wchar_t> packageFullName(packageFullNameLength);
 45          rc = GetPackageFullName(hProcess, &packageFullNameLength, packageFullName.data());
 46          if (rc != ERROR_SUCCESS)
 47          {
 48              Logger::error(L"Failed to get package full name. Error code: {}", rc);
 49              CloseHandle(hProcess);
 50              return {};
 51          }
 52  
 53          // Get the AUMID for the package
 54          UINT32 appModelIdLength = 0;
 55          rc = GetApplicationUserModelId(hProcess, &appModelIdLength, nullptr);
 56          if (rc != ERROR_INSUFFICIENT_BUFFER)
 57          {
 58              Logger::error(L"Failed to get AppUserModelId length. Error code: {}", rc);
 59              CloseHandle(hProcess);
 60              return {};
 61          }
 62  
 63          std::vector<wchar_t> appModelId(appModelIdLength);
 64          rc = GetApplicationUserModelId(hProcess, &appModelIdLength, appModelId.data());
 65          if (rc != ERROR_SUCCESS)
 66          {
 67              Logger::error(L"Failed to get AppUserModelId. Error code: {}", rc);
 68              CloseHandle(hProcess);
 69              return {};
 70          }
 71  
 72          CloseHandle(hProcess);
 73          return std::wstring(appModelId.data());
 74      }
 75  
 76      std::wstring GetAUMIDFromWindow(HWND hwnd)
 77      {
 78          std::wstring result{};
 79          if (hwnd == NULL)
 80          {
 81              return result;
 82          }
 83  
 84          Microsoft::WRL::ComPtr<IPropertyStore> propertyStore;
 85          HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&propertyStore));
 86          if (FAILED(hr))
 87          {
 88              return result;
 89          }
 90  
 91          PROPVARIANT propVariant;
 92          PropVariantInit(&propVariant);
 93  
 94          hr = propertyStore->GetValue(PKEY_AppUserModel_ID, &propVariant);
 95          if (SUCCEEDED(hr) && propVariant.vt == VT_LPWSTR && propVariant.pwszVal != nullptr)
 96          {
 97              result = propVariant.pwszVal;
 98          }
 99  
100          PropVariantClear(&propVariant);
101  
102          Logger::info(L"Found a window with aumid {}", result);
103          return result;
104      }
105  }