From cf87c3fa3a282a2dfe94adbab99ae3df9f3adf7f Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Mon, 12 Jul 2021 09:03:01 -0700 Subject: [PATCH] Find wpa.exe in the path to support store versions There are now previous versions of WPA in the Microsoft store and these versions are newer than the versions shipped through the SDK. This change teaches UIforETW how to search the path to find wpa.exe. This lets developers configure their system path so that the desired version of wpa.exe comes earliest in the path. This should be sufficient to finally resolve issue #118. --- UIforETW/UIforETWDlg.cpp | 5 ++++- UIforETW/Utility.cpp | 43 +++++++++++++++++++++++++++------------- UIforETW/Utility.h | 5 ++++- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/UIforETW/UIforETWDlg.cpp b/UIforETW/UIforETWDlg.cpp index 4ea29370..b2bc7442 100644 --- a/UIforETW/UIforETWDlg.cpp +++ b/UIforETW/UIforETWDlg.cpp @@ -542,7 +542,10 @@ BOOL CUIforETWDlg::OnInitDialog() } gpuViewPath_ = wpt10Dir_ + L"gpuview\\gpuview.exe"; - wpa10Path_ = wpt10Dir_ + L"wpa.exe"; + // look for wpa.exe in the path so that the store version can be used. + wpa10Path_ = FindInPath(L"wpa.exe"); + if (wpa10Path_.empty()) + wpa10Path_ = wpt10Dir_ + L"wpa.exe"; // When WPT has just been installed it will not be in the path, which means // that Python scripts which rely on xperf.exe being in the path will fail. diff --git a/UIforETW/Utility.cpp b/UIforETW/Utility.cpp index 7ae65671..6c32ea53 100644 --- a/UIforETW/Utility.cpp +++ b/UIforETW/Utility.cpp @@ -820,6 +820,30 @@ std::wstring GetEnvironmentVariableString(_In_z_ PCWSTR const variable) return L""; } +std::wstring FindInPath(const std::wstring& exeName) +{ + const std::wstring path = GetEnvironmentVariableString(L"path"); + if (path.empty()) + { + // Nothing found. + return L""; + } + + const std::vector pathParts = split(path, ';'); + + for (const auto& part : pathParts) + { + if (part.empty()) + continue; + const std::wstring foundPath = part + L'\\' + exeName; + if (::PathFileExistsW(foundPath.c_str())) + return foundPath; + } + + // Nothing found. + return L""; +} + std::wstring FindPython() { const std::wstring pytwoseven = GetEnvironmentVariableString(L"python27"); @@ -830,25 +854,16 @@ std::wstring FindPython() // See the issue: https://github.com/google/UIforETW/issues/13 if (!pytwoseven.empty()) return pytwoseven; - const std::wstring path = GetEnvironmentVariableString(L"path"); - if (path.empty()) - { - // No python found. - return L""; - } - const std::vector pathParts = split(path, ';'); // First look for python.exe. If that isn't found then look for // python.bat, part of Chromium's depot_tools - for (const auto& exeName : { L"\\python.exe", L"\\python.bat" }) + for (const auto& exeName : { L"python.exe", L"python.bat" }) { - for (const auto& part : pathParts) - { - const std::wstring pythonPath = part + exeName; - if (::PathFileExistsW(pythonPath.c_str())) - return pythonPath; - } + auto result = FindInPath(exeName); + if (!result.empty()) + return result; } + // No python found. return L""; } diff --git a/UIforETW/Utility.h b/UIforETW/Utility.h index 6484fe24..74773848 100644 --- a/UIforETW/Utility.h +++ b/UIforETW/Utility.h @@ -101,7 +101,10 @@ bool IsWindowsXPOrLesser(); bool IsWindowsSevenOrLesser(); bool IsWindowsVistaOrLesser(); -std::wstring FindPython(); // Returns a full path to python.exe or nothing. +// Finds an executable in the path. +std::wstring FindInPath(const std::wstring& exeName); + +std::wstring FindPython(); // Returns a full path to python.exe, python.bat, or nothing. // Helpful timer class using trendy C++ 11 features. class ElapsedTimer final