close
Skip to content
This repository was archived by the owner on May 29, 2025. It is now read-only.

Commit 6115a3b

Browse files
committed
Search more widely for xperf.exe
If WPT 22H2 is installed as a stand-alone product then it is installed to ProgramFiles rather than ProgramFilesX86 and it cannot be located in the SDK install folder. Therefore it is necessary to look in the likely paths to see if xperf.exe can be found. GetInstallFolder() was created and improved to handle this, and is called after running the installers to refresh the install path.
1 parent c54ed34 commit 6115a3b

2 files changed

Lines changed: 56 additions & 44 deletions

File tree

‎UIforETW/UIforETWDlg.cpp‎

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,51 @@ void CUIforETWDlg::CheckSymbolDLLs()
335335
}
336336
}
337337

338+
void CUIforETWDlg::GetInstallFolder()
339+
{
340+
// The WPT installer is always a 32-bit installer, so we look for it in
341+
// ProgramFilesX86 / WOW6432Node, on 32-bit and 64-bit operating systems.
342+
wpt10Dir_ = ReadRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v10.0", L"InstallationFolder", true);
343+
if (!wpt10Dir_.empty())
344+
{
345+
EnsureEndsWithDirSeparator(wpt10Dir_);
346+
wpt10Dir_ += L"Windows Performance Toolkit\\";
347+
}
348+
349+
// Look for alternate install paths if needed.
350+
{
351+
const wchar_t* const suffix = L"\\Windows Kits\\10\\Windows Performance Toolkit\\";
352+
wchar_t* progFilesx86Dir = nullptr;
353+
if (!SUCCEEDED(SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, nullptr, &progFilesx86Dir)))
354+
std::terminate();
355+
std::wstring windowsKits86Dir = progFilesx86Dir;
356+
CoTaskMemFree(progFilesx86Dir);
357+
windowsKits86Dir += suffix;
358+
359+
wchar_t* progFilesDir = nullptr;
360+
if (!SUCCEEDED(SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, nullptr, &progFilesDir)))
361+
std::terminate();
362+
std::wstring windowsKitsDir = progFilesDir;
363+
CoTaskMemFree(progFilesDir);
364+
windowsKitsDir += suffix;
365+
366+
// If the registry entries were unavailable, fall back to assuming their installation directory.
367+
// Starting with the 22H2 SDK this is the ProgramFiles directory rather than ProgramFilesX86
368+
if (wpt10Dir_.empty())
369+
{
370+
wpt10Dir_ = windowsKitsDir;
371+
}
372+
// If xperf.exe doesn't exist in wpt10Dir_ and it does exist elsewhere, switch to that.
373+
else if (!PathFileExists((wpt10Dir_ + L"xperf.exe").c_str()))
374+
{
375+
if (PathFileExists((windowsKits86Dir + L"xperf.exe").c_str()))
376+
wpt10Dir_ = windowsKits86Dir;
377+
else if (PathFileExists((windowsKitsDir + L"xperf.exe").c_str()))
378+
wpt10Dir_ = windowsKitsDir;
379+
}
380+
}
381+
}
382+
338383
BOOL CUIforETWDlg::OnInitDialog()
339384
{
340385
CDialog::OnInitDialog();
@@ -410,30 +455,7 @@ BOOL CUIforETWDlg::OnInitDialog()
410455
systemDrive_ = static_cast<char>(windowsDir_[0]);
411456
systemDrive_ += ":\\";
412457

413-
414-
// The WPT installer is always a 32-bit installer, so we look for it in
415-
// ProgramFilesX86 / WOW6432Node, on 32-bit and 64-bit operating systems.
416-
wpt10Dir_ = ReadRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v10.0", L"InstallationFolder", true);
417-
if (!wpt10Dir_.empty())
418-
{
419-
EnsureEndsWithDirSeparator(wpt10Dir_);
420-
wpt10Dir_ += L"Windows Performance Toolkit\\";
421-
}
422-
423-
// If the registry entries were unavailable, fall back to assuming their installation directory.
424-
if (wpt10Dir_.empty())
425-
{
426-
wchar_t* progFilesx86Dir = nullptr;
427-
if (!SUCCEEDED(SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, nullptr, &progFilesx86Dir)))
428-
std::terminate();
429-
std::wstring windowsKitsDir = progFilesx86Dir;
430-
CoTaskMemFree(progFilesx86Dir);
431-
windowsKitsDir += L"\\Windows Kits\\";
432-
if (wpt10Dir_.empty())
433-
{
434-
wpt10Dir_ = windowsKitsDir + L"10\\Windows Performance Toolkit\\";
435-
}
436-
}
458+
GetInstallFolder();
437459

438460
auto xperfVersion = GetFileVersion(GetXperfPath());
439461
constexpr int64_t requiredXperfVersion = (10llu << 48) + 0 + (10586llu << 16) + (15llu << 0);
@@ -472,6 +494,8 @@ BOOL CUIforETWDlg::OnInitDialog()
472494
}
473495
if (success)
474496
{
497+
// Re-run GetInstallFolder() to make sure we have the correct path.
498+
GetInstallFolder();
475499
xperfVersion = GetFileVersion(GetXperfPath());
476500
outputPrintf(L"WPT version %llu.%llu.%llu.%llu was installed.\n",
477501
xperfVersion >> 48, (xperfVersion >> 32) & 0xFFFF,
@@ -489,27 +513,14 @@ BOOL CUIforETWDlg::OnInitDialog()
489513
// Because of bugs in the initial WPT 10 we require the TH2 version.
490514
if (xperfVersion < requiredXperfVersion)
491515
{
492-
if (Is64BitWindows())
493-
{
494-
if (xperfVersion)
495-
AfxMessageBox((GetXperfPath() + L" must be version 10.0.10586.15 or higher. If you run UIforETW from etwpackage.zip\n"
496-
L"from https://github.com/google/UIforETW/releases\n"
497-
L"then WPT will be automatically installed. Exiting.").c_str());
498-
else
499-
AfxMessageBox((GetXperfPath() + L" does not exist. If you run UIforETW from etwpackage.zip\n"
500-
L"from https://github.com/google/UIforETW/releases\n"
501-
L"then WPT will be automatically installed. Exiting.").c_str());
502-
}
516+
if (xperfVersion)
517+
AfxMessageBox((GetXperfPath() + L" must be version 10.0.10586.15 or higher. If you run UIforETW from etwpackage.zip\n"
518+
L"from https://github.com/google/UIforETW/releases\n"
519+
L"then WPT will be automatically installed. Exiting.").c_str());
503520
else
504-
{
505-
if (xperfVersion)
506-
AfxMessageBox((GetXperfPath() + L" must be version 10.0.10586.15 or higher. You'll need to find the installer in the "
507-
L"Windows 10 SDK or you can xcopy install it. Exiting.").c_str());
508-
else
509-
AfxMessageBox((GetXperfPath() + L" does not exist. You'll need to find the installer in the "
510-
L"Windows 10 SDK or you can xcopy install it. Exiting.").c_str());
511-
}
512-
exit(10);
521+
AfxMessageBox((GetXperfPath() + L" does not exist. If you run UIforETW from etwpackage.zip\n"
522+
L"from https://github.com/google/UIforETW/releases\n"
523+
L"then WPT will be automatically installed. Exiting.").c_str());
513524
}
514525

515526
if (xperfVersion >= preferredXperfVersion)

‎UIforETW/UIforETWDlg.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ class CUIforETWDlg : public CDialog
185185
// false), saving the trace as well if bSaveTrace is true.
186186
void StopTracingAndMaybeRecord(bool bSaveTrace);
187187

188+
void GetInstallFolder();
188189
std::wstring GetXperfPath() const { return wpt10Dir_ + L"xperf.exe"; }
189190
std::wstring GetTraceDir() const { return traceDir_; }
190191
std::wstring GetExeDir() const;

0 commit comments

Comments
 (0)