| 17 | } |
| 18 | |
| 19 | DWORD TAPSite::Install(void*) |
| 20 | { |
| 21 | const auto event = GetReadyEvent(); |
| 22 | |
| 23 | auto [location, hr] = win32::GetDllLocation(wil::GetModuleInstanceHandle()); |
| 24 | if (FAILED(hr)) [[unlikely]] |
| 25 | { |
| 26 | event.SetEvent(); |
| 27 | return hr; |
| 28 | } |
| 29 | |
| 30 | const wil::unique_hmodule wux(LoadLibraryEx(L"Windows.UI.Xaml.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32)); |
| 31 | if (!wux) [[unlikely]] |
| 32 | { |
| 33 | event.SetEvent(); |
| 34 | return HRESULT_FROM_WIN32(GetLastError()); |
| 35 | } |
| 36 | |
| 37 | const auto ixde = reinterpret_cast<PFN_INITIALIZE_XAML_DIAGNOSTICS_EX>(GetProcAddress(wux.get(), UTIL_STRINGIFY_UTF8(InitializeXamlDiagnosticsEx))); |
| 38 | if (!ixde) [[unlikely]] |
| 39 | { |
| 40 | event.SetEvent(); |
| 41 | return HRESULT_FROM_WIN32(GetLastError()); |
| 42 | } |
| 43 | |
| 44 | DWORD pid = GetCurrentProcessId(); |
| 45 | uint8_t attempts = 1; |
| 46 | do |
| 47 | { |
| 48 | // We need this to exist because XAML Diagnostics can only be initialized once per thread |
| 49 | // future calls simply return S_OK without doing anything. |
| 50 | std::thread([&hr, ixde, pid, &location, conn = std::format(L"VisualDiagConnection{}", static_cast<int>(attempts))] |
| 51 | { |
| 52 | hr = ixde(conn.c_str(), pid, nullptr, location.c_str(), CLSID_TAPSite, nullptr); |
| 53 | }).join(); |
| 54 | |
| 55 | if (SUCCEEDED(hr)) |
| 56 | { |
| 57 | return S_OK; |
| 58 | } |
| 59 | else |
| 60 | { |
| 61 | ++attempts; |
| 62 | Sleep(500); |
| 63 | } |
| 64 | } while (FAILED(hr) && attempts <= 60); |
| 65 | // 60 * 500ms = 30s |
| 66 | |
| 67 | event.SetEvent(); |
| 68 | return hr; |
| 69 | } |
| 70 | |
| 71 | HRESULT TAPSite::SetSite(IUnknown *pUnkSite) try |
| 72 | { |