Changed how UWP packages are enumerated to resolve missing packages from previous registry method.

pull/89/head
John Simpson 5 years ago
parent 3cf635498b
commit 3cd92e0584

@ -1,12 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29009.5
VisualStudioVersion = 16.0.29418.71
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SteamTarget", "SteamTarget\SteamTarget.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GloSC", "GloSC\GloSC.vcxproj", "{2E7F8131-0BD8-475D-B16F-20445CCF2D16}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EnforceBindingDLL", "EnforceBindingDLL\EnforceBindingDLL.vcxproj", "{AFA0047E-7DEE-472A-AF4B-436A30459905}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GloSC_Watchdog", "GloSC_Watchdog\GloSC_Watchdog.vcxproj", "{752D3933-73A3-45E4-B139-CCB8C04BE543}"
@ -16,6 +12,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
GloSC_install_script.iss = GloSC_install_script.iss
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GloSC", "GloSC\GloSC.vcxproj", "{2E7F8131-0BD8-475D-B16F-20445CCF2D16}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SteamTarget", "SteamTarget\SteamTarget.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -24,24 +24,8 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.ActiveCfg = Debug|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.Build.0 = Debug|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.ActiveCfg = Release|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.Build.0 = Release|Win32
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Debug|x64.ActiveCfg = Debug|x64
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Debug|x64.Build.0 = Debug|x64
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Debug|x86.ActiveCfg = Debug|Win32
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Debug|x86.Build.0 = Debug|Win32
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Release|x64.ActiveCfg = Release|x64
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Release|x64.Build.0 = Release|x64
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Release|x86.ActiveCfg = Release|Win32
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Release|x86.Build.0 = Release|Win32
{AFA0047E-7DEE-472A-AF4B-436A30459905}.Debug|x64.ActiveCfg = Debug|x64
{AFA0047E-7DEE-472A-AF4B-436A30459905}.Debug|x64.Build.0 = Debug|x64
{AFA0047E-7DEE-472A-AF4B-436A30459905}.Debug|x64.ActiveCfg = Debug|Win32
{AFA0047E-7DEE-472A-AF4B-436A30459905}.Debug|x64.Build.0 = Debug|Win32
{AFA0047E-7DEE-472A-AF4B-436A30459905}.Debug|x86.ActiveCfg = Debug|Win32
{AFA0047E-7DEE-472A-AF4B-436A30459905}.Debug|x86.Build.0 = Debug|Win32
{AFA0047E-7DEE-472A-AF4B-436A30459905}.Release|x64.ActiveCfg = Release|Win32
@ -56,6 +40,22 @@ Global
{752D3933-73A3-45E4-B139-CCB8C04BE543}.Release|x64.Build.0 = Release|x64
{752D3933-73A3-45E4-B139-CCB8C04BE543}.Release|x86.ActiveCfg = Release|Win32
{752D3933-73A3-45E4-B139-CCB8C04BE543}.Release|x86.Build.0 = Release|Win32
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Debug|x64.ActiveCfg = Debug|x64
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Debug|x64.Build.0 = Debug|x64
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Debug|x86.ActiveCfg = Debug|Win32
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Debug|x86.Build.0 = Debug|Win32
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Release|x64.ActiveCfg = Release|x64
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Release|x64.Build.0 = Release|x64
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Release|x86.ActiveCfg = Release|Win32
{2E7F8131-0BD8-475D-B16F-20445CCF2D16}.Release|x86.Build.0 = Release|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.ActiveCfg = Debug|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.Build.0 = Debug|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.ActiveCfg = Release|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -16,6 +16,17 @@ limitations under the License.
#include "GloSC.h"
#include <memory>
#include "UpdateChecker.h"
#include <collection.h>
#include <appmodel.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <windows.h>
#include <appxpackaging.h>
#pragma comment(lib, "Shlwapi.lib")
using namespace Windows::Management::Deployment;
using namespace Windows::Foundation::Collections;
GloSC::GloSC(QWidget *parent)
: QMainWindow(parent), updater_(this)
@ -508,139 +519,206 @@ void GloSC::on_pbSearchPath_clicked()
void GloSC::on_pbUWP_clicked()
{
auto settings = std::make_unique<QSettings>(R"(HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Launch\PackageId)", QSettings::NativeFormat);
QStringList childs = settings->childGroups();
QStringList packages;
for (auto& child : childs)
{
packages << child;
}
PackageManager^ packageManager = ref new PackageManager();
IIterable<Windows::ApplicationModel::Package^>^ packages = packageManager->FindPackages();
int packageCount = 0;
// Only way to get the count of packages is to iterate through the whole collection first
std::for_each(Windows::Foundation::Collections::begin(packages), Windows::Foundation::Collections::end(packages),
[&](Windows::ApplicationModel::Package^ package)
{
packageCount += 1;
});
QProgressDialog progDialog("Searching for UWP apps...", "Cancel", 0, packages.size(), this);
QProgressDialog progDialog("Searching for UWP apps...", "Cancel", 0, packageCount, this);
progDialog.setWindowModality(Qt::WindowModal);
// Without this the progress dialog doesn't update in the lambda function.
progDialog.show();
QApplication::processEvents();
QList<UWPPair> pairs;
QStringList AppNames;
QStringList AppUMIds;
for (auto &package : packages)
{
progDialog.setValue(packages.indexOf(package));
if (progDialog.wasCanceled())
int currPackage = 0;
// Iterate through all the packages
std::for_each(Windows::Foundation::Collections::begin(packages), Windows::Foundation::Collections::end(packages),
[&](Windows::ApplicationModel::Package^ package)
{
return;
}
settings = std::make_unique<QSettings>(R"(HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Launch\PackageId\)" + package, QSettings::NativeFormat);
progDialog.setValue(currPackage);
progDialog.update();
for (auto& child : settings->childGroups())
{
if (child == "ActivatableClassId")
if (progDialog.wasCanceled())
{
const auto classIDSettings = std::make_unique<QSettings>(
R"(HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Launch\PackageId\)" + package + "\\" + child,
QSettings::NativeFormat);
if (classIDSettings->childGroups().length() > 0)
{
QString pkgNameCleaned = package.mid(0, package.indexOf("_"));
QStringList tmp = package.split("__");
if (tmp.size() > 1)
{
pkgNameCleaned += "_" + tmp.at(1);
} else {
pkgNameCleaned += package.mid(package.lastIndexOf("_"), package.size()-1);
}
QString AppUMId = pkgNameCleaned + "!" + classIDSettings->childGroups().at(0);
const auto appInfoSettings = std::make_unique<QSettings>(
R"(HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Launch\PackageId\)"
+ package + "\\" + child + "\\" + classIDSettings->childGroups().at(0),
QSettings::NativeFormat);
return;
}
HRESULT hr = S_OK;
IStream* inputStream = NULL;
UINT32 pathLen = 0;
IAppxManifestReader* manifestReader = NULL;
IAppxFactory* appxFactory = NULL;
LPWSTR appId = NULL;
LPWSTR manifestAppName = NULL;
// Get the package path on disk so we can load the manifest XML and get the PRAID
GetPackagePathByFullName(package->Id->FullName->Data(), &pathLen, NULL);
if (pathLen > 0) {
// Length of the path + "\\AppxManifest.xml" that we'll be appending
UINT32 manifestLen = pathLen + 20;
PWSTR pathBuf = (PWSTR)malloc(manifestLen * sizeof(wchar_t));
GetPackagePathByFullName(package->Id->FullName->Data(), &pathLen, pathBuf);
PWSTR manifest_xml = L"\\AppxManifest.xml";
hr = StringCchCatW(pathBuf, manifestLen, manifest_xml);
// Let's ignore a bunch of built in apps and such
if (wcsstr(pathBuf, L"SystemApps")) {
hr = E_FAIL;
}
else if (wcsstr(pathBuf, L".NET.Native."))
hr = E_FAIL;
else if (wcsstr(pathBuf, L".VCLibs."))
hr = E_FAIL;
else if (wcsstr(pathBuf, L"Microsoft.UI"))
hr = E_FAIL;
else if (wcsstr(pathBuf, L"Microsoft.Advertising"))
hr = E_FAIL;
else if (wcsstr(pathBuf, L"Microsoft.Services.Store"))
hr = E_FAIL;
BOOL hasCurrent = FALSE;
// Open the manifest XML
if (SUCCEEDED(hr)) {
hr = SHCreateStreamOnFileEx(
pathBuf,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0, // default file attributes
FALSE, // do not create new file
NULL, // no template
&inputStream);
}
if (SUCCEEDED(hr)) {
hr = CoCreateInstance(
__uuidof(AppxFactory),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IAppxFactory),
(LPVOID*)(&appxFactory));
}
if (SUCCEEDED(hr)) {
hr = appxFactory->CreateManifestReader(inputStream, &manifestReader);
}
QString AppName = appInfoSettings->value("DisplayName").toString();
// Grab application ID (PRAID) and DisplayName from the XML
if (SUCCEEDED(hr)) {
IAppxManifestApplicationsEnumerator* applications = NULL;
manifestReader->GetApplications(&applications);
if (SUCCEEDED(hr)) {
hr = applications->GetHasCurrent(&hasCurrent);
if (hasCurrent) {
IAppxManifestApplication* application = NULL;
hr = applications->GetCurrent(&application);
if (SUCCEEDED(hr)) {
application->GetStringValue(L"Id", &appId);
application->GetStringValue(L"DisplayName", &manifestAppName);
application->Release();
}
}
else {
hr = S_FALSE;
}
applications->Release();
}
manifestReader->Release();
inputStream->Release();
}
if (!AppNames.contains(AppName) && !AppUMIds.contains(AppUMId) && AppUMId.size() > 0)
if (SUCCEEDED(hr)) {
PWSTR appNameBuf;
QString AppUMId = QString::fromWCharArray(package->Id->FamilyName->Data());
QString AppName;
if (manifestAppName != NULL)
{
if (AppName.size() != 0)
AppNames << AppName;
AppUMIds << AppUMId;
if (AppName.size() == 0)
// If the display name is an indirect string, we'll try and load it using SHLoadIndirectString
if (wcsstr(manifestAppName, L"ms-resource:"))
{
AppName = "Unknown";
}
else if (AppName.at(0) == '@') {
QString packageName = AppName.mid(AppName.indexOf('{') + 1, AppName.size() - 1);
packageName = packageName.mid(0, packageName.indexOf('?'));
QSettings settings("HKEY_CLASSES_ROOT\\Local Settings\\MrtCache", QSettings::NativeFormat);
QStringList cachedNameChildGroups = settings.childGroups();
for (auto &childGroup : cachedNameChildGroups)
{
if (childGroup.contains(packageName))
{
QSettings settings(R"(HKEY_CLASSES_ROOT\Local Settings\MrtCache\)" + childGroup, QSettings::NativeFormat);
QStringList allKeys = settings.allKeys();
AppName.replace("/", "\\");
for (auto &key : allKeys)
{
if (key.contains(AppName))
{
AppName = settings.value(key).toString();
break;
}
}
break;
PWSTR res_name = wcsdup(&manifestAppName[12]);
appNameBuf = (PWSTR)malloc(1026);
LPCWSTR resource_str = L"@{";
std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/resources/" + res_name + L"}";
PCWSTR res_str = reslookup.c_str();
hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
// Try several resource paths
if (!SUCCEEDED(hr)) {
std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/Resources/" + res_name + L"}";
PCWSTR res_str = reslookup.c_str();
hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
// If the third one doesn't work, we give up and use the package name from PackageManager
if (!SUCCEEDED(hr)) {
std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/" + res_name + L"}";
PCWSTR res_str = reslookup.c_str();
hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
}
}
if (AppName.at(0) == '@') {
AppName = "Unknown";
QString PRAID = QString::fromWCharArray(appId);
CoTaskMemFree(appId);
if (!PRAID.isEmpty()) {
AppUMId = AppUMId.append("!");
AppUMId = AppUMId.append(PRAID);
}
if (!SUCCEEDED(hr))
AppName = QString::fromWCharArray(package->Id->Name->Data());
else
AppName = QString::fromWCharArray(appNameBuf);
free(appNameBuf);
}
else
{
appNameBuf = manifestAppName;
AppName = QString::fromWCharArray(appNameBuf);
const UWPPair uwpPair = {
AppName,
AppUMId,
};
pairs.push_back(uwpPair);
}
}
else {
AppName = QString::fromWCharArray(package->Id->Name->Data());
}
const UWPPair uwpPair = {
AppName,
AppUMId,
};
free(pathBuf);
break;
pairs.push_back(uwpPair);
}
break;
}
}
currPackage += 1;
});
}
uwp_pairs_ = pairs;
progDialog.close();
UWPSelectDialog dialog(this);
dialog.setUWPList(uwp_pairs_);
int selection = dialog.exec();
if (selection > -1)
{

@ -21,7 +21,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{2E7F8131-0BD8-475D-B16F-20445CCF2D16}</ProjectGuid>
<Keyword>Qt4VSv1.0</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@ -65,6 +65,8 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<AdditionalUsingDirectories>C:\Program Files %28x86%29\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.FoundationContract\3.0.0.0;C:\Program Files %28x86%29\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0;C:\Program Files %28x86%29\Windows Kits\10\UnionMetadata\10.0.18362.0;C:\Program Files %28x86%29\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\vcpackages;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<CompileAsWinRT>true</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -83,6 +85,8 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<CompileAsWinRT>true</CompileAsWinRT>
<AdditionalUsingDirectories>C:\Program Files %28x86%29\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.FoundationContract\3.0.0.0;C:\Program Files %28x86%29\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0;C:\Program Files %28x86%29\Windows Kits\10\UnionMetadata\10.0.18362.0;C:\Program Files %28x86%29\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\vcpackages;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -100,6 +104,8 @@
<DebugInformationFormat />
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<AdditionalUsingDirectories>C:\Program Files %28x86%29\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.FoundationContract\3.0.0.0;C:\Program Files %28x86%29\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0;C:\Program Files %28x86%29\Windows Kits\10\UnionMetadata\10.0.18362.0;C:\Program Files %28x86%29\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\vcpackages;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<CompileAsWinRT>true</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -118,6 +124,8 @@
</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<CompileAsWinRT>true</CompileAsWinRT>
<AdditionalUsingDirectories>C:\Program Files %28x86%29\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.FoundationContract\3.0.0.0;C:\Program Files %28x86%29\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0;C:\Program Files %28x86%29\Windows Kits\10\UnionMetadata\10.0.18362.0;C:\Program Files %28x86%29\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\vcpackages;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -301,7 +309,7 @@
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties MocDir=".\GeneratedFiles\$(ConfigurationName)" UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" lupdateOptions="" lupdateOnBuild="0" lreleaseOptions="" Qt5Version_x0020_Win32="$(DefaultQtVersion)" Qt5Version_x0020_x64="5.10.1_x64" MocOptions="" />
<UserProperties MocDir=".\GeneratedFiles\$(ConfigurationName)" UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" lupdateOptions="" lupdateOnBuild="0" lreleaseOptions="" Qt5Version_x0020_Win32="msvc2017" Qt5Version_x0020_x64="msvc2017_64" MocOptions="" />
</VisualStudio>
</ProjectExtensions>
</Project>
Loading…
Cancel
Save