@@ -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+
338383BOOL 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)
0 commit comments