[BugReportTool] Report compatibility tabs (#11375)

This commit is contained in:
Mykhailo Pylyp 2021-05-20 18:41:12 +03:00 committed by GitHub
parent 601da71f15
commit d55badf14a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 143 additions and 41 deletions

View File

@ -2231,6 +2231,7 @@ workaround
workflow workflow
workspaces workspaces
wostream wostream
wostringstream
wox wox
wparam wparam
wpf wpf

View File

@ -38,8 +38,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="ReportMonitorInfo.cpp" /> <ClCompile Include="ReportMonitorInfo.cpp" />
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />
<ClCompile Include="ReportRegistry.cpp" /> <ClCompile Include="RegistryUtils.cpp" />
<ClCompile Include="ZipTools\zipfolder.cpp" /> <ClCompile Include="ZipTools\ZipFolder.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
@ -54,8 +54,8 @@
<ClInclude Include="..\..\..\deps\cziplib\src\zip.h" /> <ClInclude Include="..\..\..\deps\cziplib\src\zip.h" />
<ClInclude Include="ReportMonitorInfo.h" /> <ClInclude Include="ReportMonitorInfo.h" />
<ClInclude Include="..\..\..\common\utils\json.h" /> <ClInclude Include="..\..\..\common\utils\json.h" />
<ClInclude Include="ReportRegistry.h" /> <ClInclude Include="RegistryUtils.h" />
<ClInclude Include="ZipTools\zipfolder.h" /> <ClInclude Include="ZipTools\ZipFolder.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -5,12 +5,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />
<ClCompile Include="ZipTools\zipfolder.cpp"> <ClCompile Include="ZipTools\ZipFolder.cpp">
<Filter>ZipTools</Filter> <Filter>ZipTools</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\deps\cziplib\src\zip.c" /> <ClCompile Include="..\..\..\deps\cziplib\src\zip.c" />
<ClCompile Include="ReportMonitorInfo.cpp" /> <ClCompile Include="ReportMonitorInfo.cpp" />
<ClCompile Include="ReportRegistry.cpp" /> <ClCompile Include="RegistryUtils.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="ZipTools"> <Filter Include="ZipTools">
@ -18,13 +18,13 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ZipTools\zipfolder.h"> <ClInclude Include="ZipTools\ZipFolder.h">
<Filter>ZipTools</Filter> <Filter>ZipTools</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\common\utils\json.h" /> <ClInclude Include="..\..\..\common\utils\json.h" />
<ClInclude Include="..\..\..\deps\cziplib\src\miniz.h" /> <ClInclude Include="..\..\..\deps\cziplib\src\miniz.h" />
<ClInclude Include="..\..\..\deps\cziplib\src\zip.h" /> <ClInclude Include="..\..\..\deps\cziplib\src\zip.h" />
<ClInclude Include="ReportMonitorInfo.h" /> <ClInclude Include="ReportMonitorInfo.h" />
<ClInclude Include="ReportRegistry.h" /> <ClInclude Include="RegistryUtils.h" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -15,7 +15,7 @@
#include <common/utils/exec.h> #include <common/utils/exec.h>
#include "ReportMonitorInfo.h" #include "ReportMonitorInfo.h"
#include "ReportRegistry.h" #include "RegistryUtils.h"
using namespace std; using namespace std;
using namespace std::filesystem; using namespace std::filesystem;
using namespace winrt::Windows::Data::Json; using namespace winrt::Windows::Data::Json;
@ -33,7 +33,7 @@ vector<wstring> filesToDelete = {
L"PowerToys Run\\Settings\\QueryHistory.json" L"PowerToys Run\\Settings\\QueryHistory.json"
}; };
vector<wstring> getXpathArray(wstring xpath) vector<wstring> GetXpathArray(wstring xpath)
{ {
vector<wstring> result; vector<wstring> result;
wstring cur = L""; wstring cur = L"";
@ -57,13 +57,13 @@ vector<wstring> getXpathArray(wstring xpath)
return result; return result;
} }
void hideByXPath(IJsonValue& val, vector<wstring>& xpathArray, int p) void HideByXPath(IJsonValue& val, vector<wstring>& xpathArray, int p)
{ {
if (val.ValueType() == JsonValueType::Array) if (val.ValueType() == JsonValueType::Array)
{ {
for (auto it : val.GetArray()) for (auto it : val.GetArray())
{ {
hideByXPath(it, xpathArray, p); HideByXPath(it, xpathArray, p);
} }
return; return;
@ -96,11 +96,11 @@ void hideByXPath(IJsonValue& val, vector<wstring>& xpathArray, int p)
return; return;
} }
hideByXPath(newVal, xpathArray, p + 1); HideByXPath(newVal, xpathArray, p + 1);
} }
} }
void hideForFile(const path& dir, const wstring& relativePath) void HideForFile(const path& dir, const wstring& relativePath)
{ {
path jsonPath = dir; path jsonPath = dir;
jsonPath.append(relativePath); jsonPath.append(relativePath);
@ -114,14 +114,14 @@ void hideForFile(const path& dir, const wstring& relativePath)
JsonValue jValue = json::value(jObject.value()); JsonValue jValue = json::value(jObject.value());
for (auto xpath : escapeInfo[relativePath]) for (auto xpath : escapeInfo[relativePath])
{ {
vector<wstring> xpathArray = getXpathArray(xpath); vector<wstring> xpathArray = GetXpathArray(xpath);
hideByXPath(jValue, xpathArray, 0); HideByXPath(jValue, xpathArray, 0);
} }
json::to_file(jsonPath.wstring(), jObject.value()); json::to_file(jsonPath.wstring(), jObject.value());
} }
bool deleteFolder(wstring path) bool DeleteFolder(wstring path)
{ {
error_code err; error_code err;
remove_all(path, err); remove_all(path, err);
@ -134,12 +134,12 @@ bool deleteFolder(wstring path)
return true; return true;
} }
void hideUserPrivateInfo(const filesystem::path& dir) void HideUserPrivateInfo(const filesystem::path& dir)
{ {
// Replace data in json files // Replace data in json files
for (auto& it : escapeInfo) for (auto& it : escapeInfo)
{ {
hideForFile(dir, it.first); HideForFile(dir, it.first);
} }
// delete files // delete files
@ -147,11 +147,11 @@ void hideUserPrivateInfo(const filesystem::path& dir)
{ {
auto path = dir; auto path = dir;
path = path.append(it); path = path.append(it);
deleteFolder(path); DeleteFolder(path);
} }
} }
void reportWindowsVersion(const filesystem::path& tmpDir) void ReportWindowsVersion(const filesystem::path& tmpDir)
{ {
auto versionReportPath = tmpDir; auto versionReportPath = tmpDir;
versionReportPath = versionReportPath.append("windows-version.txt"); versionReportPath = versionReportPath.append("windows-version.txt");
@ -187,7 +187,7 @@ void reportWindowsVersion(const filesystem::path& tmpDir)
} }
} }
void reportWindowsSettings(const filesystem::path& tmpDir) void ReportWindowsSettings(const filesystem::path& tmpDir)
{ {
std::wstring userLanguage; std::wstring userLanguage;
std::wstring userLocale; std::wstring userLocale;
@ -221,7 +221,7 @@ void reportWindowsSettings(const filesystem::path& tmpDir)
} }
void reportDotNetInstallationInfo(const filesystem::path& tmpDir) void ReportDotNetInstallationInfo(const filesystem::path& tmpDir)
{ {
auto dotnetInfoPath = tmpDir; auto dotnetInfoPath = tmpDir;
dotnetInfoPath.append("dotnet-installation-info.txt"); dotnetInfoPath.append("dotnet-installation-info.txt");
@ -271,7 +271,7 @@ int wmain(int argc, wchar_t* argv[], wchar_t*)
// Copy to a temp folder // Copy to a temp folder
auto tmpDir = temp_directory_path(); auto tmpDir = temp_directory_path();
tmpDir = tmpDir.append("PowerToys\\"); tmpDir = tmpDir.append("PowerToys\\");
if (!deleteFolder(tmpDir)) if (!DeleteFolder(tmpDir))
{ {
printf("Failed to delete temp folder\n"); printf("Failed to delete temp folder\n");
return 1; return 1;
@ -281,7 +281,7 @@ int wmain(int argc, wchar_t* argv[], wchar_t*)
{ {
copy(settingsRootPath, tmpDir, copy_options::recursive); copy(settingsRootPath, tmpDir, copy_options::recursive);
// Remove updates folder contents // Remove updates folder contents
deleteFolder(tmpDir / "Updates"); DeleteFolder(tmpDir / "Updates");
} }
catch (...) catch (...)
{ {
@ -290,22 +290,25 @@ int wmain(int argc, wchar_t* argv[], wchar_t*)
} }
// Hide sensitive information // Hide sensitive information
hideUserPrivateInfo(tmpDir); HideUserPrivateInfo(tmpDir);
// Write windows settings to the temporary folder // Write windows settings to the temporary folder
reportWindowsSettings(tmpDir); ReportWindowsSettings(tmpDir);
// Write monitors info to the temporary folder // Write monitors info to the temporary folder
reportMonitorInfo(tmpDir); reportMonitorInfo(tmpDir);
// Write windows version info to the temporary folder // Write windows version info to the temporary folder
reportWindowsVersion(tmpDir); ReportWindowsVersion(tmpDir);
// Write dotnet installation info to the temporary folder // Write dotnet installation info to the temporary folder
reportDotNetInstallationInfo(tmpDir); ReportDotNetInstallationInfo(tmpDir);
// Write registry to the temporary folder // Write registry to the temporary folder
reportRegistry(tmpDir); ReportRegistry(tmpDir);
// Write compatibility tab info to the temporary folder
ReportCompatibilityTab(tmpDir);
// Zip folder // Zip folder
auto zipPath = path::path(saveZipPath); auto zipPath = path::path(saveZipPath);
@ -316,7 +319,7 @@ int wmain(int argc, wchar_t* argv[], wchar_t*)
try try
{ {
zipFolder(zipPath, tmpDir); ZipFolder(zipPath, tmpDir);
} }
catch (...) catch (...)
{ {
@ -324,6 +327,6 @@ int wmain(int argc, wchar_t* argv[], wchar_t*)
return 1; return 1;
} }
deleteFolder(tmpDir); DeleteFolder(tmpDir);
return 0; return 0;
} }

View File

@ -1,4 +1,6 @@
#include "ReportRegistry.h" #include "RegistryUtils.h"
#include <common/utils/winapi_error.h>
#include <map>
using namespace std; using namespace std;
@ -38,7 +40,35 @@ namespace
{ HKEY_USERS, L"HKEY_USERS"}, { HKEY_USERS, L"HKEY_USERS"},
}; };
void queryKey(HKEY key, wofstream& stream, int indent = 1) vector<pair<wstring, wstring>> QueryValues(HKEY key)
{
DWORD cValues;
DWORD retCode = RegQueryInfoKeyW(key, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &cValues, nullptr, nullptr, nullptr, nullptr);
TCHAR achValue[255];
DWORD cchValue = 255;
LPBYTE value;
vector<pair<wstring, wstring>> results;
// Values
if (cValues)
{
for (DWORD i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
{
cchValue = 255;
achValue[0] = '\0';
value = new BYTE[16383];
retCode = RegEnumValueW(key, i, achValue, &cchValue, NULL, NULL, value, &cchValue);
if (retCode == ERROR_SUCCESS)
{
results.push_back({ achValue, (LPCTSTR)value });
}
}
}
return results;
}
void QueryKey(HKEY key, wostream& stream, int indent = 1)
{ {
TCHAR achKey[255]; TCHAR achKey[255];
DWORD cbName; DWORD cbName;
@ -114,7 +144,7 @@ namespace
if (RegOpenKeyExW(key, child.c_str(), 0, KEY_READ, &hTestKey) == ERROR_SUCCESS) if (RegOpenKeyExW(key, child.c_str(), 0, KEY_READ, &hTestKey) == ERROR_SUCCESS)
{ {
stream << wstring(indent, '\t') << child << "\n"; stream << wstring(indent, '\t') << child << "\n";
queryKey(hTestKey, stream, indent + 1); QueryKey(hTestKey, stream, indent + 1);
RegCloseKey(hTestKey); RegCloseKey(hTestKey);
} }
else else
@ -126,7 +156,74 @@ namespace
} }
} }
void reportRegistry(const filesystem::path& tmpDir) void ReportCompatibilityTab(HKEY key, wofstream& report)
{
vector<std::wstring> apps
{
L"PowerToys.exe",
L"ColorPickerUI.exe",
L"FancyZonesEditor.exe",
L"PowerToys.KeyboardManagerEditor.exe",
L"PowerToys.KeyboardManagerEditor.exe",
L"PowerLauncher.exe",
L"PowerToys.ShortcutGuide.exe"
};
map<wstring, wstring> flags;
for (auto app : apps)
{
flags[app] = L"";
}
try
{
HKEY outKey;
LONG result = RegOpenKeyExW(key, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, KEY_READ, &outKey);
if (result == ERROR_SUCCESS)
{
auto values = QueryValues(outKey);
for (auto value : values)
{
for (auto app : apps)
{
if (value.first.find(app) != wstring::npos)
{
flags[app] += value.second;
}
}
}
}
else
{
report << "Failed to get the report. " << get_last_error_or_default(GetLastError());
return;
}
}
catch (...)
{
report << "Failed to get the report";
return;
}
for (auto flag : flags)
{
report << flag.first << ": " << flag.second << endl;
}
}
void ReportCompatibilityTab(const std::filesystem::path& tmpDir)
{
auto reportPath = tmpDir;
reportPath.append(L"compatibility-tab-info.txt");
wofstream report(reportPath);
report << "Current user report" << endl;
ReportCompatibilityTab(HKEY_CURRENT_USER, report);
report << endl << endl;
report << "Local machine report" << endl;
ReportCompatibilityTab(HKEY_LOCAL_MACHINE, report);
}
void ReportRegistry(const filesystem::path& tmpDir)
{ {
auto registryReportPath = tmpDir; auto registryReportPath = tmpDir;
registryReportPath.append("registry-report-info.txt"); registryReportPath.append("registry-report-info.txt");
@ -142,7 +239,7 @@ void reportRegistry(const filesystem::path& tmpDir)
LONG result = RegOpenKeyExW(rootKey, subKey.c_str(), 0, KEY_READ, &outKey); LONG result = RegOpenKeyExW(rootKey, subKey.c_str(), 0, KEY_READ, &outKey);
if (result == ERROR_SUCCESS) if (result == ERROR_SUCCESS)
{ {
queryKey(outKey, registryReport); QueryKey(outKey, registryReport);
RegCloseKey(rootKey); RegCloseKey(rootKey);
} }
else else

View File

@ -7,4 +7,5 @@
#include <unordered_map> #include <unordered_map>
#include <Windows.h> #include <Windows.h>
void reportRegistry(const std::filesystem::path& tmpDir); void ReportRegistry(const std::filesystem::path& tmpDir);
void ReportCompatibilityTab(const std::filesystem::path& tmpDir);

View File

@ -1,7 +1,7 @@
#include "zipfolder.h" #include "ZipFolder.h"
#include "..\..\..\..\deps\cziplib\src\zip.h" #include "..\..\..\..\deps\cziplib\src\zip.h"
void zipFolder(std::filesystem::path zipPath, std::filesystem::path folderPath) void ZipFolder(std::filesystem::path zipPath, std::filesystem::path folderPath)
{ {
struct zip_t* zip = zip_open(zipPath.string().c_str(), ZIP_DEFAULT_COMPRESSION_LEVEL, 'w'); struct zip_t* zip = zip_open(zipPath.string().c_str(), ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
if (!zip) if (!zip)

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
#include <filesystem> #include <filesystem>
void zipFolder(std::filesystem::path zipPath, std::filesystem::path folderPath); void ZipFolder(std::filesystem::path zipPath, std::filesystem::path folderPath);