Bug report tool (#8633)

* added diagnostic tool project

* Add copy to a temp folder, escape private info and zip it

* Added diagnostic tool to installer

* zip folder path as cmd argument

* renamed project to BugReportTool

* do not use precompile headers for release

* Added zip lib

* Added license

* Delete old zip source files

* Use fork version while PR is not merged

* fix spelling

* exclude deps folder from spell checking

* exclude only zip

* removed redundant configuration from zip project

* fix spelling

* Add error handling to implementation

* Added build of BugReportTool.sln to pipeline

* Delete redundant info from BugReportTool.vcxproj

* Deleted submodule

* Added submodule

* fix build

* Restore nuget packages for BugReportTool.sln on CI

* spelling fix

* Use SettingsAPI

* changed git submodule

* added new sensitive info

* Removed zip project

* use json.h, add date to zipfolder, handle zip is not created

* fix spelling

* delete bad_alloc catch

* add new sensative info

* report monitor info

* report windows version

* fix spelling

* delete platform specific configuration

* fix output
This commit is contained in:
Mykhailo Pylyp 2020-12-22 12:27:28 +02:00 committed by GitHub
parent 063e704321
commit 321a722b8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 624 additions and 88 deletions

View File

@ -222,8 +222,8 @@ CDeclaration
cdpx
cdpxwin
CENTERALIGN
Cfg
cfg
Cfg
changecursor
Changemove
charset
@ -317,8 +317,8 @@ constexpr
contentdialog
contentfiles
CONTEXTHELP
CONTEXTMENU
contextmenu
CONTEXTMENU
CONTEXTMENUHANDLER
CONTROLL
CONTROLPARENT
@ -362,6 +362,7 @@ crutkas
CSearch
CSettings
csharp
CSIDL
csignal
cso
csproj
@ -397,6 +398,7 @@ cxxopts
CYMK
CYSMICON
cz
cziplib
Dac
dacl
DARKBLUE
@ -407,12 +409,13 @@ DARKRED
DARKTEAL
DARKYELLOW
Dataflows
Datavalue
DATAW
davidegiacometti
Dayof
Dbg
DBLEPSILON
DBLCLKS
DBLEPSILON
DCOM
dcomp
DComposition
@ -653,14 +656,14 @@ ENU
enum
ENUMITEMS
EOAC
EOL
eol
EOL
epicgames
ERASEBKGND
EREOF
EResize
ERRORLEVEL
errorlevel
ERRORLEVEL
ERRORMESSAGE
ERRORTITLE
esize
@ -710,6 +713,7 @@ fancyzones
FANCYZONESDRAWLAYOUTTEST
FANCYZONESEDITOR
Farbraum
FARPROC
Favicon
fbdc
fcharset
@ -767,6 +771,7 @@ FULLNAME
fullscreen
func
fwlink
fwrite
fx
fxcop
gabime
@ -860,8 +865,8 @@ HLSL
hmenu
hmodule
hmon
HMONITOR
hmonitor
HMONITOR
HOLDENTER
HOLDESC
homljgmgpmcbpjbnjpfijnhipfkiclkd
@ -975,6 +980,7 @@ IInput
IInspectable
IIO
IItem
IJson
IList
ILogon
IMAGEHLP
@ -1239,6 +1245,7 @@ LPNMHDR
LPNMHEADER
LPNMLISTVIEW
LPOLESTR
LPOSVERSIONINFOEXW
LPPOINT
lprc
LPRECT
@ -1298,6 +1305,7 @@ MBUTTON
MBUTTONDBLCLK
MBUTTONDOWN
MBUTTONUP
mday
Mdb
MDICHILD
MDL
@ -1325,6 +1333,7 @@ millis
mimetype
Minimizeallwindows
MINIMIZEBOX
miniz
MINMAXINFO
Miracast
mixin
@ -1384,6 +1393,7 @@ msrc
mst
msvc
msvcp
msvs
MTND
Mul
multiline
@ -1499,7 +1509,9 @@ npm
npmjs
npos
NResize
ntdll
NTFS
NTSTATUS
nuget
nullopt
nullptr
@ -1552,6 +1564,7 @@ oss
ostr
ostream
ostringstream
OSVERSIONINFOEXW
osx
otating
ouicompat
@ -1692,8 +1705,8 @@ propkey
propvarutil
Prt
prui
PRVPANE
prvpane
PRVPANE
psapi
PSECURITY
psfgao
@ -1827,8 +1840,8 @@ roslyn
royvou
rpc
RRF
RSHIFT
rshift
RSHIFT
Rsp
rst
Rstrtmgr
@ -1885,13 +1898,14 @@ Sekan
SENDCHANGE
sendinput
sendvirtualinput
sensative
serializationexception
serializer
serizalization
serverside
SETCONTEXT
SETCURSOR
setcursor
SETCURSOR
SETFOCUS
SETFOREGROUND
SETICON
@ -1922,8 +1936,8 @@ SHELLDLL
shellex
SHELLEXECUTEINFO
SHELLEXECUTEINFOW
Shellscalingapi
shellscalingapi
Shellscalingapi
Shelveset
SHFILEINFO
SHGFI
@ -1977,8 +1991,8 @@ sketchapp
SKIPDOTNETINSTALL
SKIPOWNPROCESS
sku
Skype
SKYBLUE
Skype
SLGP
Slideshow
sln
@ -2101,8 +2115,8 @@ SYSDEADCHAR
SYSICONINDEX
SYSKEY
syskeydown
SYSKEYUP
syskeyup
SYSKEYUP
syslog
SYSMENU
systemd
@ -2250,12 +2264,13 @@ uninstalling
uninstantiated
Uniq
uniquifier
Uniquifies
uniquifies
Uniquifies
unittests
unk
unknwn
UNLEN
unlicense
Unmap
UNORM
Unpublish
@ -2361,8 +2376,8 @@ wcslen
wcsncmp
wcsnicmp
wdp
WDS
wds
WDS
wdupenv
weakme
webapp
@ -2379,13 +2394,14 @@ Whichdoes
whitespaces
WIC
Wifi
wifstream
wih
wiki
wikipedia
wil
wildcards
WINAPI
winapi
WINAPI
winauto
wincolor
windef
@ -2430,6 +2446,7 @@ wixproj
wixtoolset
WIXUI
WKSG
wmain
wmi
WMKEYDOWN
WMKEYUP
@ -2454,6 +2471,7 @@ wox
wparam
wpf
wpr
wprintf
wprp
wregex
WResize
@ -2522,6 +2540,7 @@ Zc
ZEROINIT
zh
ZIndex
zipfolder
zm
zom
zonable

5
.gitmodules vendored
View File

@ -1,11 +1,12 @@
[submodule "deps/spdlog"]
path = deps/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "deps/cxxopts"]
path = deps/cxxopts
url = https://github.com/jarro2783/cxxopts.git
[submodule "deps/expected-lite"]
path = deps/expected-lite
url = https://github.com/martinmoene/expected-lite.git
[submodule "deps/cziplib"]
path = deps/cziplib
url = https://github.com/kuba--/zip.git

View File

@ -36,6 +36,25 @@ steps:
msbuildArgs: ${{ parameters.additionalBuildArguments }}
maximumCpuCount: true
- task: NuGetCommand@2
displayName: Restore NuGet packages for BugReportTool.sln
inputs:
command: restore
feedsToUse: config
configPath: NuGet.config
restoreSolution: src\bug-report\BugReportTool\BugReportTool.sln
restoreDirectory: '$(Build.SourcesDirectory)\src\bug-report\BugReportTool\packages'
- task: VSBuild@1
displayName: 'Build BugReportTool.sln'
inputs:
solution: '**\BugReportTool.sln'
vsVersion: 16.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
maximumCpuCount: true
- task: NuGetCommand@2
displayName: Restore NuGet packages for PowerToysSetup.sln
inputs:

View File

@ -236,4 +236,31 @@ FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
### zip
**Source**: https://github.com/kuba--/zip
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

1
deps/cziplib vendored Submodule

@ -0,0 +1 @@
Subproject commit f9e0959eb212262aff67e8425aceb62d7a518f62

View File

@ -12,7 +12,9 @@
<?define RepoDir="$(var.ProjectDir)..\..\" ?>
<?define BinX64Dir="$(var.RepoDir)x64\$(var.Configuration)\" ?>
<Product Id="*"
<?define BugReportToolDir="$(var.RepoDir)src\bug-report\BugReportTool\x64\$(var.Configuration)\" ?>
<Product Id="*"
Name="PowerToys (Preview)"
Language="1033"
Version="$(var.Version)"
@ -46,6 +48,7 @@
<ComponentGroupRef Id="CoreComponents" />
<ComponentGroupRef Id="ResourcesComponents" />
<ComponentGroupRef Id="LauncherComponents" />
<ComponentRef Id="BugReportTool"/>
</Feature>
<SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLFOLDER]" After="CostFinalize" />
@ -205,6 +208,7 @@
<Directory Id="ProgramFiles64Folder">
<Directory Id="INSTALLFOLDER" Name="PowerToys">
<Directory Id="SvgsInstallFolder" Name="svgs"/>
<Directory Id="BugReportToolFolder" Name="BugReportTool"/>
<Directory Id="ModulesInstallFolder" Name="modules">
<Directory Id="ImageResizerInstallFolder" Name="$(var.ImageResizerProjectName)" />
<Directory Id="PowerRenameInstallFolder" Name="$(var.PowerRenameProjectName)"/>
@ -336,6 +340,11 @@
<?endforeach?>
</Component>
</DirectoryRef>
<DirectoryRef Id="BugReportToolFolder" FileSource="$(var.BugReportToolDir)">
<Component Id="BugReportTool" Guid="0F8E3E9F-2E86-4660-A3BF-AE4DD431B93C" Win64="yes">
<File Source="$(var.BugReportToolDir)BugReportTool.exe" />
</Component>
</DirectoryRef>
<DirectoryRef Id="SvgsInstallFolder" FileSource="$(var.BinX64Dir)svgs\">
<Component Id="PowerToysSvgs" Guid="7C4D4EED-9338-423D-992C-DCE02F3E2D35" Win64="yes">
<File Source="$(var.BinX64Dir)svgs\0.svg" />

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30611.23
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BugReportTool", "BugReportTool\BugReportTool.vcxproj", "{99126840-5C30-4E9E-AC6C-E73DDED5C3BD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetttingsAPI", "..\..\common\SettingsAPI\SetttingsAPI.vcxproj", "{6955446D-23F7-4023-9BB3-8657F904AF99}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{99126840-5C30-4E9E-AC6C-E73DDED5C3BD}.Debug|x64.ActiveCfg = Debug|x64
{99126840-5C30-4E9E-AC6C-E73DDED5C3BD}.Debug|x64.Build.0 = Debug|x64
{99126840-5C30-4E9E-AC6C-E73DDED5C3BD}.Release|x64.ActiveCfg = Release|x64
{99126840-5C30-4E9E-AC6C-E73DDED5C3BD}.Release|x64.Build.0 = Release|x64
{6955446D-23F7-4023-9BB3-8657F904AF99}.Debug|x64.ActiveCfg = Debug|x64
{6955446D-23F7-4023-9BB3-8657F904AF99}.Debug|x64.Build.0 = Debug|x64
{6955446D-23F7-4023-9BB3-8657F904AF99}.Release|x64.ActiveCfg = Release|x64
{6955446D-23F7-4023-9BB3-8657F904AF99}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E9F52385-ED21-4F66-9DA4-F4A2749D480D}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{99126840-5c30-4e9e-ac6c-e73dded5c3bd}</ProjectGuid>
<RootNamespace>BugReportTool</RootNamespace>
<ProjectName>BugReportTool</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\deps\cziplib\src\zip.c" />
<ClCompile Include="..\..\..\..\tools\monitor_info_report\report-monitor-info.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="ZipTools\zipfolder.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\SettingsAPI\SetttingsAPI.vcxproj">
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\deps\cziplib\src\miniz.h" />
<ClInclude Include="..\..\..\..\deps\cziplib\src\zip.h" />
<ClInclude Include="..\..\..\..\tools\monitor_info_report\report-monitor-info.h" />
<ClInclude Include="..\..\..\common\utils\json.h" />
<ClInclude Include="ZipTools\zipfolder.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Main.cpp" />
<ClCompile Include="..\..\..\..\deps\cziplib\src\zip.c">
<Filter>ZipTools</Filter>
</ClCompile>
<ClCompile Include="ZipTools\zipfolder.cpp">
<Filter>ZipTools</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\tools\monitor_info_report\report-monitor-info.cpp">
<Filter>MonitorReportTool</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="ZipTools">
<UniqueIdentifier>{3ae1b6aa-4134-47b1-afdf-dfb3b5901dcc}</UniqueIdentifier>
</Filter>
<Filter Include="MonitorReportTool">
<UniqueIdentifier>{83b7e7d9-49b7-4fc8-9853-9dbb8f2c0e76}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\deps\cziplib\src\miniz.h">
<Filter>ZipTools</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\deps\cziplib\src\zip.h">
<Filter>ZipTools</Filter>
</ClInclude>
<ClInclude Include="ZipTools\zipfolder.h">
<Filter>ZipTools</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\utils\json.h" />
<ClInclude Include="..\..\..\..\tools\monitor_info_report\report-monitor-info.h">
<Filter>MonitorReportTool</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,285 @@
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>
#include <Shlobj.h>
#include <winrt/Windows.Data.Json.h>
#include <winrt/Windows.Foundation.Collections.h>
#include "ZipTools/ZipFolder.h"
#include "../../../common/SettingsAPI/settings_helpers.h"
#include "../../../common/utils/json.h"
#include "../../../../tools/monitor_info_report/report-monitor-info.h"
using namespace std;
using namespace std::filesystem;
using namespace winrt::Windows::Data::Json;
map<wstring, vector<wstring>> escapeInfo = {
{ L"FancyZones\\app-zone-history.json", { L"app-zone-history/app-path" } },
{ L"PowerRename\\replace-mru.json", { L"MRUList" } },
{ L"PowerRename\\search-mru.json", { L"MRUList" } },
{ L"FancyZones\\settings.json", { L"properties/fancyzones_excluded_apps" } },
{ L"PowerToys Run\\Settings\\QueryHistory.json", { L"Items" } },
};
vector<wstring> filesToDelete = {
L"PowerToys Run\\Cache\\Image.cache"
};
vector<wstring> getXpathArray(wstring xpath)
{
vector<wstring> result;
wstring cur = L"";
for (auto ch : xpath)
{
if (ch == L'/')
{
result.push_back(cur);
cur = L"";
continue;
}
cur += ch;
}
if (!cur.empty())
{
result.push_back(cur);
}
return result;
}
void hideByXPath(IJsonValue& val, vector<wstring>& xpathArray, int p)
{
if (val.ValueType() == JsonValueType::Array)
{
for (auto it : val.GetArray())
{
hideByXPath(it, xpathArray, p);
}
return;
}
if (p == xpathArray.size() - 1)
{
if (val.ValueType() == JsonValueType::Object)
{
auto obj = val.GetObjectW();
if (obj.HasKey(xpathArray[p]))
{
auto privateDatavalue = JsonValue::CreateStringValue(L"<private_data>");
obj.SetNamedValue(xpathArray[p], privateDatavalue);
}
}
return;
}
if (val.ValueType() == JsonValueType::Object)
{
IJsonValue newVal;
try
{
newVal = val.GetObjectW().GetNamedValue(xpathArray[p]);
}
catch (...)
{
return;
}
hideByXPath(newVal, xpathArray, p + 1);
}
}
void hideForFile(const path& dir, const wstring& relativePath)
{
path jsonPath = dir;
jsonPath.append(relativePath);
auto jObject = json::from_file(jsonPath.wstring());
if (!jObject.has_value())
{
wprintf(L"Can not parse file %s\n", jsonPath.c_str());
return;
}
JsonValue jValue = json::value(jObject.value());
for (auto xpath : escapeInfo[relativePath])
{
vector<wstring> xpathArray = getXpathArray(xpath);
hideByXPath(jValue, xpathArray, 0);
}
json::to_file(jsonPath.wstring(), jObject.value());
}
bool del(wstring path)
{
error_code err;
remove_all(path, err);
if (err.value() != 0)
{
wprintf_s(L"Can not delete %s. Error code: %d", path.c_str(), err.value());
return false;
}
return true;
}
void hideUserPrivateInfo(const filesystem::path& dir)
{
// Replace data in json files
for (auto& it : escapeInfo)
{
hideForFile(dir, it.first);
}
// delete files
for (auto it : filesToDelete)
{
auto path = dir;
path = path.append(it);
del(path);
}
}
string getCurrentDate()
{
time_t now = time(0);
tm localTime;
if (localtime_s(&localTime, &now) != 0)
{
return "";
}
int year = 1900 + localTime.tm_year;
int month = 1 + localTime.tm_mon;
int day = localTime.tm_mday;
return to_string(year) + "-" + to_string(month) + "-" + to_string(day);
}
void reportMonitorInfo(const filesystem::path& tmpDir)
{
auto monitorReportPath = tmpDir;
monitorReportPath.append("monitor-report-info.txt");
try
{
wofstream monitorReport(monitorReportPath);
monitorReport << "GetSystemMetrics = " << GetSystemMetrics(SM_CMONITORS) << '\n';
report(monitorReport);
}
catch (std::exception& ex)
{
printf("Can not report monitor info. %s\n", ex.what());
}
catch (...)
{
printf("Can not report monitor info\n");
}
}
void reportWindowsVersion(const filesystem::path& tmpDir)
{
auto versionReportPath = tmpDir;
versionReportPath = versionReportPath.append("windows-version.txt");
OSVERSIONINFOEXW osInfo;
try
{
NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW);
*(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
if (NULL != RtlGetVersion)
{
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
RtlGetVersion(&osInfo);
}
}
catch (...)
{
printf("Cannot get windows version info\n");
return;
}
try
{
wofstream versionReport(versionReportPath);
versionReport << "MajorVersion: " << osInfo.dwMajorVersion << endl;
versionReport << "MinorVersion: " << osInfo.dwMinorVersion << endl;
versionReport << "BuildNumber: " << osInfo.dwBuildNumber << endl;
}
catch(...)
{
printf("Can not write to %s", versionReportPath.string().c_str());
}
}
int wmain(int argc, wchar_t* argv[], wchar_t*)
{
// Get path to save zip
wstring saveZipPath;
if (argc > 1)
{
saveZipPath = argv[1];
}
else
{
wchar_t buffer[MAX_PATH];
if (SHGetSpecialFolderPath(HWND_DESKTOP, buffer, CSIDL_DESKTOP, FALSE))
{
saveZipPath = buffer;
}
else
{
printf("Can not retrieve a desktop path. Error code: %d", GetLastError());
}
}
auto powerToys = PTSettingsHelper::get_root_save_folder_location();
// Copy to a temp folder
auto tmpDir = temp_directory_path();
tmpDir = tmpDir.append("PowerToys\\");
powerToys = powerToys + L"\\";
if (!del(tmpDir))
{
return 1;
}
try
{
copy(powerToys, tmpDir, copy_options::recursive);
}
catch (...)
{
printf("Copy PowerToys directory failed");
return 1;
}
// Hide sensative information
hideUserPrivateInfo(tmpDir);
// Write monitors info to the temporary folder
reportMonitorInfo(tmpDir);
// Write windows version info to the temporary folder
reportWindowsVersion(tmpDir);
// Zip folder
auto zipPath = path::path(saveZipPath);
zipPath = zipPath.append("PowerToysReport_" + getCurrentDate() + ".zip");
try
{
zipFolder(zipPath, tmpDir);
}
catch (...)
{
printf("Zip folder failed");
return 1;
}
del(tmpDir);
return 0;
}

View File

@ -0,0 +1,28 @@
#include "zipfolder.h"
#include "..\..\..\..\..\deps\cziplib\src\zip.h"
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');
if (!zip)
{
printf("Can not open zip.");
throw -1;
}
using recursive_directory_iterator = std::filesystem::recursive_directory_iterator;
int rootSize = folderPath.wstring().size();
for (const auto& dirEntry : recursive_directory_iterator(folderPath))
{
if (dirEntry.is_regular_file())
{
auto path = dirEntry.path().string();
auto relativePath = path.substr(rootSize, path.size());
zip_entry_open(zip, relativePath.c_str());
zip_entry_fwrite(zip, path.c_str());
zip_entry_close(zip);
}
}
zip_close(zip);
}

View File

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

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
</packages>

View File

@ -12,6 +12,11 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="monitor-report-info.cpp" />
<ClCompile Include="report-monitor-info.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\common\utils\winapi_error.h" />
<ClInclude Include="report-monitor-info.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6A7F9A7C-56B6-9B0D-FFA2-8110EBB8170F}</ProjectGuid>

View File

@ -1,77 +1,10 @@
#include "report-monitor-info.h"
#include <Windows.h>
#include <iostream>
#include <ctime>
#include <fstream>
#include <sstream>
std::wstring last_error()
{
const DWORD error_code = GetLastError();
wchar_t* error_msg;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr,
error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&error_msg),
0,
nullptr);
std::wstring result{ error_msg };
LocalFree(error_msg);
return result;
}
int report(std::wostream& os)
{
auto callback = [](HMONITOR monitor, HDC, RECT*, LPARAM prm) -> BOOL {
std::wostream& os = *(std::wostream*)prm;
MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
if (GetMonitorInfo(monitor, &mi))
{
os << "GetMonitorInfo OK\n";
DISPLAY_DEVICE displayDevice = { sizeof(displayDevice) };
if (EnumDisplayDevices(mi.szDevice, 0, &displayDevice, 1))
{
if (displayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
{
os << "EnumDisplayDevices OK[MIRRORING_DRIVER]: \n"
<< "\tDeviceID = " << displayDevice.DeviceID << '\n'
<< "\tDeviceKey = " << displayDevice.DeviceKey << '\n'
<< "\tDeviceName = " << displayDevice.DeviceName << '\n'
<< "\tDeviceString = " << displayDevice.DeviceString << '\n';
}
else
{
os << "EnumDisplayDevices OK:\n"
<< "\tDeviceID = " << displayDevice.DeviceID << '\n'
<< "\tDeviceKey = " << displayDevice.DeviceKey << '\n'
<< "\tDeviceName = " << displayDevice.DeviceName << '\n'
<< "\tDeviceString = " << displayDevice.DeviceString << '\n';
}
}
else
{
os << "EnumDisplayDevices FAILED: " << last_error() << '\n';
}
}
else
{
os << "GetMonitorInfo FAILED: " << last_error() << '\n';
}
return TRUE;
};
if (EnumDisplayMonitors(nullptr, nullptr, callback, (LPARAM)&os))
{
os << "EnumDisplayMonitors OK\n";
}
else
{
os << "EnumDisplayMonitors FAILED: " << last_error() << '\n';
}
return 0;
}
#include "../../src/common/utils/winapi_error.h"
int main()
{
@ -98,7 +31,8 @@ int main()
}
catch (...)
{
oss << "unknown exception: " << last_error() << '\n';
auto message = get_last_error_message(GetLastError());
oss << "unknown exception: " << (message.has_value() ? message.value() : L"") << '\n';
}
of << oss.str();
std::wcout << oss.str() << '\n';

View File

@ -0,0 +1,60 @@
#pragma once
#include "report-monitor-info.h"
#include <Windows.h>
#include "../../src/common/utils/winapi_error.h"
int report(std::wostream& os)
{
auto callback = [](HMONITOR monitor, HDC, RECT*, LPARAM prm) -> BOOL {
std::wostream& os = *(std::wostream*)prm;
MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
if (GetMonitorInfo(monitor, &mi))
{
os << "GetMonitorInfo OK\n";
DISPLAY_DEVICE displayDevice = { sizeof(displayDevice) };
if (EnumDisplayDevices(mi.szDevice, 0, &displayDevice, 1))
{
if (displayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
{
os << "EnumDisplayDevices OK[MIRRORING_DRIVER]: \n"
<< "\tDeviceID = " << displayDevice.DeviceID << '\n'
<< "\tDeviceKey = " << displayDevice.DeviceKey << '\n'
<< "\tDeviceName = " << displayDevice.DeviceName << '\n'
<< "\tDeviceString = " << displayDevice.DeviceString << '\n';
}
else
{
os << "EnumDisplayDevices OK:\n"
<< "\tDeviceID = " << displayDevice.DeviceID << '\n'
<< "\tDeviceKey = " << displayDevice.DeviceKey << '\n'
<< "\tDeviceName = " << displayDevice.DeviceName << '\n'
<< "\tDeviceString = " << displayDevice.DeviceString << '\n';
}
}
else
{
auto message = get_last_error_message(GetLastError());
os << "EnumDisplayDevices FAILED: " << (message.has_value() ? message.value() : L"") << '\n';
}
}
else
{
auto message = get_last_error_message(GetLastError());
os << "GetMonitorInfo FAILED: " << (message.has_value() ? message.value() : L"") << '\n';
}
return TRUE;
};
if (EnumDisplayMonitors(nullptr, nullptr, callback, (LPARAM)&os))
{
os << "EnumDisplayMonitors OK\n";
}
else
{
auto message = get_last_error_message(GetLastError());
os << "EnumDisplayMonitors FAILED: " << (message.has_value() ? message.value() : L"") << '\n';
}
return 0;
}

View File

@ -0,0 +1,4 @@
#pragma once
#include <fstream>
int report(std::wostream& os);