From b57ac4125fb187ab41255aa7311d7e5728b5d78c Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 23 Jun 2025 12:17:10 -0700 Subject: [PATCH 01/33] GetPackageFile() --- .../TerminalVelocityFeatures-PackageRuntime.h | 32 ++++++ ...erminalVelocityFeatures-PackageRuntime.xml | 20 ++++ .../API/appmodel_msixdynamicdependency.h | 15 ++- dev/Package/M.W.A.Package.cpp | 26 +++++ dev/Package/M.W.A.Package.h | 20 ++++ dev/Package/Package.idl | 16 +++ dev/Package/Package.vcxitems | 31 +++++ dev/Package/Package.vcxitems.filters | 38 +++++++ dev/Package/PackageRuntime.cpp | 106 ++++++++++++++++++ dev/Package/PackageRuntime.h | 28 +++++ dev/Package/PackageTelemetry.h | 30 +++++ dev/Package/pch.h | 29 +++++ .../WindowsAppRuntime.def | 2 + .../WindowsAppRuntime_DLL.vcxproj | 1 + 14 files changed, 389 insertions(+), 5 deletions(-) create mode 100644 dev/Common/TerminalVelocityFeatures-PackageRuntime.h create mode 100644 dev/Common/TerminalVelocityFeatures-PackageRuntime.xml create mode 100644 dev/Package/M.W.A.Package.cpp create mode 100644 dev/Package/M.W.A.Package.h create mode 100644 dev/Package/Package.idl create mode 100644 dev/Package/Package.vcxitems create mode 100644 dev/Package/Package.vcxitems.filters create mode 100644 dev/Package/PackageRuntime.cpp create mode 100644 dev/Package/PackageRuntime.h create mode 100644 dev/Package/PackageTelemetry.h create mode 100644 dev/Package/pch.h diff --git a/dev/Common/TerminalVelocityFeatures-PackageRuntime.h b/dev/Common/TerminalVelocityFeatures-PackageRuntime.h new file mode 100644 index 0000000000..4fd99a2151 --- /dev/null +++ b/dev/Common/TerminalVelocityFeatures-PackageRuntime.h @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT IT + +// INPUT FILE: dev\Common\TerminalVelocityFeatures-PackageRuntime.xml +// OPTIONS: -Channel Experimental -Language C++ -Namespace Microsoft.Windows.ApplicationModel -Path dev\Common\TerminalVelocityFeatures-PackageRuntime.xml -Output dev\Common\TerminalVelocityFeatures-PackageRuntime.h + +#if defined(__midlrt) +namespace features +{ + feature_name Feature_PackageRuntime = { DisabledByDefault, FALSE }; +} +#endif // defined(__midlrt) + +// Feature constants +#define WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_FEATURE_PACKAGERUNTIME_ENABLED 1 + +#if defined(__cplusplus) + +namespace Microsoft::Windows::ApplicationModel +{ + +__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_FEATURE_PACKAGERUNTIME_ENABLED_mismatch", "AlwaysEnabled")) +struct Feature_PackageRuntime +{ + static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_FEATURE_PACKAGERUNTIME_ENABLED == 1; } +}; + +} // namespace Microsoft.Windows.ApplicationModel + +#endif // defined(__cplusplus) diff --git a/dev/Common/TerminalVelocityFeatures-PackageRuntime.xml b/dev/Common/TerminalVelocityFeatures-PackageRuntime.xml new file mode 100644 index 0000000000..2d1fa1c612 --- /dev/null +++ b/dev/Common/TerminalVelocityFeatures-PackageRuntime.xml @@ -0,0 +1,20 @@ + + + + + + + + + + Feature_PackageRuntime + Package Runtime APIs + AlwaysEnabled + + Preview + Stable + + + diff --git a/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h b/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h index 9ca7bee67e..7e472052e4 100644 --- a/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h +++ b/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h @@ -37,16 +37,16 @@ extern "C" HRESULT WINAPI GetCurrentPackageInfo3( // Modern variants of appmodel.h namespace appmodel { -inline std::wstring GetPackagePath(PCWSTR packageFullName) +inline std::wstring GetPackagePath(PCWSTR packageFullName, PackagePathType packagePathType) { // Paths can be long but typically short(ish). We can use a quick fixed buffer // as an optimization and fallback to dynamic allocation if need be - WCHAR path[MAX_PATH]; + WCHAR path[MAX_PATH]{}; UINT32 pathLength{ ARRAYSIZE(path) }; - const auto rc{ ::GetPackagePathByFullName(packageFullName, &pathLength, path) }; + const auto rc{ ::GetPackagePathByFullName2(packageFullName, packageInfoType, &pathLength, path) }; if (rc == ERROR_SUCCESS) { - return std::wstring(path); + return std::wstring{ path }; } else if (rc != ERROR_INSUFFICIENT_BUFFER) { @@ -56,7 +56,12 @@ inline std::wstring GetPackagePath(PCWSTR packageFullName) // It's bigger than a breadbox. Allocate memory std::unique_ptr pathBuffer{ std::make_unique(pathLength) }; THROW_IF_NULL_ALLOC(pathBuffer); - THROW_IF_WIN32_ERROR(::GetPackagePathByFullName(packageFullName, &pathLength, pathBuffer.get())); + THROW_IF_WIN32_ERROR(::GetPackagePathByFullName2(packageFullName, packageInfoType, &pathLength, pathBuffer.get())); return std::wstring(pathBuffer.get()); } + +inline std::wstring GetPackagePath(PCWSTR packageFullName) +{ + return GetPackagePath(packageFullName, PackagePathType_Install); +} } diff --git a/dev/Package/M.W.A.Package.cpp b/dev/Package/M.W.A.Package.cpp new file mode 100644 index 0000000000..9b507c1146 --- /dev/null +++ b/dev/Package/M.W.A.Package.cpp @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "M.W.S.Package.h" +#include "Microsoft.Windows.ApplicationModel.Package.g.cpp" + +#include "PackageRuntime.h" + +#include "PackageTelemetry.h" + +namespace winrt::Microsoft::Windows::ApplicationModel::implementation +{ + winrt::hstring Package::FindPackageFile(winrt::hstring const& PackageFullName, winrt::hstring const& filename) + { + wil::unique_process_heap_ptr packageFile; + THROW_IF_FAILED_MSG(::FindPackageFile(packageFullName.c_str(), filename.c_str(), wil::out_param(packageFile)); + "PackageFullName=%ls Filename=%s", packageFullName, filename); + if (!packageFile) + { + return winrt::hstring{}; + } + return winrt::hstring{ packageFile.get() }; + } +} diff --git a/dev/Package/M.W.A.Package.h b/dev/Package/M.W.A.Package.h new file mode 100644 index 0000000000..bcec073410 --- /dev/null +++ b/dev/Package/M.W.A.Package.h @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#pragma once + +#include "Microsoft.Windows.ApplicationModel.Package.g.h" + +namespace winrt::Microsoft::Windows::ApplicationModel::implementation +{ + struct Package : PackageT + { + static winrt::hstring FindPackageFile(winrt::hstring const& PackageFullName, winrt::hstring const& filename); + }; +} +namespace winrt::Microsoft::Windows::ApplicationModel::factory_implementation +{ + struct Package : PackageT + { + }; +} diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl new file mode 100644 index 0000000000..2c77adda35 --- /dev/null +++ b/dev/Package/Package.idl @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include + +namespace Microsoft.Windows.ApplicationModel +{ + [contractversion(1)] + apicontract PackageRuntimeContract{}; + + [contract(PackageRuntimeContract, 1)] + runtimeclass Package + { + static String FindPackageFile(String PackageFullName, String filename); + }; +} diff --git a/dev/Package/Package.vcxitems b/dev/Package/Package.vcxitems new file mode 100644 index 0000000000..c57d1a7e5a --- /dev/null +++ b/dev/Package/Package.vcxitems @@ -0,0 +1,31 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + {7cf52890-56fa-47e2-84fb-68ee274324b6} + + + + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/Package/Package.vcxitems.filters b/dev/Package/Package.vcxitems.filters new file mode 100644 index 0000000000..7b0ae98dc5 --- /dev/null +++ b/dev/Package/Package.vcxitems.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + diff --git a/dev/Package/PackageRuntime.cpp b/dev/Package/PackageRuntime.cpp new file mode 100644 index 0000000000..52c664b4a6 --- /dev/null +++ b/dev/Package/PackageRuntime.cpp @@ -0,0 +1,106 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageRuntime.h" + + +namespace appmodel +{ +inline std::wstring get_package_path(PCWSTR packageFullName, PackagePathType packagePathType) +{ + // Paths can be long but typically short(ish). We can use a quick fixed buffer + // as an optimization and fallback to dynamic allocation if need be + WCHAR path[MAX_PATH]{}; + uint32_t pathLength{ ARRAYSIZE(path) }; + const auto rc{ ::GetPackagePathByFullName2(packageFullName, packageInfoType, &pathLength, path) }; + if (rc == ERROR_SUCCESS) + { + return path; + } + else if (rc == ERROR_NOT_FOUND) + { + return std::wstring{}; + } + else if (rc != ERROR_INSUFFICIENT_BUFFER) + { + THROW_WIN32(rc); + } + + // It's bigger than a breadbox. Allocate memory + std::unique_ptr pathBuffer{ std::make_unique(pathLength) }; + THROW_IF_WIN32_ERROR_MSG(::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, pathBuffer.get()), + "PackageFullName=%ls PackagePathType=%d", packageFullName ? packageFullName : L"", static_cast(packagePathType)); + return std::wstring{ pathBuffer.get() }; +} + +inline std::wstring get_package_path(PCWSTR packageFullName) +{ + return get_package_path(packageFullName, PackagePathType_Install); +} + +inline std::filesystem::path get_package_file( + PCWSTR packageFullName, + PCWSTR filename, + PackagePathType packagePathType) +{ + std::filesystem::path absoluteFilename; + + auto packagePath{ appmodel::get_package_path(packageFullName, packagePathType) }; + if (!path.empty()) + { + absoluteFilename = packagePath; + absoluteFilename /= filename; + if (std::filesystem::exists(absoluteFilename)) + { + return absoluteFilename; + } + } + return std::filesystem::path{}; +} + +inline std::filesystem::path get_package_file( + PCWSTR packageFullName, + PCWSTR filename) +{ + auto path{ get_package_file(packageFullName, filename, PackagePathType_External) }; + if (path.empty()) + { + path = get_package_file(packageFullName, filename, PackagePathType_Mutable); + if (path.empty()) + { + path = get_package_file(packageFullName, filename, PackagePathType_Install); + } + } + return path; +} +} + +STDAPI FindPackageFile( + PCWSTR packageFullName, + PCWSTR filename, + _Outptr_result_maybenull_ PWSTR* packageFile) noexcept try +{ + *packageFile = nullptr; + + RETURN_HR_IF(E_INVALIDARG, !filename || (filename[0] == L'\0')); + + // If packageFullName = NULL or "" use the caller's package identity + WCHAR packageFullNameBuffer[PACKAGE_FULL_NAME_MAX_LENGTH + 1]{}; + if (!packageFullName || (packageFullName[0] == L'\0')) + { + uint32_t packageFullNameBufferLength{ ARRAYSIZE(packageFullNameBuffer) }; + THROW_IF_FAILED(::GetCurrentPackageFullName(&packageFullNameBufferLength, packageFullNameBuffer)); + packageFullName = packageFullNameBuffer; + } + + auto path{ appmodel::get_package_file(packageFullName, filename) }; + if (!path.empty()) + { + auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) }; + *packageFile = absoluteFilename.release(); + } + return S_OK; +} +CATCH_RETURN(); diff --git a/dev/Package/PackageRuntime.h b/dev/Package/PackageRuntime.h new file mode 100644 index 0000000000..5a3a8a569b --- /dev/null +++ b/dev/Package/PackageRuntime.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#if !defined(PACKAGERUNTIME_H) +#define PACKAGERUNTIME_H + +#include + +#include + +#if defined(__cplusplus) + +/// Return the absolute path to the packaged file. +/// @param packageFullName the package, or NULL or "" to use the current process' package identity. +/// @param filename file to locate. +/// @param packageFile absolute path to the packaged file, or NULL if not found. Allocated via HeapAlloc; use HeapFree to deallocate +/// @note The package path search order is External(User or Machine) -> Mutable -> Install. +/// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 +STDAPI FindPackageFile( + PCWSTR packageFullName, + PCWSTR filename, + _Outptr_result_maybenull_ PWSTR* packageFile) noexcept; + +#endif // defined(__cplusplus) + +#endif // PACKAGERUNTIME_H + diff --git a/dev/Package/PackageTelemetry.h b/dev/Package/PackageTelemetry.h new file mode 100644 index 0000000000..6d1c8cab58 --- /dev/null +++ b/dev/Package/PackageTelemetry.h @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT license. + +#pragma once + +#include + +DECLARE_TRACELOGGING_CLASS(PackageTelemetryProvider, + "Microsoft.WindowsAppSDK.Package", + // {95308938-292a-46ea-9ea4-4d729ab287a6} + (0x95308938, 0x292a, 0x46ea, 0x9e, 0xa4, 0x4d, 0x72, 0x9a, 0xb2, 0x87, 0xa6)); + +class PackageTelemetry : public wil::TraceLoggingProvider +{ + IMPLEMENT_TELEMETRY_CLASS(PackageTelemetry, PackageTelemetryProvider); + +public: + + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(FindPackageFile, PDT_ProductAndServicePerformance); + DEFINE_ACTIVITY_START(winrt::hstring const& packageFullName, winrt::hstring const& filename) noexcept try + { + TraceLoggingClassWriteStart( + FindPackageFile, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingWideString(packageFullName.c_str(), "PackageFullName"), + TraceLoggingWideString(filename.c_str(), "Filename")); + } + CATCH_LOG() + END_ACTIVITY_CLASS(); +}; diff --git a/dev/Package/pch.h b/dev/Package/pch.h new file mode 100644 index 0000000000..ec56d476e4 --- /dev/null +++ b/dev/Package/pch.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#pragma once + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def index c487bfd388..5d4f1b212c 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def @@ -29,3 +29,5 @@ EXPORTS WindowsAppRuntime_VersionInfo_TestInitialize WindowsAppRuntime_EnsureIsLoaded + + FindPackageFile diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj index a0b5a2c924..0b7918be73 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj @@ -107,6 +107,7 @@ + From 10643e938e6d3ad97ea646fc738dab2f72ed4fc4 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 28 Jun 2025 22:28:03 -0700 Subject: [PATCH 02/33] Fix bugs. Add start of tests --- WindowsAppRuntime.sln | 32 ++++ .../API/appmodel_msixdynamicdependency.h | 4 +- dev/Interop/StoragePickers/FileOpenPicker.cpp | 4 +- dev/Package/M.W.A.Package.cpp | 8 +- dev/Package/M.W.A.Package.h | 6 +- dev/Package/Package.idl | 2 +- dev/Package/Package.vcxitems | 3 +- dev/Package/Package.vcxitems.filters | 6 +- dev/Package/PackageRuntime.cpp | 16 +- dev/Package/PackageRuntime.h | 9 - dev/Package/pch.h | 1 + dev/WindowsAppRuntime_DLL/pch.h | 1 + test/Package/API/PackageTests.cpp | 82 +++++++++ test/Package/API/PackageTests.vcxproj | 164 ++++++++++++++++++ test/Package/API/PackageTests.vcxproj.filters | 33 ++++ test/Package/API/Test.testdef | 11 ++ test/Package/API/Test.testdef.bak | 11 ++ test/Package/API/packages.config | 9 + test/Package/API/pch.cpp | 6 + test/Package/API/pch.h | 35 ++++ 20 files changed, 408 insertions(+), 35 deletions(-) create mode 100644 test/Package/API/PackageTests.cpp create mode 100644 test/Package/API/PackageTests.vcxproj create mode 100644 test/Package/API/PackageTests.vcxproj.filters create mode 100644 test/Package/API/Test.testdef create mode 100644 test/Package/API/Test.testdef.bak create mode 100644 test/Package/API/packages.config create mode 100644 test/Package/API/pch.cpp create mode 100644 test/Package/API/pch.h diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 67f018180c..21b1627c7f 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -732,6 +732,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Decimal", "dev\Decimal\Deci EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ABForwardTests", "test\ABForward\ABForward.vcxproj", "{C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{8479133D-5FF8-486B-B978-3A14D66725F7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package", "dev\Package\Package.vcxitems", "{3D652B4A-AC29-4BA2-A2CA-2ACC08EAD1E9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{9DE31467-8D10-4558-8719-32559E01B32A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API", "API", "{BF763B12-77A9-471D-825B-4AC05E70A804}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageTests", "test\Package\API\PackageTests.vcxproj", "{F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2530,6 +2540,22 @@ Global {C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99}.Release|x64.Build.0 = Release|x64 {C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99}.Release|x86.ActiveCfg = Release|Win32 {C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99}.Release|x86.Build.0 = Release|Win32 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|Any CPU.ActiveCfg = Debug|x64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|Any CPU.Build.0 = Debug|x64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|ARM64.Build.0 = Debug|ARM64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|x64.ActiveCfg = Debug|x64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|x64.Build.0 = Debug|x64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|x86.ActiveCfg = Debug|Win32 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Debug|x86.Build.0 = Debug|Win32 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|Any CPU.ActiveCfg = Release|x64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|Any CPU.Build.0 = Release|x64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|ARM64.ActiveCfg = Release|ARM64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|ARM64.Build.0 = Release|ARM64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|x64.ActiveCfg = Release|x64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|x64.Build.0 = Release|x64 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|x86.ActiveCfg = Release|Win32 + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2753,6 +2779,11 @@ Global {E9C055BB-6AE4-497A-A354-D07841E68976} = {022E355A-AB24-48EE-9CC0-965BEFDF5E8C} {DC453DE3-18FD-43E7-8103-20763C8B97C8} = {5012149E-F09F-4F18-A03C-FFE597203821} {C40AE1D8-FD5F-472E-86B5-DDA5ABA6FF99} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} + {8479133D-5FF8-486B-B978-3A14D66725F7} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A} + {3D652B4A-AC29-4BA2-A2CA-2ACC08EAD1E9} = {8479133D-5FF8-486B-B978-3A14D66725F7} + {9DE31467-8D10-4558-8719-32559E01B32A} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} + {BF763B12-77A9-471D-825B-4AC05E70A804} = {9DE31467-8D10-4558-8719-32559E01B32A} + {F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7} = {BF763B12-77A9-471D-825B-4AC05E70A804} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} @@ -2789,6 +2820,7 @@ Global dev\DynamicDependency\API\DynamicDependency.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 dev\Licensing\Licensing.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 dev\PackageManager\API\PackageManager.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 + dev\Package\Package.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 dev\PowerNotifications\PowerNotifications.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 dev\RuntimeCompatibilityOptions\RuntimeCompatibilityOptions.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 dev\UndockedRegFreeWinRT\UndockedRegFreeWinRT.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 diff --git a/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h b/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h index 7e472052e4..4ef14a71d6 100644 --- a/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h +++ b/dev/DynamicDependency/API/appmodel_msixdynamicdependency.h @@ -43,7 +43,7 @@ inline std::wstring GetPackagePath(PCWSTR packageFullName, PackagePathType packa // as an optimization and fallback to dynamic allocation if need be WCHAR path[MAX_PATH]{}; UINT32 pathLength{ ARRAYSIZE(path) }; - const auto rc{ ::GetPackagePathByFullName2(packageFullName, packageInfoType, &pathLength, path) }; + const auto rc{ ::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, path) }; if (rc == ERROR_SUCCESS) { return std::wstring{ path }; @@ -56,7 +56,7 @@ inline std::wstring GetPackagePath(PCWSTR packageFullName, PackagePathType packa // It's bigger than a breadbox. Allocate memory std::unique_ptr pathBuffer{ std::make_unique(pathLength) }; THROW_IF_NULL_ALLOC(pathBuffer); - THROW_IF_WIN32_ERROR(::GetPackagePathByFullName2(packageFullName, packageInfoType, &pathLength, pathBuffer.get())); + THROW_IF_WIN32_ERROR(::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, pathBuffer.get())); return std::wstring(pathBuffer.get()); } diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index 8a21c0415b..17c93349af 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -91,7 +91,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto dialog = create_instance(CLSID_FileOpenDialog, CLSCTX_INPROC_SERVER); parameters.ConfigureDialog(dialog); - check_hresult(dialog->SetFileTypeIndex(parameters.FileTypeFilterPara.size())); + check_hresult(dialog->SetFileTypeIndex(static_cast(parameters.FileTypeFilterPara.size()))); { auto hr = dialog->Show(parameters.HWnd); @@ -144,7 +144,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto dialog = create_instance(CLSID_FileOpenDialog, CLSCTX_INPROC_SERVER); parameters.ConfigureDialog(dialog); - check_hresult(dialog->SetFileTypeIndex(parameters.FileTypeFilterPara.size())); + check_hresult(dialog->SetFileTypeIndex(static_cast(parameters.FileTypeFilterPara.size()))); FILEOPENDIALOGOPTIONS dialogOptions; check_hresult(dialog->GetOptions(&dialogOptions)); diff --git a/dev/Package/M.W.A.Package.cpp b/dev/Package/M.W.A.Package.cpp index 9b507c1146..da667ecaca 100644 --- a/dev/Package/M.W.A.Package.cpp +++ b/dev/Package/M.W.A.Package.cpp @@ -3,7 +3,7 @@ #include "pch.h" -#include "M.W.S.Package.h" +#include "M.W.A.Package.h" #include "Microsoft.Windows.ApplicationModel.Package.g.cpp" #include "PackageRuntime.h" @@ -12,11 +12,11 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation { - winrt::hstring Package::FindPackageFile(winrt::hstring const& PackageFullName, winrt::hstring const& filename) + hstring Package::FindPackageFile(hstring const& packageFullName, hstring const& filename) { wil::unique_process_heap_ptr packageFile; - THROW_IF_FAILED_MSG(::FindPackageFile(packageFullName.c_str(), filename.c_str(), wil::out_param(packageFile)); - "PackageFullName=%ls Filename=%s", packageFullName, filename); + THROW_IF_FAILED_MSG(::FindPackageFile(packageFullName.c_str(), filename.c_str(), wil::out_param(packageFile)), + "PackageFullName=%ls Filename=%ls", packageFullName.c_str(), filename.c_str()); if (!packageFile) { return winrt::hstring{}; diff --git a/dev/Package/M.W.A.Package.h b/dev/Package/M.W.A.Package.h index bcec073410..dd92d3dd9e 100644 --- a/dev/Package/M.W.A.Package.h +++ b/dev/Package/M.W.A.Package.h @@ -7,9 +7,11 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation { - struct Package : PackageT + struct Package { - static winrt::hstring FindPackageFile(winrt::hstring const& PackageFullName, winrt::hstring const& filename); + Package() = default; + + static hstring FindPackageFile(hstring const& packageFullName, hstring const& filename); }; } namespace winrt::Microsoft::Windows::ApplicationModel::factory_implementation diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl index 2c77adda35..85a608f799 100644 --- a/dev/Package/Package.idl +++ b/dev/Package/Package.idl @@ -11,6 +11,6 @@ namespace Microsoft.Windows.ApplicationModel [contract(PackageRuntimeContract, 1)] runtimeclass Package { - static String FindPackageFile(String PackageFullName, String filename); + static String FindPackageFile(String packageFullName, String filename); }; } diff --git a/dev/Package/Package.vcxitems b/dev/Package/Package.vcxitems index c57d1a7e5a..7d1bae7431 100644 --- a/dev/Package/Package.vcxitems +++ b/dev/Package/Package.vcxitems @@ -3,7 +3,7 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) true - {7cf52890-56fa-47e2-84fb-68ee274324b6} + {3D652B4A-AC29-4BA2-A2CA-2ACC08EAD1E9} @@ -21,6 +21,7 @@ + diff --git a/dev/Package/Package.vcxitems.filters b/dev/Package/Package.vcxitems.filters index 7b0ae98dc5..7990cea9ec 100644 --- a/dev/Package/Package.vcxitems.filters +++ b/dev/Package/Package.vcxitems.filters @@ -22,15 +22,15 @@ Header Files - - Header Files - Header Files Header Files + + Header Files + diff --git a/dev/Package/PackageRuntime.cpp b/dev/Package/PackageRuntime.cpp index 52c664b4a6..2bfd9dc395 100644 --- a/dev/Package/PackageRuntime.cpp +++ b/dev/Package/PackageRuntime.cpp @@ -5,7 +5,6 @@ #include "PackageRuntime.h" - namespace appmodel { inline std::wstring get_package_path(PCWSTR packageFullName, PackagePathType packagePathType) @@ -14,7 +13,7 @@ inline std::wstring get_package_path(PCWSTR packageFullName, PackagePathType pac // as an optimization and fallback to dynamic allocation if need be WCHAR path[MAX_PATH]{}; uint32_t pathLength{ ARRAYSIZE(path) }; - const auto rc{ ::GetPackagePathByFullName2(packageFullName, packageInfoType, &pathLength, path) }; + const auto rc{ ::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, path) }; if (rc == ERROR_SUCCESS) { return path; @@ -35,11 +34,6 @@ inline std::wstring get_package_path(PCWSTR packageFullName, PackagePathType pac return std::wstring{ pathBuffer.get() }; } -inline std::wstring get_package_path(PCWSTR packageFullName) -{ - return get_package_path(packageFullName, PackagePathType_Install); -} - inline std::filesystem::path get_package_file( PCWSTR packageFullName, PCWSTR filename, @@ -48,7 +42,7 @@ inline std::filesystem::path get_package_file( std::filesystem::path absoluteFilename; auto packagePath{ appmodel::get_package_path(packageFullName, packagePathType) }; - if (!path.empty()) + if (!packagePath.empty()) { absoluteFilename = packagePath; absoluteFilename /= filename; @@ -64,7 +58,7 @@ inline std::filesystem::path get_package_file( PCWSTR packageFullName, PCWSTR filename) { - auto path{ get_package_file(packageFullName, filename, PackagePathType_External) }; + auto path{ get_package_file(packageFullName, filename, PackagePathType_EffectiveExternal) }; if (path.empty()) { path = get_package_file(packageFullName, filename, PackagePathType_Mutable); @@ -84,11 +78,11 @@ STDAPI FindPackageFile( { *packageFile = nullptr; - RETURN_HR_IF(E_INVALIDARG, !filename || (filename[0] == L'\0')); + RETURN_HR_IF(E_INVALIDARG, ::Microsoft::Foundation::String::IsNullOrEmpty(filename)); // If packageFullName = NULL or "" use the caller's package identity WCHAR packageFullNameBuffer[PACKAGE_FULL_NAME_MAX_LENGTH + 1]{}; - if (!packageFullName || (packageFullName[0] == L'\0')) + if (::Microsoft::Foundation::String::IsNullOrEmpty(packageFullName)) { uint32_t packageFullNameBufferLength{ ARRAYSIZE(packageFullNameBuffer) }; THROW_IF_FAILED(::GetCurrentPackageFullName(&packageFullNameBufferLength, packageFullNameBuffer)); diff --git a/dev/Package/PackageRuntime.h b/dev/Package/PackageRuntime.h index 5a3a8a569b..eda739c1f8 100644 --- a/dev/Package/PackageRuntime.h +++ b/dev/Package/PackageRuntime.h @@ -4,12 +4,6 @@ #if !defined(PACKAGERUNTIME_H) #define PACKAGERUNTIME_H -#include - -#include - -#if defined(__cplusplus) - /// Return the absolute path to the packaged file. /// @param packageFullName the package, or NULL or "" to use the current process' package identity. /// @param filename file to locate. @@ -22,7 +16,4 @@ STDAPI FindPackageFile( PCWSTR filename, _Outptr_result_maybenull_ PWSTR* packageFile) noexcept; -#endif // defined(__cplusplus) - #endif // PACKAGERUNTIME_H - diff --git a/dev/Package/pch.h b/dev/Package/pch.h index ec56d476e4..50deffc909 100644 --- a/dev/Package/pch.h +++ b/dev/Package/pch.h @@ -27,3 +27,4 @@ #include #include +#include diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index 8dcd8e87ea..d790ea81f5 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include diff --git a/test/Package/API/PackageTests.cpp b/test/Package/API/PackageTests.cpp new file mode 100644 index 0000000000..d2157014d1 --- /dev/null +++ b/test/Package/API/PackageTests.cpp @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +static const winrt::hstring null_hstring; + +namespace Test::Package::Tests +{ + const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + + class PackageTests + { + public: + BEGIN_TEST_CLASS(PackageTests) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(FindPackageFile_InvalidParameter) + { + try + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring noFileName; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::FindPackageFile(packageFullName, noFileName); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + } + + TEST_METHOD(FindPackageFile_NullPackageFullName_UnpackagedProcess) + { + try + { + winrt::hstring noPackageFullName; + winrt::hstring fileName{ L"AppxManifest.xml" }; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::FindPackageFile(noPackageFullName, fileName); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + } + + TEST_METHOD(FindPackageFile_NullPackageFullName_PackagedProcess) + { + //TODO + } + + TEST_METHOD(FindPackageFile_InstallPath) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::FindPackageFile(packageFullName, fileName) }; + //TODO + } + }; +} diff --git a/test/Package/API/PackageTests.vcxproj b/test/Package/API/PackageTests.vcxproj new file mode 100644 index 0000000000..16536bc13b --- /dev/null +++ b/test/Package/API/PackageTests.vcxproj @@ -0,0 +1,164 @@ + + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + 16.0 + {f8a40421-cede-4ba2-8df5-d00c33df16b7} + Win32Proj + PackageTests + 10.0 + NativeUnitTestProject + PackageTests + + + DynamicLibrary + false + v143 + Unicode + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + Use + true + pch.h + $(RepoRoot)\test\inc;$(RepoRoot)\dev\common;$(VCInstallDir)UnitTest\include;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) + $(RepoRoot);%(AdditionalIncludeDirectories) + + + Windows + onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL + Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + WIN32;%(PreprocessorDefinitions) + + + + + Create + + + + + + + + + + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.winmd + true + + + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd + true + + + + + + + + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} + + + + + + + + + + + + + + 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}. + + + + + + + + + + + + + diff --git a/test/Package/API/PackageTests.vcxproj.filters b/test/Package/API/PackageTests.vcxproj.filters new file mode 100644 index 0000000000..43cd9bcb1e --- /dev/null +++ b/test/Package/API/PackageTests.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + + diff --git a/test/Package/API/Test.testdef b/test/Package/API/Test.testdef new file mode 100644 index 0000000000..c843bed7ad --- /dev/null +++ b/test/Package/API/Test.testdef @@ -0,0 +1,11 @@ +{ + "Tests": [ + { + "Description": "PackageTests tests for feature Package", + "Filename": "PackageTests.dll", + "Parameters": "", + "Architectures": ["x86", "x64", "arm64"], + "Status": "Enabled" + } + ] +} diff --git a/test/Package/API/Test.testdef.bak b/test/Package/API/Test.testdef.bak new file mode 100644 index 0000000000..f047cd1a30 --- /dev/null +++ b/test/Package/API/Test.testdef.bak @@ -0,0 +1,11 @@ +{ + "Tests": [ + { + "Description": "PackageTests tests for feature Package", + "Filename": "PackageTests.dll", + "Parameters": "", + "Architectures": ["x86", "x64"], + "Status": "Enabled" + } + ] +} diff --git a/test/Package/API/packages.config b/test/Package/API/packages.config new file mode 100644 index 0000000000..0c13ff7b9c --- /dev/null +++ b/test/Package/API/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/test/Package/API/pch.cpp b/test/Package/API/pch.cpp new file mode 100644 index 0000000000..f59e66e263 --- /dev/null +++ b/test/Package/API/pch.cpp @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" diff --git a/test/Package/API/pch.h b/test/Package/API/pch.h new file mode 100644 index 0000000000..aa6962f8da --- /dev/null +++ b/test/Package/API/pch.h @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#ifndef PCH_H +#define PCH_H + +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#endif //PCH_H From 3e746520e9eeaa982c8da9b2cf0260b2dec90f1f Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 28 Jun 2025 22:29:44 -0700 Subject: [PATCH 03/33] Don't checkin *.bak --- .gitignore | 3 +++ test/Package/API/Test.testdef.bak | 11 ----------- 2 files changed, 3 insertions(+), 11 deletions(-) delete mode 100644 test/Package/API/Test.testdef.bak diff --git a/.gitignore b/.gitignore index 863bfdce8f..a26c9d9721 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ *.userosscache *.sln.docstates +# Backup files +*.[Bb][Aa][Kk] + # full nuget directory [Bb]uild/FullNuget diff --git a/test/Package/API/Test.testdef.bak b/test/Package/API/Test.testdef.bak deleted file mode 100644 index f047cd1a30..0000000000 --- a/test/Package/API/Test.testdef.bak +++ /dev/null @@ -1,11 +0,0 @@ -{ - "Tests": [ - { - "Description": "PackageTests tests for feature Package", - "Filename": "PackageTests.dll", - "Parameters": "", - "Architectures": ["x86", "x64"], - "Status": "Enabled" - } - ] -} From d41dd1480b078351cf6d168865817d2e879cc14d Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 28 Jun 2025 22:38:15 -0700 Subject: [PATCH 04/33] Added Package activatable class to manifests --- build/NuSpecs/AppxManifest.xml | 3 +++ .../Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/build/NuSpecs/AppxManifest.xml b/build/NuSpecs/AppxManifest.xml index 12fe8e6c5f..69f533db34 100644 --- a/build/NuSpecs/AppxManifest.xml +++ b/build/NuSpecs/AppxManifest.xml @@ -46,6 +46,9 @@ + + + diff --git a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml index 2380c63e0b..88419fb791 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -66,6 +66,12 @@ + + + Microsoft.WindowsAppRuntime.dll + + + Microsoft.WindowsAppRuntime.dll From 9912d17871134da429a7e26959baee1ddb2943b9 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 7 Aug 2025 00:51:42 -0700 Subject: [PATCH 05/33] Partial implementation --- dev/Package/M.W.A.Package.cpp | 14 +++- dev/Package/M.W.A.Package.h | 2 + dev/Package/Package.idl | 18 ++++- dev/Package/Package.vcxitems | 6 +- dev/Package/Package.vcxitems.filters | 4 +- dev/Package/PackageRuntime.h | 19 ----- ...PackageRuntime.cpp => package_runtime.cpp} | 2 +- dev/Package/package_runtime.h | 31 +++++++++ test/Package/API/PackageTests.vcxproj | 3 +- test/Package/API/PackageTests.vcxproj.filters | 5 +- test/Package/API/PackageTests_CPP.cpp | 69 +++++++++++++++++++ ...ackageTests.cpp => PackageTests_WinRT.cpp} | 4 +- 12 files changed, 146 insertions(+), 31 deletions(-) delete mode 100644 dev/Package/PackageRuntime.h rename dev/Package/{PackageRuntime.cpp => package_runtime.cpp} (99%) create mode 100644 dev/Package/package_runtime.h create mode 100644 test/Package/API/PackageTests_CPP.cpp rename test/Package/API/{PackageTests.cpp => PackageTests_WinRT.cpp} (97%) diff --git a/dev/Package/M.W.A.Package.cpp b/dev/Package/M.W.A.Package.cpp index da667ecaca..86ee5bb385 100644 --- a/dev/Package/M.W.A.Package.cpp +++ b/dev/Package/M.W.A.Package.cpp @@ -6,7 +6,7 @@ #include "M.W.A.Package.h" #include "Microsoft.Windows.ApplicationModel.Package.g.cpp" -#include "PackageRuntime.h" +#include "package_runtime.h" #include "PackageTelemetry.h" @@ -23,4 +23,16 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation } return winrt::hstring{ packageFile.get() }; } + + hstring Package::FindPackageFileInPackageGraph(hstring const& packageFullName, hstring const& filename) + { + wil::unique_process_heap_ptr packageFile; + THROW_IF_FAILED_MSG(::FindPackageFile(packageFullName.c_str(), filename.c_str(), wil::out_param(packageFile)), + "PackageFullName=%ls Filename=%ls", packageFullName.c_str(), filename.c_str()); + if (!packageFile) + { + return winrt::hstring{}; + } + return winrt::hstring{ packageFile.get() }; + } } diff --git a/dev/Package/M.W.A.Package.h b/dev/Package/M.W.A.Package.h index dd92d3dd9e..045137ddc7 100644 --- a/dev/Package/M.W.A.Package.h +++ b/dev/Package/M.W.A.Package.h @@ -12,6 +12,8 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation Package() = default; static hstring FindPackageFile(hstring const& packageFullName, hstring const& filename); + + static hstring FindPackageFileInPackageGraph(hstring const& packageFullName, hstring const& filename); }; } namespace winrt::Microsoft::Windows::ApplicationModel::factory_implementation diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl index 85a608f799..b3020e0a81 100644 --- a/dev/Package/Package.idl +++ b/dev/Package/Package.idl @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation and Contributors. // Licensed under the MIT License. -#include +#include namespace Microsoft.Windows.ApplicationModel { @@ -11,6 +11,22 @@ namespace Microsoft.Windows.ApplicationModel [contract(PackageRuntimeContract, 1)] runtimeclass Package { + /// Return the absolute path to the file in the package. + /// @param packageFullName the package, or empty string ("") to use the current process' package identity. + /// @param filename file to locate. + /// @param packageFile absolute path to the packaged file, or empty string ("") if not found. + /// @note The package path search order is External(User or Machine) -> Mutable -> Install. + /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). + /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 static String FindPackageFile(String packageFullName, String filename); + + /// Return the absolute path to the file in the package graph. + /// @param packageFullName the package, or empty string ("") to use the current process' package identity. + /// @param filename file to locate. + /// @param packageFile absolute path to the packaged file, or empty string ("") if not found. + /// @note The package paths search order is External(User or Machine) -> Mutable -> Install. + /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). + /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 + static String FindPackageFileInPackageGraph(String packageFullName, String filename); }; } diff --git a/dev/Package/Package.vcxitems b/dev/Package/Package.vcxitems index 7d1bae7431..85066a46a1 100644 --- a/dev/Package/Package.vcxitems +++ b/dev/Package/Package.vcxitems @@ -15,11 +15,11 @@ - + - + @@ -27,6 +27,6 @@ - + diff --git a/dev/Package/Package.vcxitems.filters b/dev/Package/Package.vcxitems.filters index 7990cea9ec..37ff233cbe 100644 --- a/dev/Package/Package.vcxitems.filters +++ b/dev/Package/Package.vcxitems.filters @@ -14,7 +14,7 @@ Source Files - + Source Files @@ -22,7 +22,7 @@ Header Files - + Header Files diff --git a/dev/Package/PackageRuntime.h b/dev/Package/PackageRuntime.h deleted file mode 100644 index eda739c1f8..0000000000 --- a/dev/Package/PackageRuntime.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Microsoft Corporation and Contributors. -// Licensed under the MIT License. - -#if !defined(PACKAGERUNTIME_H) -#define PACKAGERUNTIME_H - -/// Return the absolute path to the packaged file. -/// @param packageFullName the package, or NULL or "" to use the current process' package identity. -/// @param filename file to locate. -/// @param packageFile absolute path to the packaged file, or NULL if not found. Allocated via HeapAlloc; use HeapFree to deallocate -/// @note The package path search order is External(User or Machine) -> Mutable -> Install. -/// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). -/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 -STDAPI FindPackageFile( - PCWSTR packageFullName, - PCWSTR filename, - _Outptr_result_maybenull_ PWSTR* packageFile) noexcept; - -#endif // PACKAGERUNTIME_H diff --git a/dev/Package/PackageRuntime.cpp b/dev/Package/package_runtime.cpp similarity index 99% rename from dev/Package/PackageRuntime.cpp rename to dev/Package/package_runtime.cpp index 2bfd9dc395..33821e5f62 100644 --- a/dev/Package/PackageRuntime.cpp +++ b/dev/Package/package_runtime.cpp @@ -3,7 +3,7 @@ #include "pch.h" -#include "PackageRuntime.h" +#include "package_runtime.h" namespace appmodel { diff --git a/dev/Package/package_runtime.h b/dev/Package/package_runtime.h new file mode 100644 index 0000000000..b24fea1617 --- /dev/null +++ b/dev/Package/package_runtime.h @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#if !defined(PACKAGE_RUNTIME_H) +#define PACKAGE_RUNTIME_H + +/// Return the absolute path to the file in the package. +/// @param packageFullName the package, or NULL or "" to use the current process' package identity. +/// @param filename file to locate. +/// @param packageFile absolute path to the packaged file, or NULL if not found. Allocated via HeapAlloc; use HeapFree to deallocate +/// @note The package path search order is External(User or Machine) -> Mutable -> Install. +/// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 +STDAPI FindPackageFile( + _In_ PCWSTR packageFullName, + _In_ PCWSTR filename, + _Outptr_result_maybenull_ PWSTR* packageFile) noexcept; + +/// Return the absolute path to the file in the package graph. +/// @param packageFullName the package, or NULL or "" to use the current process' package identity. +/// @param filename file to locate. +/// @param packageFile absolute path to the packaged file, or NULL if not found. Allocated via HeapAlloc; use HeapFree to deallocate +/// @note The package paths search order is External(User or Machine) -> Mutable -> Install. +/// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 +STDAPI FindPackageFileInPackageGraph( + _In_ PCWSTR packageFullName, + _In_ PCWSTR filename, + _Outptr_result_maybenull_ PWSTR* packageFile) noexcept; + +#endif // PACKAGE_RUNTIME_H diff --git a/test/Package/API/PackageTests.vcxproj b/test/Package/API/PackageTests.vcxproj index 16536bc13b..053f7a18fc 100644 --- a/test/Package/API/PackageTests.vcxproj +++ b/test/Package/API/PackageTests.vcxproj @@ -109,7 +109,8 @@ Create - + + diff --git a/test/Package/API/PackageTests.vcxproj.filters b/test/Package/API/PackageTests.vcxproj.filters index 43cd9bcb1e..c0c02b67c9 100644 --- a/test/Package/API/PackageTests.vcxproj.filters +++ b/test/Package/API/PackageTests.vcxproj.filters @@ -18,7 +18,10 @@ Source Files - + + Source Files + + Source Files diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp new file mode 100644 index 0000000000..ca22d97ada --- /dev/null +++ b/test/Package/API/PackageTests_CPP.cpp @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +namespace Test::Package::Tests +{ + const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + + class PackageTests_CPP + { + public: + BEGIN_TEST_CLASS(PackageTests_CPP) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(FindPackageFile_InvalidParameter) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR noFileName{}; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_ARE_EQUAL(E_INVALIDARG, ::FindPackageFile(packageFullName, noFileName, wil::out_param(absoluteFilename)); + } + + TEST_METHOD(FindPackageFile_NullPackageFullName_UnpackagedProcess) + { + PCWSTR noPackageFullName{}; + PCWSTR fileName{ L"AppxManifest.xml" }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), ::FindPackageFile(noPackageFullName, fileName, wil::out_param(absoluteFilename))); + } + + TEST_METHOD(FindPackageFile_NullPackageFullName_PackagedProcess) + { + //TODO + } + + TEST_METHOD(FindPackageFile_InstallPath) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::FindPackageFile(noPackageFullName, fileName, wil::out_param(absoluteFilename))); + //TODO + } + }; +} diff --git a/test/Package/API/PackageTests.cpp b/test/Package/API/PackageTests_WinRT.cpp similarity index 97% rename from test/Package/API/PackageTests.cpp rename to test/Package/API/PackageTests_WinRT.cpp index d2157014d1..c1868e9a69 100644 --- a/test/Package/API/PackageTests.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -16,10 +16,10 @@ namespace Test::Package::Tests { const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; - class PackageTests + class PackageTests_WinRT { public: - BEGIN_TEST_CLASS(PackageTests) + BEGIN_TEST_CLASS(PackageTests_WinRT) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") END_TEST_CLASS() From 7f25624e319c456629e44a9abf3a2ded0ee7d66d Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 13 Dec 2025 16:01:13 -0800 Subject: [PATCH 06/33] GetFilePath initial implementation --- WindowsAppRuntime.sln | 4 + dev/Interop/StoragePickers/PickerCommon.cpp | 4 +- dev/Package/M.W.A.Package.cpp | 35 +-- dev/Package/M.W.A.Package.h | 6 +- dev/Package/M.W.A.PackageGraph.cpp | 43 ++++ dev/Package/M.W.A.PackageGraph.h | 23 ++ dev/Package/Package.idl | 98 +++++++- dev/Package/Package.vcxitems | 2 + dev/Package/Package.vcxitems.filters | 6 + dev/Package/package_runtime.cpp | 130 ++++++++++- dev/Package/package_runtime.h | 64 ++++- .../WindowsAppRuntime.def | 3 +- test/ABForward/FunctionalTests.cpp | 2 +- test/Package/API/PackageTests.Packages.h | 218 ++++++++++++++++++ test/Package/API/PackageTests.vcxproj | 2 +- test/Package/API/PackageTests.vcxproj.filters | 3 + test/Package/API/PackageTests_CPP.cpp | 89 ++++++- test/Package/API/PackageTests_WinRT.cpp | 125 +++++++++- test/Package/API/pch.h | 2 + .../Package.MachineExternal.msix.vcxproj | 120 ++++++++++ ...ckage.MachineExternal.msix.vcxproj.filters | 12 + .../Package.MachineExternal.vcxproj.filters | 15 ++ .../data/MachineExternal/appxmanifest.xml | 29 +++ test/Package/data/MachineExternal/logo.png | Bin 0 -> 5632 bytes .../data/MachineExternal/packages.config | 6 + .../data/Mutable/Package.Mutable.msix.vcxproj | 120 ++++++++++ .../Package.Mutable.msix.vcxproj.filters | 12 + .../Mutable/Package.Mutable.vcxproj.filters | 17 ++ test/Package/data/Mutable/appxmanifest.xml | 40 ++++ test/Package/data/Mutable/logo.png | Bin 0 -> 5632 bytes test/Package/data/Mutable/packages.config | 6 + .../Package.UserExternal.msix.vcxproj | 120 ++++++++++ .../Package.UserExternal.msix.vcxproj.filters | 12 + .../Package.UserExternal.vcxproj.filters | 15 ++ .../data/UserExternal/appxmanifest.xml | 29 +++ test/Package/data/UserExternal/logo.png | Bin 0 -> 5632 bytes .../Package/data/UserExternal/packages.config | 6 + tools/DevCheck/DevCheck.ps1 | 47 ++-- 38 files changed, 1388 insertions(+), 77 deletions(-) create mode 100644 dev/Package/M.W.A.PackageGraph.cpp create mode 100644 dev/Package/M.W.A.PackageGraph.h create mode 100644 test/Package/API/PackageTests.Packages.h create mode 100644 test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj create mode 100644 test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj.filters create mode 100644 test/Package/data/MachineExternal/Package.MachineExternal.vcxproj.filters create mode 100644 test/Package/data/MachineExternal/appxmanifest.xml create mode 100644 test/Package/data/MachineExternal/logo.png create mode 100644 test/Package/data/MachineExternal/packages.config create mode 100644 test/Package/data/Mutable/Package.Mutable.msix.vcxproj create mode 100644 test/Package/data/Mutable/Package.Mutable.msix.vcxproj.filters create mode 100644 test/Package/data/Mutable/Package.Mutable.vcxproj.filters create mode 100644 test/Package/data/Mutable/appxmanifest.xml create mode 100644 test/Package/data/Mutable/logo.png create mode 100644 test/Package/data/Mutable/packages.config create mode 100644 test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj create mode 100644 test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj.filters create mode 100644 test/Package/data/UserExternal/Package.UserExternal.vcxproj.filters create mode 100644 test/Package/data/UserExternal/appxmanifest.xml create mode 100644 test/Package/data/UserExternal/logo.png create mode 100644 test/Package/data/UserExternal/packages.config diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index dba2ee3ee1..649aa090e8 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -690,6 +690,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Decimal", "Decimal", "{5012149E-F09F-4F18-A03C-FFE597203821}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Foundation.Projection", "dev\Projections\CS\Microsoft.Windows.Foundation\Microsoft.Windows.Foundation.Projection.csproj", "{8EBA8758-19D5-AE31-FD9C-86BBA3BFF6CA}" + ProjectSection(ProjectDependencies) = postProject + {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CPP", "CPP", "{7C0F3E70-BDB3-40B2-84E1-B1B77A80CB53}" EndProject @@ -2853,6 +2856,7 @@ Global dev\RuntimeCompatibilityOptions\RuntimeCompatibilityOptions.vcxitems*{1f7b9e9f-9987-490b-9e6e-093c7f63fec4}*SharedItemsImports = 9 dev\Notifications\BaseNotifications\BaseNotifications.vcxitems*{2bd7a1bb-d3d8-484f-9180-409d781dccf9}*SharedItemsImports = 9 dev\EnvironmentManager\API\Microsoft.Process.Environment.vcxitems*{2f3fad1b-d3df-4866-a3a3-c2c777d55638}*SharedItemsImports = 9 + dev\Package\Package.vcxitems*{3d652b4a-ac29-4ba2-a2ca-2acc08ead1e9}*SharedItemsImports = 9 dev\OAuth\OAuth.vcxitems*{3e7fd510-8b66-40e7-a80b-780cb8972f83}*SharedItemsImports = 9 test\inc\inc.vcxitems*{412d023e-8635-4ad2-a0ea-e19e08d36915}*SharedItemsImports = 4 test\inc\inc.vcxitems*{4b30c685-8490-440f-9879-a75d45daa361}*SharedItemsImports = 4 diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index dec7a50d3a..d65a0f68ca 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -178,7 +178,7 @@ namespace PickerCommon { return; } - for (int i = 0; i < value.size(); i++) + for (std::uint32_t i = 0; i < value.size(); i++) { if (value[i] == L'\0') { @@ -201,7 +201,7 @@ namespace PickerCommon { PickerLocalization::GetStoragePickersLocalizationText(ImproperFileExtensionLocalizationKey)); } - for (int i = 1; i < filter.size(); i++) + for (std::uint32_t i = 1; i < filter.size(); i++) { if (filter[i] == L'.' || filter[i] == L'*' || filter[i] == L'?') { diff --git a/dev/Package/M.W.A.Package.cpp b/dev/Package/M.W.A.Package.cpp index 86ee5bb385..c99580053a 100644 --- a/dev/Package/M.W.A.Package.cpp +++ b/dev/Package/M.W.A.Package.cpp @@ -12,23 +12,32 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation { - hstring Package::FindPackageFile(hstring const& packageFullName, hstring const& filename) + static_assert(static_cast(GetFilePathOptions::None) == static_cast(GetPackageFilePathOptions_None), "GetFilePathOptions::None != FindPackageFileOptions_None"); + static_assert(static_cast(GetFilePathOptions::SearchInstallPath) == static_cast(GetPackageFilePathOptions_SearchInstallPath), "GetFilePathOptions::SearchInstallPath != GetPackageFilePathOptions_SearchInstallPath"); + static_assert(static_cast(GetFilePathOptions::SearchMutablePath) == static_cast(GetPackageFilePathOptions_SearchMutablePath), "GetFilePathOptions::SearchMutablePath != GetPackageFilePathOptions_SearchMutablePath"); + static_assert(static_cast(GetFilePathOptions::SearchMachineExternalPath) == static_cast(GetPackageFilePathOptions_SearchMachineExternalPath), "GetFilePathOptions::SearchMachineExternalPath != GetPackageFilePathOptions_SearchMachineExternalPath"); + static_assert(static_cast(GetFilePathOptions::SearchUserExternalPath) == static_cast(GetPackageFilePathOptions_SearchUserExternalPath), "GetFilePathOptions::SearchUserExternalPath != GetPackageFilePathOptions_SearchUserExternalPath"); + static_assert(static_cast(GetFilePathOptions::SearchMainPackages) == static_cast(GetPackageFilePathOptions_SearchMainPackages), "GetFilePathOptions::SearchMainPackages!= GetPackageFilePathOptions_SearchMainPackages"); + static_assert(static_cast(GetFilePathOptions::SearchFrameworkPackages) == static_cast(GetPackageFilePathOptions_SearchFrameworkPackages), "GetFilePathOptions::SearchFrameworkPackages!= GetPackageFilePathOptions_SearchFrameworkPackages"); + static_assert(static_cast(GetFilePathOptions::SearchOptionalPackages) == static_cast(GetPackageFilePathOptions_SearchOptionalPackages), "GetFilePathOptions::SearchOptionalPackages!= GetPackageFilePathOptions_SearchOptionalPackages"); + static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages"); + static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies"); + static_assert(static_cast(GetFilePathOptions::SearchStaticDependencies) == static_cast(GetPackageFilePathOptions_SearchStaticDependencies), "GetFilePathOptions::SearchStaticDependencies!= GetPackageFilePathOptions_SearchStaticDependencies"); + static_assert(static_cast(GetFilePathOptions::SearchDynamicDependencies) == static_cast(GetPackageFilePathOptions_SearchDynamicDependencies), "GetFilePathOptions::SearchDynamicDependencies!= GetPackageFilePathOptions_SearchDynamicDependencies"); + + hstring Package::GetFilePath(hstring const& filename) { - wil::unique_process_heap_ptr packageFile; - THROW_IF_FAILED_MSG(::FindPackageFile(packageFullName.c_str(), filename.c_str(), wil::out_param(packageFile)), - "PackageFullName=%ls Filename=%ls", packageFullName.c_str(), filename.c_str()); - if (!packageFile) - { - return winrt::hstring{}; - } - return winrt::hstring{ packageFile.get() }; + return GetFilePath(filename, winrt::hstring{}); } - - hstring Package::FindPackageFileInPackageGraph(hstring const& packageFullName, hstring const& filename) + hstring Package::GetFilePath(hstring const& filename, hstring const& packageFullName) + { + return GetFilePath(filename, packageFullName, GetFilePathOptions::None); + } + hstring Package::GetFilePath(hstring const& filename, hstring const& packageFullName, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options) { wil::unique_process_heap_ptr packageFile; - THROW_IF_FAILED_MSG(::FindPackageFile(packageFullName.c_str(), filename.c_str(), wil::out_param(packageFile)), - "PackageFullName=%ls Filename=%ls", packageFullName.c_str(), filename.c_str()); + THROW_IF_FAILED_MSG(::GetPackageFilePath(packageFullName.c_str(), filename.c_str(), static_cast<::GetPackageFilePathOptions>(options), wil::out_param(packageFile)), + "PackageFullName=%ls Options=0x%X Filename=%ls", packageFullName.c_str(), static_cast(options), filename.c_str()); if (!packageFile) { return winrt::hstring{}; diff --git a/dev/Package/M.W.A.Package.h b/dev/Package/M.W.A.Package.h index 045137ddc7..3048b231a7 100644 --- a/dev/Package/M.W.A.Package.h +++ b/dev/Package/M.W.A.Package.h @@ -11,9 +11,9 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation { Package() = default; - static hstring FindPackageFile(hstring const& packageFullName, hstring const& filename); - - static hstring FindPackageFileInPackageGraph(hstring const& packageFullName, hstring const& filename); + static hstring GetFilePath(hstring const& filename); + static hstring GetFilePath(hstring const& filename, hstring const& packageFullName); + static hstring GetFilePath(hstring const& filename, hstring const& packageFullName, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options); }; } namespace winrt::Microsoft::Windows::ApplicationModel::factory_implementation diff --git a/dev/Package/M.W.A.PackageGraph.cpp b/dev/Package/M.W.A.PackageGraph.cpp new file mode 100644 index 0000000000..806e028915 --- /dev/null +++ b/dev/Package/M.W.A.PackageGraph.cpp @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "M.W.A.PackageGraph.h" +#include "Microsoft.Windows.ApplicationModel.PackageGraph.g.cpp" + +#include "package_runtime.h" + +#include "PackageTelemetry.h" + +namespace winrt::Microsoft::Windows::ApplicationModel::implementation +{ + static_assert(static_cast(GetFilePathOptions::None) == static_cast(GetPackageFilePathOptions_None), "GetFilePathOptions::None != FindPackageFileOptions_None"); + static_assert(static_cast(GetFilePathOptions::SearchInstallPath) == static_cast(GetPackageFilePathOptions_SearchInstallPath), "GetFilePathOptions::SearchInstallPath != GetPackageFilePathOptions_SearchInstallPath"); + static_assert(static_cast(GetFilePathOptions::SearchMutablePath) == static_cast(GetPackageFilePathOptions_SearchMutablePath), "GetFilePathOptions::SearchMutablePath != GetPackageFilePathOptions_SearchMutablePath"); + static_assert(static_cast(GetFilePathOptions::SearchMachineExternalPath) == static_cast(GetPackageFilePathOptions_SearchMachineExternalPath), "GetFilePathOptions::SearchMachineExternalPath != GetPackageFilePathOptions_SearchMachineExternalPath"); + static_assert(static_cast(GetFilePathOptions::SearchUserExternalPath) == static_cast(GetPackageFilePathOptions_SearchUserExternalPath), "GetFilePathOptions::SearchUserExternalPath != GetPackageFilePathOptions_SearchUserExternalPath"); + static_assert(static_cast(GetFilePathOptions::SearchMainPackages) == static_cast(GetPackageFilePathOptions_SearchMainPackages), "GetFilePathOptions::SearchMainPackages!= GetPackageFilePathOptions_SearchMainPackages"); + static_assert(static_cast(GetFilePathOptions::SearchFrameworkPackages) == static_cast(GetPackageFilePathOptions_SearchFrameworkPackages), "GetFilePathOptions::SearchFrameworkPackages!= GetPackageFilePathOptions_SearchFrameworkPackages"); + static_assert(static_cast(GetFilePathOptions::SearchOptionalPackages) == static_cast(GetPackageFilePathOptions_SearchOptionalPackages), "GetFilePathOptions::SearchOptionalPackages!= GetPackageFilePathOptions_SearchOptionalPackages"); + static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages"); + static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies"); + static_assert(static_cast(GetFilePathOptions::SearchStaticDependencies) == static_cast(GetPackageFilePathOptions_SearchStaticDependencies), "GetFilePathOptions::SearchStaticDependencies!= GetPackageFilePathOptions_SearchStaticDependencies"); + static_assert(static_cast(GetFilePathOptions::SearchDynamicDependencies) == static_cast(GetPackageFilePathOptions_SearchDynamicDependencies), "GetFilePathOptions::SearchDynamicDependencies!= GetPackageFilePathOptions_SearchDynamicDependencies"); + + hstring PackageGraph::GetFilePath(hstring const& filename) + { + return GetFilePath(filename, GetFilePathOptions::None); + } + hstring PackageGraph::GetFilePath(hstring const& filename, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options) + { + wil::unique_process_heap_ptr packageFile; + THROW_IF_FAILED_MSG(::GetPackageFilePathInPackageGraph(filename.c_str(), static_cast<::GetPackageFilePathOptions>(options), wil::out_param(packageFile)), + "Options=0x%X Filename=%ls", static_cast(options), filename.c_str()); + if (!packageFile) + { + return winrt::hstring{}; + } + return winrt::hstring{ packageFile.get() }; + } +} diff --git a/dev/Package/M.W.A.PackageGraph.h b/dev/Package/M.W.A.PackageGraph.h new file mode 100644 index 0000000000..f888f0f1b9 --- /dev/null +++ b/dev/Package/M.W.A.PackageGraph.h @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#pragma once + +#include "Microsoft.Windows.ApplicationModel.PackageGraph.g.h" + +namespace winrt::Microsoft::Windows::ApplicationModel::implementation +{ + struct PackageGraph + { + PackageGraph() = default; + + static hstring GetFilePath(hstring const& filename); + static hstring GetFilePath(hstring const& filename, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options); + }; +} +namespace winrt::Microsoft::Windows::ApplicationModel::factory_implementation +{ + struct PackageGraph : PackageGraphT + { + }; +} diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl index b3020e0a81..4428332118 100644 --- a/dev/Package/Package.idl +++ b/dev/Package/Package.idl @@ -1,32 +1,120 @@ // Copyright (c) Microsoft Corporation and Contributors. // Licensed under the MIT License. -#include +#include namespace Microsoft.Windows.ApplicationModel { [contractversion(1)] apicontract PackageRuntimeContract{}; + /// Options for GetFilePath*() + /// @see Package.GetFilePath + /// @see PackageGraph.GetFilePath + [contract(PackageRuntimeContract, 1)] + [flags] + enum GetFilePathOptions + { + /// Default behavior + None = 0, + + /// Include the package's Install path in the file search order + SearchInstallPath = 0x0001, + + /// Include the package's Mutable path (if it has one) in the file search order + SearchMutablePath = 0x0002, + + /// Include the package's Machine External path (if it has one) in the file search order + SearchMachineExternalPath = 0x0004, + + /// Include the package's User External path (if it has one) in the file search order + SearchUserExternalPath = 0x0008, + + /// Include Main packages in the file search order + SearchMainPackages = 0x0010, + + /// Include Framework packages in the file search order + SearchFrameworkPackages = 0x0020, + + /// Include Optional packages in the file search order + SearchOptionalPackages = 0x0040, + + /// Include Resource packages in the file search order + SearchResourcePackages = 0x0080, + + /// Include HostRuntime dependencies in the file search order + SearchHostRuntimeDependencies = 0x0100, + + /// Include Static package dependencies in the file search order + /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + SearchStaticDependencies = 0x0200, + + /// Include Dynamic package dependencies in the file search order + /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + SearchDynamicDependencies = 0x0400, + }; + [contract(PackageRuntimeContract, 1)] runtimeclass Package { + /// Return the absolute path to the file in the current process' package. This uses the + /// current process' package identity, or fails with HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE) + /// if the process lacks package identity. + /// @param filename file to locate. + /// @param packageFile absolute path to the packaged file, or empty string ("") if not found. + /// @note The package path search order is External(User or Machine) -> Mutable -> Install. + /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). + /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 + /// @see PackageGraph.GetFilePath + static String GetFilePath(String filename); + + /// Return the absolute path to the file in the package. + /// @param filename file to locate. + /// @param packageFullName the package. + /// @param packageFile absolute path to the packaged file, or empty string ("") if not found. + /// @note The package path search order is External(User or Machine) -> Mutable -> Install. + /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). + /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 + /// @see PackageGraph.GetFilePath + [method_name("GetFilePathInPackage")] + static String GetFilePath(String filename, String packageFullName); + /// Return the absolute path to the file in the package. - /// @param packageFullName the package, or empty string ("") to use the current process' package identity. /// @param filename file to locate. + /// @param packageFullName the package. /// @param packageFile absolute path to the packaged file, or empty string ("") if not found. + /// @param options options for the search. /// @note The package path search order is External(User or Machine) -> Mutable -> Install. /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 - static String FindPackageFile(String packageFullName, String filename); + /// @see PackageGraph.GetFilePath + /// @see PackageGraph.GetFilePathOptions + [method_name("GetFilePathInPackageWithOptions")] + static String GetFilePath(String filename, String packageFullName, GetFilePathOptions options); + } + + [contract(PackageRuntimeContract, 1)] + runtimeclass PackageGraph + { + /// Return the absolute path to the file in the package graph. + /// @param filename file to locate. + /// @param packageFile absolute path to the packaged file, or empty string ("") if not found. + /// @note The package paths search order is External(User or Machine) -> Mutable -> Install. + /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). + /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 + /// @see Package.GetFilePath + static String GetFilePath(String filename); /// Return the absolute path to the file in the package graph. - /// @param packageFullName the package, or empty string ("") to use the current process' package identity. /// @param filename file to locate. /// @param packageFile absolute path to the packaged file, or empty string ("") if not found. + /// @param options options for the search. /// @note The package paths search order is External(User or Machine) -> Mutable -> Install. /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 - static String FindPackageFileInPackageGraph(String packageFullName, String filename); + /// @see Package.GetFilePath + /// @see GetPackageFilePathOptions + [method_name("GetFilePathWithOptions")] + static String GetFilePath(String filename, GetFilePathOptions options); }; } diff --git a/dev/Package/Package.vcxitems b/dev/Package/Package.vcxitems index 85066a46a1..67039d5f16 100644 --- a/dev/Package/Package.vcxitems +++ b/dev/Package/Package.vcxitems @@ -15,10 +15,12 @@ + + diff --git a/dev/Package/Package.vcxitems.filters b/dev/Package/Package.vcxitems.filters index 37ff233cbe..2a72bbe298 100644 --- a/dev/Package/Package.vcxitems.filters +++ b/dev/Package/Package.vcxitems.filters @@ -14,6 +14,9 @@ Source Files + + Source Files + Source Files @@ -22,6 +25,9 @@ Header Files + + Header Files + Header Files diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index 33821e5f62..82487d99ce 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -7,7 +7,9 @@ namespace appmodel { -inline std::wstring get_package_path(PCWSTR packageFullName, PackagePathType packagePathType) +inline std::wstring get_package_path( + PCWSTR packageFullName, + PackagePathType packagePathType) { // Paths can be long but typically short(ish). We can use a quick fixed buffer // as an optimization and fallback to dynamic allocation if need be @@ -36,7 +38,8 @@ inline std::wstring get_package_path(PCWSTR packageFullName, PackagePathType pac inline std::filesystem::path get_package_file( PCWSTR packageFullName, - PCWSTR filename, + _In_ PCWSTR filename, + _In_ GetPackageFilePathOptions options, PackagePathType packagePathType) { std::filesystem::path absoluteFilename; @@ -56,24 +59,54 @@ inline std::filesystem::path get_package_file( inline std::filesystem::path get_package_file( PCWSTR packageFullName, - PCWSTR filename) + _In_ PCWSTR filename, + _In_ GetPackageFilePathOptions options) { - auto path{ get_package_file(packageFullName, filename, PackagePathType_EffectiveExternal) }; + std::filesystem::path path; + + // Search External location + if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchUserExternalPath)) + { + if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) + { + // EffectiveExternal == UserExternal if package/user has one else MachineExternal + path = get_package_file(packageFullName, filename, options, PackagePathType_EffectiveExternal); + } + else + { + path = get_package_file(packageFullName, filename, options, PackagePathType_UserExternal); + } + } + else if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) + { + path = get_package_file(packageFullName, filename, options, PackagePathType_MachineExternal); + } if (path.empty()) { - path = get_package_file(packageFullName, filename, PackagePathType_Mutable); + // Search Mutable location + if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMutablePath)) + { + path = get_package_file(packageFullName, filename, options, PackagePathType_Mutable); + } if (path.empty()) { - path = get_package_file(packageFullName, filename, PackagePathType_Install); + // Search Install location + if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchInstallPath)) + { + path = get_package_file(packageFullName, filename, options, PackagePathType_Install); + } } } - return path; + + // Not found + return std::filesystem::path{}; } } -STDAPI FindPackageFile( +STDAPI GetPackageFilePath( PCWSTR packageFullName, - PCWSTR filename, + _In_ PCWSTR filename, + _In_ GetPackageFilePathOptions options, _Outptr_result_maybenull_ PWSTR* packageFile) noexcept try { *packageFile = nullptr; @@ -89,7 +122,7 @@ STDAPI FindPackageFile( packageFullName = packageFullNameBuffer; } - auto path{ appmodel::get_package_file(packageFullName, filename) }; + auto path{ appmodel::get_package_file(packageFullName, filename, options) }; if (!path.empty()) { auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) }; @@ -98,3 +131,80 @@ STDAPI FindPackageFile( return S_OK; } CATCH_RETURN(); + +/// Is a PACKAGE_INFO entry a Main package? +/// @note There's no direct propery to check indicating a Main package. +/// That's only detectable by the absence of any other type of package. +inline constexpr bool IsMainPackage(const UINT32 packageInfoFlags) +{ + return WI_AreAllFlagsClear(packageInfoFlags, PACKAGE_PROPERTY_BUNDLE | PACKAGE_PROPERTY_FRAMEWORK | PACKAGE_PROPERTY_OPTIONAL | PACKAGE_PROPERTY_RESOURCE); +} + +STDAPI GetPackageFilePathInPackageGraph( + _In_ PCWSTR filename, + _In_ GetPackageFilePathOptions options, + _Outptr_result_maybenull_ PWSTR* packageFile) noexcept try +{ + *packageFile = nullptr; + + RETURN_HR_IF(E_INVALIDARG, ::Microsoft::Foundation::String::IsNullOrEmpty(filename)); + + // Ideally we'd pass our filtering needs down to package graph query API (e.g. GetCurrentPackageGraph) + // but it doesn't quite give us the semantics we need, so we'll do it the hard way. + // + // We can (partially) optimize filtering checks for PackageType=Framework|Resource|Optional and HostRuntime|Static|Dynamic + // by a simple bitmask check. We can only determine if PackageType=Main by the absence of other properties. + const UINT32 flagsMask{ (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchFrameworkPackages) ? PACKAGE_PROPERTY_FRAMEWORK : 0u) | + (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchResourcePackages) ? PACKAGE_PROPERTY_RESOURCE : 0u) | + (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchOptionalPackages) ? PACKAGE_PROPERTY_OPTIONAL : 0u) | + (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchHostRuntimeDependencies) ? PACKAGE_PROPERTY_HOSTRUNTIME : 0u) | + (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchStaticDependencies) ? PACKAGE_PROPERTY_STATIC : 0u) | + (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchDynamicDependencies) ? PACKAGE_PROPERTY_DYNAMIC : 0u) }; + + // Search the package graph + UINT32 flags{ PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC }; + uint32_t packageGraphCount{}; + const PACKAGE_INFO* packageInfo{}; + wil::unique_cotaskmem_ptr buffer; + RETURN_IF_FAILED(::AppModel::PackageGraph::GetCurrentPackageGraph(flags, packageGraphCount, packageInfo, buffer)); + for (uint32_t index=0; index < packageGraphCount; ++index) + { + const auto& pi{ packageInfo[index] }; + + // Default behavior is search everything. Do we need to filter to a subset? + if (options != GetPackageFilePathOptions_None) + { + // Does this package meet any of the simple filtering criteria: Framework|Resource|Optional|HostRuntime|Static|Dynamic + if (WI_AreAllFlagsClear(pi.flags, flagsMask)) + { + // Nope! Complex filtering time. Is this a Main package? + if (IsMainPackage(pi.flags)) + { + // Are Main packages included in our search? + if (WI_IsFlagClear(options, GetPackageFilePathOptions::GetPackageFilePathOptions_SearchMainPackages)) + { + // It's a Main package but we're not interested in Main packages. Skip it + continue; + } + } + else + { + // It's not a Main package, and it doesn't meet any other filter criteria. Skip it + continue; + } + } + } + + // This package is included in our search. Check for the file + const auto packageFullName{ pi.packageFullName }; + auto path{ appmodel::get_package_file(packageFullName, filename, options) }; + if (!path.empty()) + { + auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) }; + *packageFile = absoluteFilename.release(); + break; + } + } + return S_OK; +} +CATCH_RETURN(); diff --git a/dev/Package/package_runtime.h b/dev/Package/package_runtime.h index b24fea1617..9e28ea5088 100644 --- a/dev/Package/package_runtime.h +++ b/dev/Package/package_runtime.h @@ -4,28 +4,78 @@ #if !defined(PACKAGE_RUNTIME_H) #define PACKAGE_RUNTIME_H +/// Options for GetPackageFilePath*() functions +typedef enum GetPackageFilePathOptions +{ + /// Default behavior + GetPackageFilePathOptions_None = 0, + + /// Include the package's Install path in the file search order + GetPackageFilePathOptions_SearchInstallPath = 0x0001, + + /// Include the package's Mutable path (if it has one) in the file search order + GetPackageFilePathOptions_SearchMutablePath = 0x0002, + + /// Include the package's Machine External path (if it has one) in the file search order + GetPackageFilePathOptions_SearchMachineExternalPath = 0x0004, + + /// Include the package's User External path (if it has one) in the file search order + GetPackageFilePathOptions_SearchUserExternalPath = 0x0008, + + /// Include Main packages in the file search order + GetPackageFilePathOptions_SearchMainPackages = 0x0010, + + /// Include Framework packages in the file search order + GetPackageFilePathOptions_SearchFrameworkPackages = 0x0020, + + /// Include Optional packages in the file search order + GetPackageFilePathOptions_SearchOptionalPackages = 0x0040, + + /// Include Resource packages in the file search order + GetPackageFilePathOptions_SearchResourcePackages = 0x0080, + + /// Include HostRuntime dependencies in the file search order + GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0100, + + /// Include Static package dependencies in the file search order + /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted + /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + GetPackageFilePathOptions_SearchStaticDependencies = 0x0200, + + /// Include Dynamic package dependencies in the file search order + /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted + /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + GetPackageFilePathOptions_SearchDynamicDependencies = 0x0400, +} GetPackageFilePathOptions; + /// Return the absolute path to the file in the package. /// @param packageFullName the package, or NULL or "" to use the current process' package identity. /// @param filename file to locate. +/// @param options options for the search. /// @param packageFile absolute path to the packaged file, or NULL if not found. Allocated via HeapAlloc; use HeapFree to deallocate /// @note The package path search order is External(User or Machine) -> Mutable -> Install. /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 -STDAPI FindPackageFile( - _In_ PCWSTR packageFullName, +/// @see GetPackageFilePathInPackageGraph() +/// @see GetPackageFilePathOptions +STDAPI GetPackageFilePath( + PCWSTR packageFullName, _In_ PCWSTR filename, + _In_ GetPackageFilePathOptions options, _Outptr_result_maybenull_ PWSTR* packageFile) noexcept; -/// Return the absolute path to the file in the package graph. -/// @param packageFullName the package, or NULL or "" to use the current process' package identity. +/// Return the absolute path to the file in the caller's package graph. /// @param filename file to locate. +/// @param options options for the search. /// @param packageFile absolute path to the packaged file, or NULL if not found. Allocated via HeapAlloc; use HeapFree to deallocate -/// @note The package paths search order is External(User or Machine) -> Mutable -> Install. +/// @note The search order is External(User or Machine) -> Mutable -> Install for each package in the package graph. /// @note If a package has a UserExternal location then MachineExternal location is not checked (even if the package has one). /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 -STDAPI FindPackageFileInPackageGraph( - _In_ PCWSTR packageFullName, +/// @see GetPackageFilePath() +/// @see GetPackageFilePathOptions +STDAPI GetPackageFilePathInPackageGraph( _In_ PCWSTR filename, + _In_ GetPackageFilePathOptions options, _Outptr_result_maybenull_ PWSTR* packageFile) noexcept; #endif // PACKAGE_RUNTIME_H diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def index 5d4f1b212c..582b0f5e39 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def @@ -30,4 +30,5 @@ EXPORTS WindowsAppRuntime_EnsureIsLoaded - FindPackageFile + GetPackageFilePath + GetPackageFilePathInPackageGraph diff --git a/test/ABForward/FunctionalTests.cpp b/test/ABForward/FunctionalTests.cpp index b05d3d33cc..16345e8547 100644 --- a/test/ABForward/FunctionalTests.cpp +++ b/test/ABForward/FunctionalTests.cpp @@ -110,7 +110,7 @@ namespace Test::ABForward TEST_METHOD(BatteryStatus) { - auto batteryStatus{ winrt::Microsoft::Windows::System::Power::PowerManager::BatteryStatus() }; + [[maybe_unused]] auto batteryStatus{ winrt::Microsoft::Windows::System::Power::PowerManager::BatteryStatus() }; } TEST_METHOD(DeploymentManager) diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h new file mode 100644 index 0000000000..5fe631e83f --- /dev/null +++ b/test/Package/API/PackageTests.Packages.h @@ -0,0 +1,218 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#ifndef __PACKAGETESTS_PACKAGES_H +#define __PACKAGETESTS_PACKAGES_H + +namespace Test::Package::Tests{} +// +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; + +namespace Test::Packages +{ +namespace Mutable +{ + constexpr PCWSTR c_packageDirName = L"Package.Test.Mutable.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.Package.Mutable_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName = L"Test.Package.Mutable_1.2.3.4_neutral__8wekyb3d8bbwe"; +} +namespace UserExternal +{ + constexpr PCWSTR c_packageDirName = L"Package.Test.UserExternal.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.Package.UserExternal_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName = L"Test.Package.UserExternal_1.2.3.4_neutral__8wekyb3d8bbwe"; +} +namespace MachineExternal +{ + constexpr PCWSTR c_packageDirName = L"Package.Test.MachineExternal.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.Package.MachineExternal_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName = L"Test.Package.MachineExternal_1.2.3.4_neutral__8wekyb3d8bbwe"; +} +} + +namespace Test::Package::Tests +{ + namespace TP = ::Test::Packages; + //namespace TPF = ::Test::Packages::Framework; + + inline bool IsPackageRegistered_Mutable() + { + return TP::IsPackageRegistered(TP::Mutable::c_packageFullName); + } + inline bool IsPackageStaged_Mutable() + { + return TP::IsPackageStaged(TP::Mutable::c_packageFullName); + } + inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_Mutable() + { + return TP::GetPackageStatus(TP::Mutable::c_packageFullName); + } + inline void AddPackage_Mutable() + { + TP::AddPackageIfNecessary(TP::Mutable::c_packageDirName, TP::Mutable::c_packageFullName); + } + inline void AddPackageDefer_Mutable() + { + TP::AddPackageDeferIfNecessary(TP::Mutable::c_packageDirName, TP::Mutable::c_packageFullName); + } + inline void StagePackage_Mutable() + { + TP::StagePackageIfNecessary(TP::Mutable::c_packageDirName, TP::Mutable::c_packageFullName); + } + inline void RegisterPackage_Mutable() + { + TP::RegisterPackageIfNecessary(TP::Mutable::c_packageFullName); + } + inline void RemovePackage_Mutable() + { + if (IsPackageRegistered_Mutable()) + { + TP::RemovePackage(TP::Mutable::c_packageFullName); + } + else if (IsPackageStaged_Mutable()) + { + // We can't directly remove a Stage package not registered for current user + // w/o admin privilege but we can add it to make it registered and then remove it. + AddPackage_Mutable(); + TP::RemovePackage(TP::Mutable::c_packageFullName); + } + } + inline void RemovePackageFamily_Mutable() + { + RemovePackage_Mutable(); + } + inline bool IsPackageProvisioned_Mutable() + { + return TP::IsPackageProvisioned(TP::Mutable::c_packageFamilyName); + } + inline void ProvisionPackage_Mutable() + { + TP::ProvisionPackage(TP::Mutable::c_packageFamilyName); + } + inline void DeprovisionPackage_Mutable() + { + TP::DeprovisionPackageIfNecessary(TP::Mutable::c_packageFamilyName); + } + + inline bool IsPackageRegistered_UserExternal() + { + return TP::IsPackageRegistered(TP::UserExternal::c_packageFullName); + } + inline bool IsPackageStaged_UserExternal() + { + return TP::IsPackageStaged(TP::UserExternal::c_packageFullName); + } + inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_UserExternal() + { + return TP::GetPackageStatus(TP::UserExternal::c_packageFullName); + } + inline void AddPackage_UserExternal() + { + TP::AddPackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName); + } + inline void AddPackageDefer_UserExternal() + { + TP::AddPackageDeferIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName); + } + inline void StagePackage_UserExternal() + { + TP::StagePackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName); + } + inline void RegisterPackage_UserExternal() + { + TP::RegisterPackageIfNecessary(TP::UserExternal::c_packageFullName); + } + inline void RemovePackage_UserExternal() + { + if (IsPackageRegistered_UserExternal()) + { + TP::RemovePackage(TP::UserExternal::c_packageFullName); + } + else if (IsPackageStaged_UserExternal()) + { + // We can't directly remove a Stage package not registered for current user + // w/o admin privilege but we can add it to make it registered and then remove it. + AddPackage_UserExternal(); + TP::RemovePackage(TP::UserExternal::c_packageFullName); + } + } + inline void RemovePackageFamily_UserExternal() + { + RemovePackage_UserExternal(); + } + inline bool IsPackageProvisioned_UserExternal() + { + return TP::IsPackageProvisioned(TP::UserExternal::c_packageFamilyName); + } + inline void ProvisionPackage_UserExternal() + { + TP::ProvisionPackage(TP::UserExternal::c_packageFamilyName); + } + inline void DeprovisionPackage_UserExternal() + { + TP::DeprovisionPackageIfNecessary(TP::UserExternal::c_packageFamilyName); + } + + inline bool IsPackageRegistered_MachineExternal() + { + return TP::IsPackageRegistered(TP::MachineExternal::c_packageFullName); + } + inline bool IsPackageStaged_MachineExternal() + { + return TP::IsPackageStaged(TP::MachineExternal::c_packageFullName); + } + inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_MachineExternal() + { + return TP::GetPackageStatus(TP::MachineExternal::c_packageFullName); + } + inline void AddPackage_MachineExternal() + { + TP::AddPackageIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName); + } + inline void AddPackageDefer_MachineExternal() + { + TP::AddPackageDeferIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName); + } + inline void StagePackage_MachineExternal() + { + TP::StagePackageIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName); + } + inline void RegisterPackage_MachineExternal() + { + TP::RegisterPackageIfNecessary(TP::MachineExternal::c_packageFullName); + } + inline void RemovePackage_MachineExternal() + { + if (IsPackageRegistered_MachineExternal()) + { + TP::RemovePackage(TP::MachineExternal::c_packageFullName); + } + else if (IsPackageStaged_MachineExternal()) + { + // We can't directly remove a Stage package not registered for current user + // w/o admin privilege but we can add it to make it registered and then remove it. + AddPackage_MachineExternal(); + TP::RemovePackage(TP::MachineExternal::c_packageFullName); + } + } + inline void RemovePackageFamily_MachineExternal() + { + RemovePackage_MachineExternal(); + } + inline bool IsPackageProvisioned_MachineExternal() + { + return TP::IsPackageProvisioned(TP::MachineExternal::c_packageFamilyName); + } + inline void ProvisionPackage_MachineExternal() + { + TP::ProvisionPackage(TP::MachineExternal::c_packageFamilyName); + } + inline void DeprovisionPackage_MachineExternal() + { + TP::DeprovisionPackageIfNecessary(TP::MachineExternal::c_packageFamilyName); + } +} + +#endif // __PACKAGETESTS_PACKAGES_H diff --git a/test/Package/API/PackageTests.vcxproj b/test/Package/API/PackageTests.vcxproj index 053f7a18fc..73d841fc34 100644 --- a/test/Package/API/PackageTests.vcxproj +++ b/test/Package/API/PackageTests.vcxproj @@ -80,7 +80,7 @@ Use true pch.h - $(RepoRoot)\test\inc;$(RepoRoot)\dev\common;$(VCInstallDir)UnitTest\include;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) + $(MSBuildThisFileDirectory);$(RepoRoot)\test\inc;$(RepoRoot)\dev\common;$(VCInstallDir)UnitTest\include;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) $(RepoRoot);%(AdditionalIncludeDirectories) diff --git a/test/Package/API/PackageTests.vcxproj.filters b/test/Package/API/PackageTests.vcxproj.filters index c0c02b67c9..74809d9fc7 100644 --- a/test/Package/API/PackageTests.vcxproj.filters +++ b/test/Package/API/PackageTests.vcxproj.filters @@ -26,6 +26,9 @@ + + Header Files + Header Files diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp index ca22d97ada..74b68a83d8 100644 --- a/test/Package/API/PackageTests_CPP.cpp +++ b/test/Package/API/PackageTests_CPP.cpp @@ -7,6 +7,8 @@ #include +#include "PackageTests.Packages.h" + namespace TD = ::Test::Diagnostics; namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; @@ -14,6 +16,7 @@ namespace TD = ::Test::Diagnostics; namespace Test::Package::Tests { + const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; class PackageTests_CPP @@ -27,42 +30,114 @@ namespace Test::Package::Tests TEST_CLASS_SETUP(ClassSetup) { ::TB::Setup(); + + //RemovePackage_MachineExternal(); + //RemovePackage_UserExternal(); + //RemovePackage_Mutable(); + + //AddPackage_Mutable(); + //AddPackage_UserExternal(); + //AddPackage_MachineExternal(); + return true; } TEST_CLASS_CLEANUP(ClassCleanup) { ::TB::Cleanup(); + + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + RemovePackage_Mutable(); + return true; } - TEST_METHOD(FindPackageFile_InvalidParameter) + TEST_METHOD(GetPackageFilePath_InvalidParameter) { PCWSTR packageFullName{ Framework_PackageFullName }; PCWSTR noFileName{}; wil::unique_process_heap_ptr absoluteFilename; - VERIFY_ARE_EQUAL(E_INVALIDARG, ::FindPackageFile(packageFullName, noFileName, wil::out_param(absoluteFilename)); + const auto options{ GetPackageFilePathOptions_None }; + VERIFY_ARE_EQUAL(E_INVALIDARG, ::GetPackageFilePath(packageFullName, noFileName, options, wil::out_param(absoluteFilename))); } - TEST_METHOD(FindPackageFile_NullPackageFullName_UnpackagedProcess) + TEST_METHOD(GetPackageFilePath_NullPackageFullName_UnpackagedProcess_NoPackage) { PCWSTR noPackageFullName{}; PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_None }; wil::unique_process_heap_ptr absoluteFilename; - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), ::FindPackageFile(noPackageFullName, fileName, wil::out_param(absoluteFilename))); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), ::GetPackageFilePath(noPackageFullName, fileName, options, wil::out_param(absoluteFilename))); } - TEST_METHOD(FindPackageFile_NullPackageFullName_PackagedProcess) + TEST_METHOD(GetPackageFilePath_NullPackageFullName_PackagedProcess_InstallPath) { //TODO } - TEST_METHOD(FindPackageFile_InstallPath) + TEST_METHOD(GetPackageFilePath) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_None }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + //TODO + } + + TEST_METHOD(GetPackageFilePath_InstallPath) { PCWSTR packageFullName{ Framework_PackageFullName }; PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath }; wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::FindPackageFile(noPackageFullName, fileName, wil::out_param(absoluteFilename))); + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + //TODO + } + + TEST_METHOD(GetPackageFilePath_MutablePath) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_MachineExternalPath) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_UserExternalPath) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_FilterPackageType_Framework_NoMatch) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_Filter_Static_NoMatch) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_Filter_Dynamic_NoMatch) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_Filter_Static) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_Filter_Dynamic) + { //TODO } }; diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index c1868e9a69..a3a36565fb 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -14,6 +14,7 @@ static const winrt::hstring null_hstring; namespace Test::Package::Tests { + const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; class PackageTests_WinRT @@ -27,22 +28,49 @@ namespace Test::Package::Tests TEST_CLASS_SETUP(ClassSetup) { ::TB::Setup(); + + //RemovePackage_MachineExternal(); + //RemovePackage_UserExternal(); + //RemovePackage_Mutable(); + + //AddPackage_Mutable(); + //AddPackage_UserExternal(); + //AddPackage_MachineExternal(); + return true; } TEST_CLASS_CLEANUP(ClassCleanup) { ::TB::Cleanup(); + + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + RemovePackage_Mutable(); + return true; } - TEST_METHOD(FindPackageFile_InvalidParameter) + TEST_METHOD(GetFilePath_InvalidParameter) { try { winrt::hstring packageFullName{ Framework_PackageFullName }; winrt::hstring noFileName; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::FindPackageFile(packageFullName, noFileName); + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(packageFullName, noFileName); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + + try + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring noFileName; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(packageFullName, noFileName, options); VERIFY_FAIL(L"Success is not expected"); } catch (winrt::hresult_error& e) @@ -51,13 +79,26 @@ namespace Test::Package::Tests } } - TEST_METHOD(FindPackageFile_NullPackageFullName_UnpackagedProcess) + TEST_METHOD(GetFilePath_NullPackageFullName_UnpackagedProcess_NoPackage) { try { winrt::hstring noPackageFullName; winrt::hstring fileName{ L"AppxManifest.xml" }; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::FindPackageFile(noPackageFullName, fileName); + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noPackageFullName, fileName); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + + try + { + winrt::hstring noPackageFullName; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noPackageFullName, fileName, options); VERIFY_FAIL(L"Success is not expected"); } catch (winrt::hresult_error& e) @@ -66,16 +107,86 @@ namespace Test::Package::Tests } } - TEST_METHOD(FindPackageFile_NullPackageFullName_PackagedProcess) + TEST_METHOD(GetFilePath_NullPackageFullName_PackagedProcess_InstallPath) { //TODO } - TEST_METHOD(FindPackageFile_InstallPath) + TEST_METHOD(GetFilePath) { winrt::hstring packageFullName{ Framework_PackageFullName }; winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::FindPackageFile(packageFullName, fileName) }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) }; + //TODO + } + + TEST_METHOD(GetFilePath_InstallPath) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + //TODO + } + + TEST_METHOD(GetFilePath_MutablePath) + { + //TODO + } + + TEST_METHOD(GetFilePath_MachineExternalPath) + { + //TODO + } + + TEST_METHOD(GetFilePath_UserExternalPath) + { + //TODO + } + + TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) + { + winrt::hstring packageFullName{ Main_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Static_NoMatch) + { + //TODO + } + + TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Static) + { + //TODO + } + + TEST_METHOD(GetFilePath_Filter_Dynamic) + { //TODO } }; diff --git a/test/Package/API/pch.h b/test/Package/API/pch.h index aa6962f8da..efe9e7ce67 100644 --- a/test/Package/API/pch.h +++ b/test/Package/API/pch.h @@ -32,4 +32,6 @@ #include #include +#include + #endif //PCH_H diff --git a/test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj b/test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj new file mode 100644 index 0000000000..ca587985ff --- /dev/null +++ b/test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj @@ -0,0 +1,120 @@ + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {3347E246-6BF5-469F-9C91-7D6E33B66786} + VCProjectVersion + Package.Test.UserExternal.Msix + en-US + 16.0 + 10.0.26100.0 + 10.0.17763.0 + 10.0 + + + Utility + v143 + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(TargetName) + + + + + + + $(RepoTestCertificatePFX) + $(RepoTestCertificatePassword) + + + + + + + + + + + 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}. + + + + + + + + + diff --git a/test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj.filters b/test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj.filters new file mode 100644 index 0000000000..93e09be5b1 --- /dev/null +++ b/test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj.filters @@ -0,0 +1,12 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + diff --git a/test/Package/data/MachineExternal/Package.MachineExternal.vcxproj.filters b/test/Package/data/MachineExternal/Package.MachineExternal.vcxproj.filters new file mode 100644 index 0000000000..fb91a1a002 --- /dev/null +++ b/test/Package/data/MachineExternal/Package.MachineExternal.vcxproj.filters @@ -0,0 +1,15 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + diff --git a/test/Package/data/MachineExternal/appxmanifest.xml b/test/Package/data/MachineExternal/appxmanifest.xml new file mode 100644 index 0000000000..ee7774c7a4 --- /dev/null +++ b/test/Package/data/MachineExternal/appxmanifest.xml @@ -0,0 +1,29 @@ + + + + + + + + Test.Package.MachineExternal + Microsoft Corporation + logo.png + true + + + + + + + + + + diff --git a/test/Package/data/MachineExternal/logo.png b/test/Package/data/MachineExternal/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd7c0ce4d75499f6bcf2224412a39a23d5298a3 GIT binary patch literal 5632 zcmai2`%{$H8D2nfVVCw>^?ljX7tuE<3$yP(3tg4|V>Nn)Bz+ezBQ zbWA7d)V68bM#q_4S~J>arrIP;tc^))sw6s2e(A)S=3nUZ@Sc3D&U8BSywCfd_k8=E zbKcAO7{0yy{<9tG%vg8TubDZH^3c8trD--94Z+2(Su? z5HsbgC&gI%`pJu8fpc>~!^c2+%~yT!#8n_WfU-7Gn$4ZZQu-ol0o~ zTPDSG>sis|={t?EtOY!P^#}vBFa^qjm=uYrAApxI)xNXAi)bgE+#)!`OSo?6nuda0i%*VMzV;7r|qY zBO4KeA=tY|G=H}i3Gzb5xXZ*-DD9NuIQ9omf;6Kfv#hB0jySF2c%8R%BjrN3Kq=D-%f*D zqoeIIk>%u(90gupF#xLw=!WEpNso#{Q^S;U?w7gD9V&9CWGu|(UH5-*4vO!o7O!yO zk$PsbrWP~^u|fPNcq8Nt9_5}EAU#{c_(SGP!1$@xcn|;Q`Cq70$z(WGpNg=pa;Q~3^zyoJ4(>@558F}$FD`(YZ_=DF zxIo2NHETyhaja>$*)PKr@je*l$u#i2%OD+W+mfcZ8ce=)1P zUd&FGBQO-f8WyxnaG@JNZ|6@Y#aHj=a)PMR4j9|Dv6;~<7-wqvkT-7^_?s7gL>t2T zUVfxtCg1@AT&8R~UPfVIqI*RNs}@R`zo*uQJJS+Z4#npfX@P#PX7auSg85?I3I6@! zX&6kG25&0N{yNY`EAe}!Is=yP?mOV4rTabI2}SN5%~{PD0(}gtAkq!Jp9B=J1puoH zRQlCx;Cb;dsVtCX8UE#M=->{^4B`gQSBiN|^T6<*0)2IPk!8`qAzzmiJ(za7` z@or6un_6CG+75_2>Y%HCkY7k(WB}9=3S#N;X$@OK#H{2+4Ycu0V=6YP9pEWmDVF&? z9{24xZ=ILHJYPBc`P?9>E! zm+oB99){7q2J)oGh>sTrz}47&y4+y9W7rSjehe8S z0YfPm@FuJpc|)l{?Ka>4;d6Y@Ci5(l$Dk5EIRt-Y@a?f1f9Q3>>ByH~c&)xWmtgj@ z2Q>s>sl7A&ON^MHO`XMyq50bPN{rDkdLb+$TZS_yR(H(!`A-uu+PMuR;EF&VWYnr` zt^wTqwZ(dJX{k&`$5o$iOHDV8!gc+X9V!mZSphqXZg{sm8TR3O-dPiCpI@wmUas%_ z`uusQij3J3ZeZgNY`>KW&D;6$yHH%agBJy`Q25s?{P|JHo)pWm`JRLv-XvoXfVF2) zK?zrV`bdlnHS*w=tUwD_%j4;c(MIb`ej~5d{Zk{M>eFTq=N!PQIj%0`{4L@W9z6-& zk_&pIj0PCPKte6}`qLmT#As{aj0R?#$EnY03JtMXf_c}TXokg2C|r3dfm_vZ`%=J$ z0dp=0-j`h2VTw<;@G37-=V{d*6eEl=;T2>qnbnJ{GO3Tv^sfun6D)VOy`YU13?wkm zCVK_Xu3`4pndv7i?6>u2K-_j*CPNfg7di|D=+_4P=5#l#cyS~{S>{38%SqyNLK(zN zi#x#4n2aV^X%qZu@U$|c@ux3|S*3Zn10e0jt6-zi$dhenrD*v0-Gf6c$gFEu*y~p> zhRak_nR#~G?b8^j27<-=BO*!W6E^dEqhW?Y0T@q)jX`H-0eAJ@!BSp24#*a!9Qg8Q zpn`*+y;5pO*_jw;W2Q>=;(nReS z1&;PIXJ!Vh1=7pTs)hiCZI#?B@F@?epYq*(UB(<`XaD()Qf&xh{l}_;7*X8^FF$zx zZ5Soxs<~mes*|ZrsI$~E;(xyg0+!dj^B$E>3~M$r>XW%1s0jmG#Z>^R%mBqke0T}! z^Yd%`(NI9$n^Q{|3DQdbXEA8cFlzf5p-qt42Jx#`gxuiaf$6p`@Z=FU(`#&IL9#pr z4X2=&GF0T4D!~_Tx+7SS+`E9ECORrXHm*_3xIYXPp2=d5c$3%9c2ABSRD}v(lLchm z5u>sbgAsdhg1t2e*{UXB0uBqWz;XV8F~#!qvnq6Eo*5Wood8w2w=No6^rrF|PIE#O zPqb3f5B9~0CoTfIm}>!pS)ghU8$HaKuNS9qqBe-s?Gihei#0RIz;vi+Fe^ZXd;Oj3 z?`i&_4~Sr3QJ)^p%MdKq)aE4>o}7#b~%{%)&E4D6~DnKD8# zX_4GcgwGJng4&5Z1|F=^O#7ijX*!G;V0BniFxa`lyOS3tuoW^03CIxKz;$C{J1zF9 zr0@Pk({G7qO^t@hQ%o0-0AbGgp$^N|?{hKZk>G9pd$5m?~`QKgGu-lTy z^7myjx4gZoc>$ENuZmn%VBR9CAi~RBJfUR`#I^Xfst!pqZe`eeA6$5j1st|?91N%* zWy55N4{$ft3m{fRm5O>8>y_bRj~0i39tIz3%ButOlK>?0-JhKUO|RU1!@vaMU$eT_ O#tu8o`e9I1 + + + + + diff --git a/test/Package/data/Mutable/Package.Mutable.msix.vcxproj b/test/Package/data/Mutable/Package.Mutable.msix.vcxproj new file mode 100644 index 0000000000..f343603d1d --- /dev/null +++ b/test/Package/data/Mutable/Package.Mutable.msix.vcxproj @@ -0,0 +1,120 @@ + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {469EE821-0FB5-4B9A-82D9-91292B0593D0} + VCProjectVersion + Package.Test.Mutable.Msix + en-US + 16.0 + 10.0.26100.0 + 10.0.17763.0 + 10.0 + + + Utility + v143 + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(TargetName) + + + + + + + $(RepoTestCertificatePFX) + $(RepoTestCertificatePassword) + + + + + + + + + + + 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}. + + + + + + + + + diff --git a/test/Package/data/Mutable/Package.Mutable.msix.vcxproj.filters b/test/Package/data/Mutable/Package.Mutable.msix.vcxproj.filters new file mode 100644 index 0000000000..93e09be5b1 --- /dev/null +++ b/test/Package/data/Mutable/Package.Mutable.msix.vcxproj.filters @@ -0,0 +1,12 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + diff --git a/test/Package/data/Mutable/Package.Mutable.vcxproj.filters b/test/Package/data/Mutable/Package.Mutable.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/Package/data/Mutable/Package.Mutable.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + + + diff --git a/test/Package/data/Mutable/appxmanifest.xml b/test/Package/data/Mutable/appxmanifest.xml new file mode 100644 index 0000000000..672ceff746 --- /dev/null +++ b/test/Package/data/Mutable/appxmanifest.xml @@ -0,0 +1,40 @@ + + + + + + + + Test.Package.Mutable + Microsoft Corporation + logo.png + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Package/data/Mutable/logo.png b/test/Package/data/Mutable/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd7c0ce4d75499f6bcf2224412a39a23d5298a3 GIT binary patch literal 5632 zcmai2`%{$H8D2nfVVCw>^?ljX7tuE<3$yP(3tg4|V>Nn)Bz+ezBQ zbWA7d)V68bM#q_4S~J>arrIP;tc^))sw6s2e(A)S=3nUZ@Sc3D&U8BSywCfd_k8=E zbKcAO7{0yy{<9tG%vg8TubDZH^3c8trD--94Z+2(Su? z5HsbgC&gI%`pJu8fpc>~!^c2+%~yT!#8n_WfU-7Gn$4ZZQu-ol0o~ zTPDSG>sis|={t?EtOY!P^#}vBFa^qjm=uYrAApxI)xNXAi)bgE+#)!`OSo?6nuda0i%*VMzV;7r|qY zBO4KeA=tY|G=H}i3Gzb5xXZ*-DD9NuIQ9omf;6Kfv#hB0jySF2c%8R%BjrN3Kq=D-%f*D zqoeIIk>%u(90gupF#xLw=!WEpNso#{Q^S;U?w7gD9V&9CWGu|(UH5-*4vO!o7O!yO zk$PsbrWP~^u|fPNcq8Nt9_5}EAU#{c_(SGP!1$@xcn|;Q`Cq70$z(WGpNg=pa;Q~3^zyoJ4(>@558F}$FD`(YZ_=DF zxIo2NHETyhaja>$*)PKr@je*l$u#i2%OD+W+mfcZ8ce=)1P zUd&FGBQO-f8WyxnaG@JNZ|6@Y#aHj=a)PMR4j9|Dv6;~<7-wqvkT-7^_?s7gL>t2T zUVfxtCg1@AT&8R~UPfVIqI*RNs}@R`zo*uQJJS+Z4#npfX@P#PX7auSg85?I3I6@! zX&6kG25&0N{yNY`EAe}!Is=yP?mOV4rTabI2}SN5%~{PD0(}gtAkq!Jp9B=J1puoH zRQlCx;Cb;dsVtCX8UE#M=->{^4B`gQSBiN|^T6<*0)2IPk!8`qAzzmiJ(za7` z@or6un_6CG+75_2>Y%HCkY7k(WB}9=3S#N;X$@OK#H{2+4Ycu0V=6YP9pEWmDVF&? z9{24xZ=ILHJYPBc`P?9>E! zm+oB99){7q2J)oGh>sTrz}47&y4+y9W7rSjehe8S z0YfPm@FuJpc|)l{?Ka>4;d6Y@Ci5(l$Dk5EIRt-Y@a?f1f9Q3>>ByH~c&)xWmtgj@ z2Q>s>sl7A&ON^MHO`XMyq50bPN{rDkdLb+$TZS_yR(H(!`A-uu+PMuR;EF&VWYnr` zt^wTqwZ(dJX{k&`$5o$iOHDV8!gc+X9V!mZSphqXZg{sm8TR3O-dPiCpI@wmUas%_ z`uusQij3J3ZeZgNY`>KW&D;6$yHH%agBJy`Q25s?{P|JHo)pWm`JRLv-XvoXfVF2) zK?zrV`bdlnHS*w=tUwD_%j4;c(MIb`ej~5d{Zk{M>eFTq=N!PQIj%0`{4L@W9z6-& zk_&pIj0PCPKte6}`qLmT#As{aj0R?#$EnY03JtMXf_c}TXokg2C|r3dfm_vZ`%=J$ z0dp=0-j`h2VTw<;@G37-=V{d*6eEl=;T2>qnbnJ{GO3Tv^sfun6D)VOy`YU13?wkm zCVK_Xu3`4pndv7i?6>u2K-_j*CPNfg7di|D=+_4P=5#l#cyS~{S>{38%SqyNLK(zN zi#x#4n2aV^X%qZu@U$|c@ux3|S*3Zn10e0jt6-zi$dhenrD*v0-Gf6c$gFEu*y~p> zhRak_nR#~G?b8^j27<-=BO*!W6E^dEqhW?Y0T@q)jX`H-0eAJ@!BSp24#*a!9Qg8Q zpn`*+y;5pO*_jw;W2Q>=;(nReS z1&;PIXJ!Vh1=7pTs)hiCZI#?B@F@?epYq*(UB(<`XaD()Qf&xh{l}_;7*X8^FF$zx zZ5Soxs<~mes*|ZrsI$~E;(xyg0+!dj^B$E>3~M$r>XW%1s0jmG#Z>^R%mBqke0T}! z^Yd%`(NI9$n^Q{|3DQdbXEA8cFlzf5p-qt42Jx#`gxuiaf$6p`@Z=FU(`#&IL9#pr z4X2=&GF0T4D!~_Tx+7SS+`E9ECORrXHm*_3xIYXPp2=d5c$3%9c2ABSRD}v(lLchm z5u>sbgAsdhg1t2e*{UXB0uBqWz;XV8F~#!qvnq6Eo*5Wood8w2w=No6^rrF|PIE#O zPqb3f5B9~0CoTfIm}>!pS)ghU8$HaKuNS9qqBe-s?Gihei#0RIz;vi+Fe^ZXd;Oj3 z?`i&_4~Sr3QJ)^p%MdKq)aE4>o}7#b~%{%)&E4D6~DnKD8# zX_4GcgwGJng4&5Z1|F=^O#7ijX*!G;V0BniFxa`lyOS3tuoW^03CIxKz;$C{J1zF9 zr0@Pk({G7qO^t@hQ%o0-0AbGgp$^N|?{hKZk>G9pd$5m?~`QKgGu-lTy z^7myjx4gZoc>$ENuZmn%VBR9CAi~RBJfUR`#I^Xfst!pqZe`eeA6$5j1st|?91N%* zWy55N4{$ft3m{fRm5O>8>y_bRj~0i39tIz3%ButOlK>?0-JhKUO|RU1!@vaMU$eT_ O#tu8o`e9I1 + + + + + diff --git a/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj b/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj new file mode 100644 index 0000000000..37699d7afb --- /dev/null +++ b/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj @@ -0,0 +1,120 @@ + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563} + VCProjectVersion + Package.Test.UserExternal.Msix + en-US + 16.0 + 10.0.26100.0 + 10.0.17763.0 + 10.0 + + + Utility + v143 + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(TargetName) + + + + + + + $(RepoTestCertificatePFX) + $(RepoTestCertificatePassword) + + + + + + + + + + + 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}. + + + + + + + + + diff --git a/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj.filters b/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj.filters new file mode 100644 index 0000000000..93e09be5b1 --- /dev/null +++ b/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj.filters @@ -0,0 +1,12 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + diff --git a/test/Package/data/UserExternal/Package.UserExternal.vcxproj.filters b/test/Package/data/UserExternal/Package.UserExternal.vcxproj.filters new file mode 100644 index 0000000000..fb91a1a002 --- /dev/null +++ b/test/Package/data/UserExternal/Package.UserExternal.vcxproj.filters @@ -0,0 +1,15 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + diff --git a/test/Package/data/UserExternal/appxmanifest.xml b/test/Package/data/UserExternal/appxmanifest.xml new file mode 100644 index 0000000000..cb7dccc8f0 --- /dev/null +++ b/test/Package/data/UserExternal/appxmanifest.xml @@ -0,0 +1,29 @@ + + + + + + + + Test.Package.UserExternal + Microsoft Corporation + logo.png + true + + + + + + + + + + diff --git a/test/Package/data/UserExternal/logo.png b/test/Package/data/UserExternal/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd7c0ce4d75499f6bcf2224412a39a23d5298a3 GIT binary patch literal 5632 zcmai2`%{$H8D2nfVVCw>^?ljX7tuE<3$yP(3tg4|V>Nn)Bz+ezBQ zbWA7d)V68bM#q_4S~J>arrIP;tc^))sw6s2e(A)S=3nUZ@Sc3D&U8BSywCfd_k8=E zbKcAO7{0yy{<9tG%vg8TubDZH^3c8trD--94Z+2(Su? z5HsbgC&gI%`pJu8fpc>~!^c2+%~yT!#8n_WfU-7Gn$4ZZQu-ol0o~ zTPDSG>sis|={t?EtOY!P^#}vBFa^qjm=uYrAApxI)xNXAi)bgE+#)!`OSo?6nuda0i%*VMzV;7r|qY zBO4KeA=tY|G=H}i3Gzb5xXZ*-DD9NuIQ9omf;6Kfv#hB0jySF2c%8R%BjrN3Kq=D-%f*D zqoeIIk>%u(90gupF#xLw=!WEpNso#{Q^S;U?w7gD9V&9CWGu|(UH5-*4vO!o7O!yO zk$PsbrWP~^u|fPNcq8Nt9_5}EAU#{c_(SGP!1$@xcn|;Q`Cq70$z(WGpNg=pa;Q~3^zyoJ4(>@558F}$FD`(YZ_=DF zxIo2NHETyhaja>$*)PKr@je*l$u#i2%OD+W+mfcZ8ce=)1P zUd&FGBQO-f8WyxnaG@JNZ|6@Y#aHj=a)PMR4j9|Dv6;~<7-wqvkT-7^_?s7gL>t2T zUVfxtCg1@AT&8R~UPfVIqI*RNs}@R`zo*uQJJS+Z4#npfX@P#PX7auSg85?I3I6@! zX&6kG25&0N{yNY`EAe}!Is=yP?mOV4rTabI2}SN5%~{PD0(}gtAkq!Jp9B=J1puoH zRQlCx;Cb;dsVtCX8UE#M=->{^4B`gQSBiN|^T6<*0)2IPk!8`qAzzmiJ(za7` z@or6un_6CG+75_2>Y%HCkY7k(WB}9=3S#N;X$@OK#H{2+4Ycu0V=6YP9pEWmDVF&? z9{24xZ=ILHJYPBc`P?9>E! zm+oB99){7q2J)oGh>sTrz}47&y4+y9W7rSjehe8S z0YfPm@FuJpc|)l{?Ka>4;d6Y@Ci5(l$Dk5EIRt-Y@a?f1f9Q3>>ByH~c&)xWmtgj@ z2Q>s>sl7A&ON^MHO`XMyq50bPN{rDkdLb+$TZS_yR(H(!`A-uu+PMuR;EF&VWYnr` zt^wTqwZ(dJX{k&`$5o$iOHDV8!gc+X9V!mZSphqXZg{sm8TR3O-dPiCpI@wmUas%_ z`uusQij3J3ZeZgNY`>KW&D;6$yHH%agBJy`Q25s?{P|JHo)pWm`JRLv-XvoXfVF2) zK?zrV`bdlnHS*w=tUwD_%j4;c(MIb`ej~5d{Zk{M>eFTq=N!PQIj%0`{4L@W9z6-& zk_&pIj0PCPKte6}`qLmT#As{aj0R?#$EnY03JtMXf_c}TXokg2C|r3dfm_vZ`%=J$ z0dp=0-j`h2VTw<;@G37-=V{d*6eEl=;T2>qnbnJ{GO3Tv^sfun6D)VOy`YU13?wkm zCVK_Xu3`4pndv7i?6>u2K-_j*CPNfg7di|D=+_4P=5#l#cyS~{S>{38%SqyNLK(zN zi#x#4n2aV^X%qZu@U$|c@ux3|S*3Zn10e0jt6-zi$dhenrD*v0-Gf6c$gFEu*y~p> zhRak_nR#~G?b8^j27<-=BO*!W6E^dEqhW?Y0T@q)jX`H-0eAJ@!BSp24#*a!9Qg8Q zpn`*+y;5pO*_jw;W2Q>=;(nReS z1&;PIXJ!Vh1=7pTs)hiCZI#?B@F@?epYq*(UB(<`XaD()Qf&xh{l}_;7*X8^FF$zx zZ5Soxs<~mes*|ZrsI$~E;(xyg0+!dj^B$E>3~M$r>XW%1s0jmG#Z>^R%mBqke0T}! z^Yd%`(NI9$n^Q{|3DQdbXEA8cFlzf5p-qt42Jx#`gxuiaf$6p`@Z=FU(`#&IL9#pr z4X2=&GF0T4D!~_Tx+7SS+`E9ECORrXHm*_3xIYXPp2=d5c$3%9c2ABSRD}v(lLchm z5u>sbgAsdhg1t2e*{UXB0uBqWz;XV8F~#!qvnq6Eo*5Wood8w2w=No6^rrF|PIE#O zPqb3f5B9~0CoTfIm}>!pS)ghU8$HaKuNS9qqBe-s?Gihei#0RIz;vi+Fe^ZXd;Oj3 z?`i&_4~Sr3QJ)^p%MdKq)aE4>o}7#b~%{%)&E4D6~DnKD8# zX_4GcgwGJng4&5Z1|F=^O#7ijX*!G;V0BniFxa`lyOS3tuoW^03CIxKz;$C{J1zF9 zr0@Pk({G7qO^t@hQ%o0-0AbGgp$^N|?{hKZk>G9pd$5m?~`QKgGu-lTy z^7myjx4gZoc>$ENuZmn%VBR9CAi~RBJfUR`#I^Xfst!pqZe`eeA6$5j1st|?91N%* zWy55N4{$ft3m{fRm5O>8>y_bRj~0i39tIz3%ButOlK>?0-JhKUO|RU1!@vaMU$eT_ O#tu8o`e9I1 + + + + + diff --git a/tools/DevCheck/DevCheck.ps1 b/tools/DevCheck/DevCheck.ps1 index a897494f46..fc810f8e7f 100644 --- a/tools/DevCheck/DevCheck.ps1 +++ b/tools/DevCheck/DevCheck.ps1 @@ -853,13 +853,13 @@ function Install-VCLibsAppx [string]$architecture ) - $install = 0 + $install_issues = 0 - $package = Get-AppxPackage $name | Where-Object Architecture -eq $architecture - if (-not $package) + $packages = Get-AppxPackage $name | Where-Object Architecture -eq $architecture + if (-not $packages) { Write-Host "...$name $($architecture) not installed" - $install++ + $install_issues++ $identity = $null } else @@ -872,35 +872,43 @@ function Install-VCLibsAppx $stream.Close() $zip.Dispose() $xml = [xml]$manifest - #$identity = $xml.selectSingleNode("/*[local-name()='Package']/*[local-name='Identity']") $identity = $xml.documentElement.Identity - $appx_version_fields = Parse-DotQuadVersion $identity.Version - $appx_version = "{0:X04}.{1:X04}.{2:X04}.{3:X04}" -f $appx_version_fields + $appx_version = $identity.Version + $appx_version_fields = Parse-DotQuadVersion $appx_version + $appx_version_comparable = "{0:X04}.{1:X04}.{2:X04}.{3:X04}" -f $appx_version_fields - if ($package) + $max_found_version = $null + $max_found_version_comparable = $null + ForEach ($package in $packages) { - $package_version_fields = Parse-DotQuadVersion $package.Version - $package_version = "{0:X04}.{1:X04}.{2:X04}.{3:X04}" -f $package_version_fields - - if ($package_version -ge $appx_version) + if (($max_found_version_comparable -eq $null) -or ($max_found_version_comparable -lt $appx_version)) + { + $max_found_version = $package.Version + $version_fields = Parse-DotQuadVersion $max_found_version + $max_found_version_comparable = "{0:X04}.{1:X04}.{2:X04}.{3:X04}" -f $version_fields + } + } + if ($max_found_version) + { + if ($max_found_version_comparable -ge $appx_version_comparable) { - Write-Host "...$($name) $($architecture): Latest version $($package.Version) installed" + Write-Host "...$($name) $($architecture): Latest version $($max_found_version) installed" } else { - Write-Host "...$($name) $($architecture): $($package.Version) installed but newer version $($identity.Version) available" - $install++ + Write-Host "...$($name) $($architecture): $($max_found_version) installed but newer version $($appx_version) available" + $install_issues++ } } } if ($InstallVCLibs) { - if ($install) + if ($install_issues) { if ($identity) { - Write-Host "...Installing $name $($architecture) $($identity.Version)..." + Write-Host "...Installing $name $($architecture) $($appx_version)..." } else { @@ -911,9 +919,9 @@ function Install-VCLibsAppx } else { - $global:issues += $install + $global:issues += $install_issues } - return $install -eq 0 + return $install_issues -eq 0 } function Install-VCLibs @@ -941,7 +949,6 @@ function Install-VCLibs Write-Host "Installing VCLibs MSIX packages..." $cpu = Get-CpuArchitecture - Install-VCLibsAppx (Join-Path $path 'Retail\x86\Microsoft.VCLibs.x86.14.00.appx') 'Microsoft.VCLibs.140.00' 'x86' Install-VCLibsAppx (Join-Path $path 'Debug\x86\Microsoft.VCLibs.x86.Debug.14.00.appx') 'Microsoft.VCLibs.140.00.Debug' 'x86' Install-VCLibsAppx (Join-Path $path_desktop 'Retail\x86\Microsoft.VCLibs.x86.14.00.Desktop.appx') 'Microsoft.VCLibs.140.00.UWPDesktop' 'x86' From 115ef4e58adf5a06749023b29bc9a8869989b702 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 27 Dec 2025 16:36:47 -0800 Subject: [PATCH 07/33] Improved tests. Added dllmain --- WindowsAppRuntime.sln | 31 +++++++++++++++++++ test/Package/API/PackageTests.Packages.h | 1 - test/Package/API/PackageTests.vcxproj | 1 + test/Package/API/PackageTests.vcxproj.filters | 3 ++ test/Package/API/PackageTests_CPP.cpp | 14 +++++++-- test/Package/API/PackageTests_WinRT.cpp | 5 +-- test/Package/API/dllmain.cpp | 30 ++++++++++++++++++ test/Package/data/Mutable/appxmanifest.xml | 3 +- 8 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 test/Package/API/dllmain.cpp diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index ade4205950..6d97cb334d 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -765,6 +765,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Deployment.WindowsAppRuntim EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Deployment.WindowsAppRuntime.Test.SingletonLowerVersion", "test\Deployment\data\WindowsAppRuntime.Test.SingletonLowerVersion\WindowsAppRuntime.Test.SingletonLowerVersion.vcxproj", "{7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{2BF5AE78-D16A-402B-84C1-2164B887D858}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MachineExternal", "MachineExternal", "{862A4050-B803-493D-89C2-09390141C774}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mutable", "Mutable", "{39ADE0B0-74E8-478A-9AE1-EFB568985AA5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UserExternal", "UserExternal", "{70317696-8BDE-4D1E-99DE-5CD722EB86B1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Mutable.msix", "test\Package\data\Mutable\Package.Mutable.msix.vcxproj", "{469EE821-0FB5-4B9A-82D9-91292B0593D0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2691,6 +2701,22 @@ Global {7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D}.Release|x64.Build.0 = Release|x64 {7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D}.Release|x86.ActiveCfg = Release|Win32 {7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D}.Release|x86.Build.0 = Release|Win32 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|Any CPU.ActiveCfg = Debug|x64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|Any CPU.Build.0 = Debug|x64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|ARM64.Build.0 = Debug|ARM64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|x64.ActiveCfg = Debug|x64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|x64.Build.0 = Debug|x64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|x86.ActiveCfg = Debug|Win32 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Debug|x86.Build.0 = Debug|Win32 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|Any CPU.ActiveCfg = Release|x64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|Any CPU.Build.0 = Release|x64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|ARM64.ActiveCfg = Release|ARM64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|ARM64.Build.0 = Release|ARM64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x64.ActiveCfg = Release|x64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x64.Build.0 = Release|x64 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x86.ActiveCfg = Release|Win32 + {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2924,6 +2950,11 @@ Global {06AA7FD7-36BE-41AC-9008-56919D1612C6} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} {462CF10A-E6B5-4005-8E25-132D1DE589B7} = {2B653A15-2482-40E5-9509-C531E69D0749} {7A3C8F5D-9B2E-4A1F-8D6C-3E9F7B4A2C1D} = {2B653A15-2482-40E5-9509-C531E69D0749} + {2BF5AE78-D16A-402B-84C1-2164B887D858} = {9DE31467-8D10-4558-8719-32559E01B32A} + {862A4050-B803-493D-89C2-09390141C774} = {2BF5AE78-D16A-402B-84C1-2164B887D858} + {39ADE0B0-74E8-478A-9AE1-EFB568985AA5} = {2BF5AE78-D16A-402B-84C1-2164B887D858} + {70317696-8BDE-4D1E-99DE-5CD722EB86B1} = {2BF5AE78-D16A-402B-84C1-2164B887D858} + {469EE821-0FB5-4B9A-82D9-91292B0593D0} = {39ADE0B0-74E8-478A-9AE1-EFB568985AA5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h index 5fe631e83f..2618856b6a 100644 --- a/test/Package/API/PackageTests.Packages.h +++ b/test/Package/API/PackageTests.Packages.h @@ -35,7 +35,6 @@ namespace MachineExternal namespace Test::Package::Tests { namespace TP = ::Test::Packages; - //namespace TPF = ::Test::Packages::Framework; inline bool IsPackageRegistered_Mutable() { diff --git a/test/Package/API/PackageTests.vcxproj b/test/Package/API/PackageTests.vcxproj index 73d841fc34..7b900b8786 100644 --- a/test/Package/API/PackageTests.vcxproj +++ b/test/Package/API/PackageTests.vcxproj @@ -109,6 +109,7 @@ Create + diff --git a/test/Package/API/PackageTests.vcxproj.filters b/test/Package/API/PackageTests.vcxproj.filters index 74809d9fc7..6b38491398 100644 --- a/test/Package/API/PackageTests.vcxproj.filters +++ b/test/Package/API/PackageTests.vcxproj.filters @@ -18,6 +18,9 @@ Source Files + + Source Files + Source Files diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp index 74b68a83d8..2c63a2fea9 100644 --- a/test/Package/API/PackageTests_CPP.cpp +++ b/test/Package/API/PackageTests_CPP.cpp @@ -18,6 +18,7 @@ namespace Test::Package::Tests { const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; class PackageTests_CPP { @@ -33,9 +34,9 @@ namespace Test::Package::Tests //RemovePackage_MachineExternal(); //RemovePackage_UserExternal(); - //RemovePackage_Mutable(); + RemovePackage_Mutable(); - //AddPackage_Mutable(); + AddPackage_Mutable(); //AddPackage_UserExternal(); //AddPackage_MachineExternal(); @@ -92,12 +93,19 @@ namespace Test::Package::Tests PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath }; wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)), + WEX::Common::String().Format(L"AbsoluteFilename:%s", absoluteFilename.get())); //TODO } TEST_METHOD(GetPackageFilePath_MutablePath) { + PCWSTR packageFullName{ Mutable_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchMutablePath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)), + WEX::Common::String().Format(L"AbsoluteFilename:%s", absoluteFilename.get())); //TODO } diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index a3a36565fb..ab37095103 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -16,6 +16,7 @@ namespace Test::Package::Tests { const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; class PackageTests_WinRT { @@ -31,9 +32,9 @@ namespace Test::Package::Tests //RemovePackage_MachineExternal(); //RemovePackage_UserExternal(); - //RemovePackage_Mutable(); + RemovePackage_Mutable(); - //AddPackage_Mutable(); + AddPackage_Mutable(); //AddPackage_UserExternal(); //AddPackage_MachineExternal(); diff --git a/test/Package/API/dllmain.cpp b/test/Package/API/dllmain.cpp new file mode 100644 index 0000000000..1e024a3c62 --- /dev/null +++ b/test/Package/API/dllmain.cpp @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +// Including this file once per binary will automatically opt WIL error handling macros into calling RoOriginateError when they +// begin logging a new error. This greatly improves the debuggability of errors that propagate before a failfast. +#include + +BOOL APIENTRY DllMain(HMODULE hmodule, DWORD reason, LPVOID reserved) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hmodule); + break; + case DLL_PROCESS_DETACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + } + + // Give WIL a crack at DLLMain processing + // See DLLMain() in wil/result_macros.h for why + wil::DLLMain(hmodule, reason, reserved); + + return TRUE; +} diff --git a/test/Package/data/Mutable/appxmanifest.xml b/test/Package/data/Mutable/appxmanifest.xml index 672ceff746..9a5b4b8f69 100644 --- a/test/Package/data/Mutable/appxmanifest.xml +++ b/test/Package/data/Mutable/appxmanifest.xml @@ -4,7 +4,8 @@ xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6" - IgnorableNamespaces="uap desktop6"> + xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" + IgnorableNamespaces="uap desktop6 rescap"> Date: Sat, 24 Jan 2026 20:54:36 -0800 Subject: [PATCH 08/33] More tests. Added dev\common to various test projects' Include path to fix compile error. Cleaned up (optimized) several test projects. --- dev/Common/IsWindowsVersion.h | 4 +- dev/Interop/StoragePickers/PickerCommon.cpp | 2 +- test/ABForward/ABForward.vcxproj | 80 ++----------- .../AccessControlTests.vcxproj | 113 +++--------------- test/AppLifecycle/AppLifecycle.vcxproj | 78 ++---------- test/Deployment/API/DeploymentTests.vcxproj | 73 ++--------- test/Package/API/PackageTests.Packages.h | 13 +- .../PowerNotifications.vcxproj | 39 ++---- .../AccessControlTestApp.vcxproj | 70 ++--------- .../ToastNotificationsTestApp.vcxproj | 70 ++--------- test/VersionInfo/VersionInfoTests.vcxproj | 2 +- test/inc/WindowsAppRuntime.Test.Package.h | 109 +++++++++++++++-- 12 files changed, 174 insertions(+), 479 deletions(-) diff --git a/dev/Common/IsWindowsVersion.h b/dev/Common/IsWindowsVersion.h index f7fe5ee17c..2b049a1b43 100644 --- a/dev/Common/IsWindowsVersion.h +++ b/dev/Common/IsWindowsVersion.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation and Contributors. +// Copyright (c) Microsoft Corporation and Contributors. // Licensed under the MIT License. #ifndef __ISWINDOWSVERSION_H @@ -6,6 +6,8 @@ #include +#include + namespace WindowsVersion { inline bool IsExportPresent( diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index 8b2006581e..668e1e3c71 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -432,7 +432,7 @@ namespace PickerCommon { if (FocusLastFilter) { - check_hresult(dialog->SetFileTypeIndex(FileTypeFilterPara.size())); + check_hresult(dialog->SetFileTypeIndex(static_cast(FileTypeFilterPara.size()))); } } } diff --git a/test/ABForward/ABForward.vcxproj b/test/ABForward/ABForward.vcxproj index a8c7dfaa4c..02cf728f1c 100644 --- a/test/ABForward/ABForward.vcxproj +++ b/test/ABForward/ABForward.vcxproj @@ -126,28 +126,13 @@ - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - WIN32;NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h - - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) - - - + Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - WIN32;_DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common + %(PreprocessorDefinitions);INLINE_TEST_METHOD_MARKUP Windows @@ -156,65 +141,20 @@ Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + _DEBUG;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + NDEBUG;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_DLL\Generated Files;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + WIN32;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_DLL\Generated Files;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h - - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - @@ -327,4 +267,4 @@ $(RepoTestCertificatePFX) $(RepoTestCertificatePassword) - \ No newline at end of file + diff --git a/test/AccessControlTests/AccessControlTests.vcxproj b/test/AccessControlTests/AccessControlTests.vcxproj index 36aa8bb2ba..3c0d7741cd 100644 --- a/test/AccessControlTests/AccessControlTests.vcxproj +++ b/test/AccessControlTests/AccessControlTests.vcxproj @@ -35,41 +35,16 @@ AccessControlTests 10.0 - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - Unicode - - + DynamicLibrary - false v143 Unicode - - DynamicLibrary + true - v143 - Unicode - - DynamicLibrary + false - v143 - Unicode @@ -96,95 +71,35 @@ - + - WIN32;_DEBUG;%(PreprocessorDefinitions) Use + true pch.h - $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) + $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories);$(RepoRoot)\dev\common + %(PreprocessorDefinitions);INLINE_TEST_METHOD_MARKUP Windows - false - onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) - Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) - - - - - WIN32;_DEBUG;%(PreprocessorDefinitions) - Use - pch.h - $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) - - - Windows - false - onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) - Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) - - - - - WIN32;NDEBUG;%(PreprocessorDefinitions) - Use - pch.h - $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) - - - Windows - false onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) - Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) + Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - + - WIN32;NDEBUG;%(PreprocessorDefinitions) - Use - pch.h - $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) - - Windows - false - onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) - Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) - - + - _DEBUG;%(PreprocessorDefinitions) - Use - pch.h - $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) - - Windows - false - onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) - Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) - - + - NDEBUG;%(PreprocessorDefinitions) - Use - pch.h - $(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories) + WIN32;%(PreprocessorDefinitions) - - Windows - false - onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) - Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) - diff --git a/test/AppLifecycle/AppLifecycle.vcxproj b/test/AppLifecycle/AppLifecycle.vcxproj index 3e3cb5d208..1b3c95cc7e 100644 --- a/test/AppLifecycle/AppLifecycle.vcxproj +++ b/test/AppLifecycle/AppLifecycle.vcxproj @@ -104,13 +104,13 @@ - + Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - WIN32;NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common + %(PreprocessorDefinitions);INLINE_TEST_METHOD_MARKUP Windows @@ -119,80 +119,20 @@ Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - WIN32;_DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + _DEBUG;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + NDEBUG;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + WIN32;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h - - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;..\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h - - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - diff --git a/test/Deployment/API/DeploymentTests.vcxproj b/test/Deployment/API/DeploymentTests.vcxproj index 706f411c26..ea876ee025 100644 --- a/test/Deployment/API/DeploymentTests.vcxproj +++ b/test/Deployment/API/DeploymentTests.vcxproj @@ -104,13 +104,13 @@ - + Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - WIN32;NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common + %(PreprocessorDefinitions);INLINE_TEST_METHOD_MARKUP Windows @@ -118,75 +118,20 @@ onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - WIN32;_DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h - - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h - - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + _DEBUG;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + NDEBUG;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL - NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP - true - pch.h + WIN32;%(PreprocessorDefinitions) - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h index 2618856b6a..55600cace1 100644 --- a/test/Package/API/PackageTests.Packages.h +++ b/test/Package/API/PackageTests.Packages.h @@ -109,19 +109,18 @@ namespace Test::Package::Tests } inline void AddPackage_UserExternal() { - TP::AddPackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName); + const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName) }; + TP::AddPackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str()); } inline void AddPackageDefer_UserExternal() { - TP::AddPackageDeferIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName); + const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName) }; + TP::AddPackageDeferIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str()); } inline void StagePackage_UserExternal() { - TP::StagePackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName); - } - inline void RegisterPackage_UserExternal() - { - TP::RegisterPackageIfNecessary(TP::UserExternal::c_packageFullName); + const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName) }; + TP::StagePackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str()); } inline void RemovePackage_UserExternal() { diff --git a/test/PowerNotifications/PowerNotifications.vcxproj b/test/PowerNotifications/PowerNotifications.vcxproj index 4a6083f0a4..eeedd50ee9 100644 --- a/test/PowerNotifications/PowerNotifications.vcxproj +++ b/test/PowerNotifications/PowerNotifications.vcxproj @@ -69,53 +69,32 @@ - + - WIN32;_DEBUG;POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) Use pch.h - $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\ + $(RepoRoot)\test\inc;$(RepoRoot)\dev\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common + %(PreprocessorDefinitions);POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL; Windows false - + - WIN32;NDEBUG;POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - Use - pch.h - $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\ + _DEBUG;%(PreprocessorDefinitions) - - Windows - false - - + - _DEBUG;POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - Use - pch.h - $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\ + NDEBUG;%(PreprocessorDefinitions) - - Windows - false - - + - NDEBUG;POWERNOTIFICATIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - Use - pch.h - $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\ + WIN32;%(PreprocessorDefinitions) - - Windows - false - diff --git a/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj b/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj index 227342c347..2dfd8b9445 100644 --- a/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj +++ b/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj @@ -48,7 +48,7 @@ - + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} @@ -122,12 +122,11 @@ - + Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc - WIN32;_DEBUG;%(PreprocessorDefinitions) pch.h + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\test\inc;$(RepoRoot)\dev\common Console @@ -136,75 +135,20 @@ Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc - WIN32;NDEBUG;%(PreprocessorDefinitions) - pch.h - - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc _DEBUG;%(PreprocessorDefinitions) - pch.h - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc NDEBUG;%(PreprocessorDefinitions) - pch.h - - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc - _DEBUG;%(PreprocessorDefinitions) - pch.h - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc - NDEBUG;%(PreprocessorDefinitions) - pch.h + WIN32;%(PreprocessorDefinitions) - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - diff --git a/test/TestApps/ToastNotificationsTestApp/ToastNotificationsTestApp.vcxproj b/test/TestApps/ToastNotificationsTestApp/ToastNotificationsTestApp.vcxproj index 04e3858dbc..bf385b6d38 100644 --- a/test/TestApps/ToastNotificationsTestApp/ToastNotificationsTestApp.vcxproj +++ b/test/TestApps/ToastNotificationsTestApp/ToastNotificationsTestApp.vcxproj @@ -59,7 +59,7 @@ - + $(RepoRoot);%(AdditionalIncludeDirectories) @@ -136,12 +136,11 @@ - + Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc - WIN32;_DEBUG;%(PreprocessorDefinitions) pch.h + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\test\inc;$(RepoRoot)\dev\common Console @@ -150,75 +149,20 @@ Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc - WIN32;NDEBUG;%(PreprocessorDefinitions) - pch.h - - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc _DEBUG;%(PreprocessorDefinitions) - pch.h - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc NDEBUG;%(PreprocessorDefinitions) - pch.h - - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - - - - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc - _DEBUG;%(PreprocessorDefinitions) - pch.h - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - - + - Use - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;..\..\inc - NDEBUG;%(PreprocessorDefinitions) - pch.h + WIN32;%(PreprocessorDefinitions) - - Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL - onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) - diff --git a/test/VersionInfo/VersionInfoTests.vcxproj b/test/VersionInfo/VersionInfoTests.vcxproj index 029e9305d3..e2fc22358e 100644 --- a/test/VersionInfo/VersionInfoTests.vcxproj +++ b/test/VersionInfo/VersionInfoTests.vcxproj @@ -77,7 +77,7 @@ Use true pch.h - $(RepoRoot)\test\inc;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL + $(RepoRoot)\test\inc;$(RepoRoot)\dev\common;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL $(RepoRoot);%(AdditionalIncludeDirectories) diff --git a/test/inc/WindowsAppRuntime.Test.Package.h b/test/inc/WindowsAppRuntime.Test.Package.h index 5c1bb8de6b..b372cc3455 100644 --- a/test/inc/WindowsAppRuntime.Test.Package.h +++ b/test/inc/WindowsAppRuntime.Test.Package.h @@ -6,6 +6,8 @@ #include +#include + #include #include #include @@ -321,18 +323,52 @@ inline void AddPackage(PCWSTR packageDirName, PCWSTR packageFullName) VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"AddPackageAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); } -inline void AddPackageDefer(PCWSTR packageDirName, PCWSTR packageFullName) +inline void AddPackageByUri( + winrt::Windows::Foundation::Uri packageUri, + PCWSTR packageFullName, + bool DeferRegistrationWhenPackagesAreInUse = false, + PCWSTR externalLocation = nullptr) { - auto msixUri{ GetMsixPackageUri(packageDirName) }; + // AddPackageByUri added in 20H1 + VERIFY_IS_TRUE(::WindowsVersion::IsWindows10_20H1OrGreater()); winrt::Windows::Management::Deployment::PackageManager packageManager; winrt::Windows::Management::Deployment::AddPackageOptions options; - options.DeferRegistrationWhenPackagesAreInUse(true); - auto deploymentResult{ packageManager.AddPackageByUriAsync(msixUri, options).get() }; - VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"AddPackageByUriAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); + options.DeferRegistrationWhenPackagesAreInUse(DeferRegistrationWhenPackagesAreInUse); + if (externalLocation) + { + auto externalLocationUri{ winrt::Windows::Foundation::Uri{ externalLocation } }; + options.ExternalLocationUri(externalLocationUri); + } + auto deploymentResult{ packageManager.AddPackageByUriAsync(packageUri, options).get() }; + if (externalLocation) + { + VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), + WEX::Common::String().Format(L"AddPackageByUriAsync('%s', ExtLoc='%s') = 0x%0X %s", + packageFullName, externalLocation ? externalLocation : L"", deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); + } + else + { + VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"AddPackageByUriAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); + } +} + +inline void AddPackageByUri( + PCWSTR packageDirName, + PCWSTR packageFullName, + bool DeferRegistrationWhenPackagesAreInUse = false, + PCWSTR externalLocation = nullptr) +{ + auto msixUri{ GetMsixPackageUri(packageDirName) }; + AddPackageByUri(msixUri, packageFullName, DeferRegistrationWhenPackagesAreInUse, externalLocation); +} + +inline void AddPackageDefer(PCWSTR packageDirName, PCWSTR packageFullName, PCWSTR externalLocation = nullptr) +{ + AddPackageByUri(packageDirName, packageFullName, true, externalLocation); } -inline void AddPackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName) +inline void AddPackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName, PCWSTR externalLocation = nullptr) { if (IsPackageRegistered(packageFullName)) { @@ -341,11 +377,18 @@ inline void AddPackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName) else { WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddPackageIfNecessary: %s not registered, adding...", packageFullName)); - AddPackage(packageDirName, packageFullName); + if (externalLocation) + { + AddPackageByUri(packageDirName, packageFullName, false, externalLocation); + } + else + { + AddPackage(packageDirName, packageFullName); + } } } -inline void AddPackageDeferIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName) +inline void AddPackageDeferIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName, PCWSTR externalLocation = nullptr) { if (IsPackageRegistered(packageFullName)) { @@ -354,7 +397,7 @@ inline void AddPackageDeferIfNecessary(PCWSTR packageDirName, PCWSTR packageFull else { WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddPackageDeferIfNecessary: %s not registered, adding...", packageFullName)); - AddPackageDefer(packageDirName, packageFullName); + AddPackageDefer(packageDirName, packageFullName, externalLocation); } } @@ -368,7 +411,44 @@ inline void StagePackage(PCWSTR packageDirName, PCWSTR packageFullName) VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"StagePackageAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); } -inline void StagePackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName) +inline void StagePackageByUri( + winrt::Windows::Foundation::Uri packageUri, + PCWSTR packageFullName, + PCWSTR externalLocation = nullptr) +{ + // StagePackageByUri added in 20H1 + VERIFY_IS_TRUE(::WindowsVersion::IsWindows10_20H1OrGreater()); + + winrt::Windows::Management::Deployment::PackageManager packageManager; + winrt::Windows::Management::Deployment::StagePackageOptions options; + if (externalLocation) + { + auto externalLocationUri{ winrt::Windows::Foundation::Uri{ externalLocation } }; + options.ExternalLocationUri(externalLocationUri); + } + auto deploymentResult{ packageManager.StagePackageByUriAsync(packageUri, options).get() }; + if (externalLocation) + { + VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), + WEX::Common::String().Format(L"StagePackageAsync('%s', ExtLoc='%s') = 0x%0X %s", + packageFullName, externalLocation, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); + } + else + { + VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"StagePackageAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); + } +} + +inline void StagePackageByUri( + PCWSTR packageDirName, + PCWSTR packageFullName, + PCWSTR externalLocation = nullptr) +{ + auto msixUri{ GetMsixPackageUri(packageDirName) }; + StagePackageByUri(msixUri, packageFullName, externalLocation); +} + +inline void StagePackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName, PCWSTR externalLocation=nullptr) { if (IsPackageAvailable(packageFullName)) { @@ -377,7 +457,14 @@ inline void StagePackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullNam else { WEX::Logging::Log::Comment(WEX::Common::String().Format(L"StagePackageIfNecessary: %s not staged, staging...", packageFullName)); - StagePackage(packageDirName, packageFullName); + if (externalLocation) + { + StagePackageByUri(packageDirName, packageFullName, externalLocation); + } + else + { + StagePackage(packageDirName, packageFullName); + } } } From 4ffc7620d9d6a77cb63ef5a874fe4933a2cf6d5e Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 24 Jan 2026 21:38:08 -0800 Subject: [PATCH 09/33] Test fixes --- WindowsAppRuntime.sln | 43 ++++++++++++++++++- dev/Package/package_runtime.cpp | 2 +- test/Package/API/PackageTests.Packages.h | 6 +-- test/Package/API/PackageTests.vcxproj | 1 + test/Package/API/PackageTests_CPP.cpp | 4 +- ...Package.Test.MachineExternal.msix.vcxproj} | 0 ...Test.MachineExternal.msix.vcxproj.filters} | 0 ...kage.Test.MachineExternal.vcxproj.filters} | 0 .../data/MachineExternal/appxmanifest.xml | 2 +- ...proj => Package.Test.Mutable.msix.vcxproj} | 0 ...Package.Test.Mutable.msix.vcxproj.filters} | 7 ++- ...=> Package.Test.UserExternal.msix.vcxproj} | 0 ...ge.Test.UserExternal.msix.vcxproj.filters} | 0 ...Package.Test.UserExternal.vcxproj.filters} | 0 .../data/UserExternal/appxmanifest.xml | 2 +- 15 files changed, 57 insertions(+), 10 deletions(-) rename test/Package/data/MachineExternal/{Package.MachineExternal.msix.vcxproj => Package.Test.MachineExternal.msix.vcxproj} (100%) rename test/Package/data/MachineExternal/{Package.MachineExternal.msix.vcxproj.filters => Package.Test.MachineExternal.msix.vcxproj.filters} (100%) rename test/Package/data/MachineExternal/{Package.MachineExternal.vcxproj.filters => Package.Test.MachineExternal.vcxproj.filters} (100%) rename test/Package/data/Mutable/{Package.Mutable.msix.vcxproj => Package.Test.Mutable.msix.vcxproj} (100%) rename test/Package/data/{UserExternal/Package.UserExternal.msix.vcxproj.filters => Mutable/Package.Test.Mutable.msix.vcxproj.filters} (69%) rename test/Package/data/UserExternal/{Package.UserExternal.msix.vcxproj => Package.Test.UserExternal.msix.vcxproj} (100%) rename test/Package/data/{Mutable/Package.Mutable.msix.vcxproj.filters => UserExternal/Package.Test.UserExternal.msix.vcxproj.filters} (100%) rename test/Package/data/UserExternal/{Package.UserExternal.vcxproj.filters => Package.Test.UserExternal.vcxproj.filters} (100%) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 6d97cb334d..f1d17ffa96 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -748,6 +748,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API", "API", "{BF763B12-77A9-471D-825B-4AC05E70A804}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageTests", "test\Package\API\PackageTests.vcxproj", "{F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}" + ProjectSection(ProjectDependencies) = postProject + {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Windows.ApplicationModel.Resources", "dev\MRTCore\mrt\Microsoft.Windows.ApplicationModel.Resources\src\Microsoft.Windows.ApplicationModel.Resources.vcxproj", "{9B3B03BC-1BC0-43EA-B3FF-D5214F3CF5CF}" EndProject @@ -773,7 +776,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mutable", "Mutable", "{39AD EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UserExternal", "UserExternal", "{70317696-8BDE-4D1E-99DE-5CD722EB86B1}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Mutable.msix", "test\Package\data\Mutable\Package.Mutable.msix.vcxproj", "{469EE821-0FB5-4B9A-82D9-91292B0593D0}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.Mutable.msix", "test\Package\data\Mutable\Package.Test.Mutable.msix.vcxproj", "{469EE821-0FB5-4B9A-82D9-91292B0593D0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.MachineExternal.msix", "test\Package\data\MachineExternal\Package.Test.MachineExternal.msix.vcxproj", "{3347E246-6BF5-469F-9C91-7D6E33B66786}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.UserExternal.msix", "test\Package\data\UserExternal\Package.Test.UserExternal.msix.vcxproj", "{28CEF2AF-174B-4EE9-B71E-D596C5E1E563}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -2717,6 +2724,38 @@ Global {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x64.Build.0 = Release|x64 {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x86.ActiveCfg = Release|Win32 {469EE821-0FB5-4B9A-82D9-91292B0593D0}.Release|x86.Build.0 = Release|Win32 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|Any CPU.ActiveCfg = Debug|x64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|Any CPU.Build.0 = Debug|x64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|ARM64.Build.0 = Debug|ARM64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|x64.ActiveCfg = Debug|x64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|x64.Build.0 = Debug|x64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|x86.ActiveCfg = Debug|Win32 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Debug|x86.Build.0 = Debug|Win32 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|Any CPU.ActiveCfg = Release|x64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|Any CPU.Build.0 = Release|x64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|ARM64.ActiveCfg = Release|ARM64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|ARM64.Build.0 = Release|ARM64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|x64.ActiveCfg = Release|x64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|x64.Build.0 = Release|x64 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|x86.ActiveCfg = Release|Win32 + {3347E246-6BF5-469F-9C91-7D6E33B66786}.Release|x86.Build.0 = Release|Win32 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|Any CPU.ActiveCfg = Debug|x64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|Any CPU.Build.0 = Debug|x64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|ARM64.Build.0 = Debug|ARM64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|x64.ActiveCfg = Debug|x64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|x64.Build.0 = Debug|x64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|x86.ActiveCfg = Debug|Win32 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Debug|x86.Build.0 = Debug|Win32 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|Any CPU.ActiveCfg = Release|x64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|Any CPU.Build.0 = Release|x64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|ARM64.ActiveCfg = Release|ARM64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|ARM64.Build.0 = Release|ARM64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x64.ActiveCfg = Release|x64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x64.Build.0 = Release|x64 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x86.ActiveCfg = Release|Win32 + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2955,6 +2994,8 @@ Global {39ADE0B0-74E8-478A-9AE1-EFB568985AA5} = {2BF5AE78-D16A-402B-84C1-2164B887D858} {70317696-8BDE-4D1E-99DE-5CD722EB86B1} = {2BF5AE78-D16A-402B-84C1-2164B887D858} {469EE821-0FB5-4B9A-82D9-91292B0593D0} = {39ADE0B0-74E8-478A-9AE1-EFB568985AA5} + {3347E246-6BF5-469F-9C91-7D6E33B66786} = {862A4050-B803-493D-89C2-09390141C774} + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563} = {70317696-8BDE-4D1E-99DE-5CD722EB86B1} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index 82487d99ce..ad1761d004 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -118,7 +118,7 @@ STDAPI GetPackageFilePath( if (::Microsoft::Foundation::String::IsNullOrEmpty(packageFullName)) { uint32_t packageFullNameBufferLength{ ARRAYSIZE(packageFullNameBuffer) }; - THROW_IF_FAILED(::GetCurrentPackageFullName(&packageFullNameBufferLength, packageFullNameBuffer)); + RETURN_IF_WIN32_ERROR(::GetCurrentPackageFullName(&packageFullNameBufferLength, packageFullNameBuffer)); packageFullName = packageFullNameBuffer; } diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h index 55600cace1..cba5b0cd7b 100644 --- a/test/Package/API/PackageTests.Packages.h +++ b/test/Package/API/PackageTests.Packages.h @@ -109,17 +109,17 @@ namespace Test::Package::Tests } inline void AddPackage_UserExternal() { - const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName) }; + const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName).parent_path()}; TP::AddPackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str()); } inline void AddPackageDefer_UserExternal() { - const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName) }; + const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName).parent_path() }; TP::AddPackageDeferIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str()); } inline void StagePackage_UserExternal() { - const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName) }; + const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName).parent_path() }; TP::StagePackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str()); } inline void RemovePackage_UserExternal() diff --git a/test/Package/API/PackageTests.vcxproj b/test/Package/API/PackageTests.vcxproj index 7b900b8786..eff4a2b62a 100644 --- a/test/Package/API/PackageTests.vcxproj +++ b/test/Package/API/PackageTests.vcxproj @@ -88,6 +88,7 @@ onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) + Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp index 2c63a2fea9..5837b6a054 100644 --- a/test/Package/API/PackageTests_CPP.cpp +++ b/test/Package/API/PackageTests_CPP.cpp @@ -33,11 +33,11 @@ namespace Test::Package::Tests ::TB::Setup(); //RemovePackage_MachineExternal(); - //RemovePackage_UserExternal(); + RemovePackage_UserExternal(); RemovePackage_Mutable(); AddPackage_Mutable(); - //AddPackage_UserExternal(); + AddPackage_UserExternal(); //AddPackage_MachineExternal(); return true; diff --git a/test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj b/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj similarity index 100% rename from test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj rename to test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj diff --git a/test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj.filters b/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj.filters similarity index 100% rename from test/Package/data/MachineExternal/Package.MachineExternal.msix.vcxproj.filters rename to test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj.filters diff --git a/test/Package/data/MachineExternal/Package.MachineExternal.vcxproj.filters b/test/Package/data/MachineExternal/Package.Test.MachineExternal.vcxproj.filters similarity index 100% rename from test/Package/data/MachineExternal/Package.MachineExternal.vcxproj.filters rename to test/Package/data/MachineExternal/Package.Test.MachineExternal.vcxproj.filters diff --git a/test/Package/data/MachineExternal/appxmanifest.xml b/test/Package/data/MachineExternal/appxmanifest.xml index ee7774c7a4..27858672e3 100644 --- a/test/Package/data/MachineExternal/appxmanifest.xml +++ b/test/Package/data/MachineExternal/appxmanifest.xml @@ -7,7 +7,7 @@ IgnorableNamespaces="uap uap10"> diff --git a/test/Package/data/Mutable/Package.Mutable.msix.vcxproj b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj similarity index 100% rename from test/Package/data/Mutable/Package.Mutable.msix.vcxproj rename to test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj diff --git a/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj.filters b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj.filters similarity index 69% rename from test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj.filters rename to test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj.filters index 93e09be5b1..2df21c891a 100644 --- a/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj.filters +++ b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj.filters @@ -7,6 +7,11 @@ - + + + + + + diff --git a/test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj b/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj similarity index 100% rename from test/Package/data/UserExternal/Package.UserExternal.msix.vcxproj rename to test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj diff --git a/test/Package/data/Mutable/Package.Mutable.msix.vcxproj.filters b/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj.filters similarity index 100% rename from test/Package/data/Mutable/Package.Mutable.msix.vcxproj.filters rename to test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj.filters diff --git a/test/Package/data/UserExternal/Package.UserExternal.vcxproj.filters b/test/Package/data/UserExternal/Package.Test.UserExternal.vcxproj.filters similarity index 100% rename from test/Package/data/UserExternal/Package.UserExternal.vcxproj.filters rename to test/Package/data/UserExternal/Package.Test.UserExternal.vcxproj.filters diff --git a/test/Package/data/UserExternal/appxmanifest.xml b/test/Package/data/UserExternal/appxmanifest.xml index cb7dccc8f0..006cb58f5f 100644 --- a/test/Package/data/UserExternal/appxmanifest.xml +++ b/test/Package/data/UserExternal/appxmanifest.xml @@ -7,7 +7,7 @@ IgnorableNamespaces="uap uap10"> From 4416815f9face9ad5181d1b6a34a8ee8ebf332f4 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 25 Jan 2026 01:58:16 -0800 Subject: [PATCH 10/33] Fixed missing build dependencies --- WindowsAppRuntime.sln | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index f1d17ffa96..d3592a9f64 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -548,6 +548,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OAuth", "dev\OAuth\OAuth.vcxitems", "{3E7FD510-8B66-40E7-A80B-780CB8972F83}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Security.Authentication.OAuth.Projection", "dev\Projections\CS\Microsoft.Security.Authentication.OAuth\Microsoft.Security.Authentication.OAuth.Projection.csproj", "{1D24CC70-85B1-4864-B847-3328F40AF01E}" + ProjectSection(ProjectDependencies) = postProject + {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{3B706C5C-55E0-4B76-BF59-89E20FE46795}" EndProject @@ -564,6 +567,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CameraCaptureUITests", "tes EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Windows.Media.Capture.Projection", "dev\Projections\CS\Microsoft.Windows.Media.Capture.Projection\Microsoft.Windows.Media.Capture.Projection.csproj", "{97AB4F8D-DF7E-4BA8-9B06-E7B79AF616D6}" + ProjectSection(ProjectDependencies) = postProject + {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BackgroundTaskBuilder", "BackgroundTaskBuilder", "{F425452A-3597-4A7A-BA0A-0C3C76A9F5CD}" EndProject @@ -680,6 +686,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BadgeNotificationTest", "test\BadgeNotificationTest\BadgeNotificationTest.vcxproj", "{7C8BEED1-7B27-41C5-A22F-9D6B4468F52A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.Pickers.Projection", "dev\Projections\CS\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.csproj", "{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}" + ProjectSection(ProjectDependencies) = postProject + {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Interop\StoragePickers\StoragePickers.vcxitems", "{A39E7B2F-5F67-47DD-8443-531D095CA7F3}" EndProject From 67cf0f1643998b6c9da0b8cfbdf5e3d609991594 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 25 Jan 2026 21:40:28 -0800 Subject: [PATCH 11/33] More tests. Checkpointing code in progress --- dev/Common/AppModel.Package.h | 103 +++++++++++ dev/Package/M.W.A.Package.cpp | 1 + dev/Package/M.W.A.PackageGraph.cpp | 1 + dev/Package/Package.idl | 41 ++++- dev/Package/package_runtime.cpp | 222 ++++++++++++++++++----- dev/Package/package_runtime.h | 46 ++++- dev/Package/pch.h | 2 + dev/WindowsAppRuntime_DLL/pch.h | 1 + specs/package/Package.md | 105 +++++++++-- test/Package/API/PackageTests.Packages.h | 13 +- test/Package/API/PackageTests_CPP.cpp | 6 +- test/Package/API/PackageTests_WinRT.cpp | 12 +- 12 files changed, 483 insertions(+), 70 deletions(-) diff --git a/dev/Common/AppModel.Package.h b/dev/Common/AppModel.Package.h index 772091840a..d8cd1bc641 100644 --- a/dev/Common/AppModel.Package.h +++ b/dev/Common/AppModel.Package.h @@ -79,6 +79,109 @@ inline std::tuple + inline TString MakeFromPCWSTR(PCWSTR s) + { + if constexpr (std::is_same_v) + { + return s ? std::wstring{s} : std::wstring{}; + } + else + { + // For WIL unique string wrappers, use WIL's maker. + // WIL string maker functions accept PCWSTR and return a unique_*_string wrapper. [1](https://github-wiki-see.page/m/microsoft/wil/wiki/String-helpers) + return wil::make_unique_string(s); + } + } +} + +/// Get the path for a package. +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getcurrentpackagepath2 +template +inline Tstring GetPath(_In_ PCWSTR packageFullName, PackagePathType packagePathType) +{ + // Paths can be long but typically short(ish). We can use a quick fixed buffer + // as an optimization and fallback to dynamic allocation if need be + WCHAR path[MAX_PATH]{}; + uint32_t pathLength{ ARRAYSIZE(path) }; + const auto rc{ ::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, path) }; + if (rc == ERROR_SUCCESS) + { + return details::MakeFromPCWSTR(path); + } + else if ((rc == ERROR_NOT_FOUND) || (rc == APPMODEL_ERROR_NO_MUTABLE_DIRECTORY)) + { + return Tstring{}; + } + else if (rc != ERROR_INSUFFICIENT_BUFFER) + { + THROW_WIN32(rc); + } + + // It's bigger than a breadbox. Allocate memory + std::unique_ptr pathBuffer{ std::make_unique(pathLength) }; + THROW_IF_WIN32_ERROR_MSG(::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, pathBuffer.get()), + "PackageFullName=%ls PackagePathType=%d", packageFullName ? packageFullName : L"", static_cast(packagePathType)); + return details::MakeFromPCWSTR(pathBuffer.get()); +} + +/// Get the install path for a package. +/// @return null or empty string if the package isn't visible. +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype +template +inline Tstring GetInstallPath(_In_ PCWSTR packageFullName) +{ + return GetPath(packageFullName, PackagePathType_Install); +} + +/// Get the mutable path for a package. +/// @return null or empty string if the package isn't visible to the caller or has no mutable path. +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype +template +inline Tstring GetMutablePath(_In_ PCWSTR packageFullName) +{ + return GetPath(packageFullName, PackagePathType_Mutable); +} + +/// Get the machine external path for a package. +/// @return null or empty string if the package isn't visible to the caller or has no machine external path. +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype +template +inline Tstring GetMachineExternalPath(_In_ PCWSTR packageFullName) +{ + return GetPath(packageFullName, PackagePathType_MachineExternal); +} + +/// Get the user external path for a package. +/// @return null or empty string if the package isn't visible to the caller or has no user external path. +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype +template +inline Tstring GetUserExternalPath(_In_ PCWSTR packageFullName) +{ + return GetPath(packageFullName, PackagePathType_UserExternal); +} + +/// Get the effective external path for a package. +/// @return null or empty string if the package isn't visible to the caller or has no effective external path. +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype +template +inline Tstring GetEffectiveExternalPath(_In_ PCWSTR packageFullName) +{ + return GetPath(packageFullName, PackagePathType_EffectiveExternal); +} + +/// Get the effective path for a package. +/// @return null or empty string if the package isn't visible to the caller. +/// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ne-appmodel-packagepathtype +template +inline Tstring GetEffectivePath(_In_ PCWSTR packageFullName) +{ + return GetPath(packageFullName, PackagePathType_Effective); +} } #endif // __APPMODEL_PACKAGE_H diff --git a/dev/Package/M.W.A.Package.cpp b/dev/Package/M.W.A.Package.cpp index c99580053a..d52199aa39 100644 --- a/dev/Package/M.W.A.Package.cpp +++ b/dev/Package/M.W.A.Package.cpp @@ -21,6 +21,7 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation static_assert(static_cast(GetFilePathOptions::SearchFrameworkPackages) == static_cast(GetPackageFilePathOptions_SearchFrameworkPackages), "GetFilePathOptions::SearchFrameworkPackages!= GetPackageFilePathOptions_SearchFrameworkPackages"); static_assert(static_cast(GetFilePathOptions::SearchOptionalPackages) == static_cast(GetPackageFilePathOptions_SearchOptionalPackages), "GetFilePathOptions::SearchOptionalPackages!= GetPackageFilePathOptions_SearchOptionalPackages"); static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages"); + static_assert(static_cast(GetFilePathOptions::SearchBundlePackages) == static_cast(GetPackageFilePathOptions_SearchBundlePackages), "GetFilePathOptions::SearchBundlePackages!= GetPackageFilePathOptions_SearchBundlePackages"); static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies"); static_assert(static_cast(GetFilePathOptions::SearchStaticDependencies) == static_cast(GetPackageFilePathOptions_SearchStaticDependencies), "GetFilePathOptions::SearchStaticDependencies!= GetPackageFilePathOptions_SearchStaticDependencies"); static_assert(static_cast(GetFilePathOptions::SearchDynamicDependencies) == static_cast(GetPackageFilePathOptions_SearchDynamicDependencies), "GetFilePathOptions::SearchDynamicDependencies!= GetPackageFilePathOptions_SearchDynamicDependencies"); diff --git a/dev/Package/M.W.A.PackageGraph.cpp b/dev/Package/M.W.A.PackageGraph.cpp index 806e028915..7979f555a1 100644 --- a/dev/Package/M.W.A.PackageGraph.cpp +++ b/dev/Package/M.W.A.PackageGraph.cpp @@ -21,6 +21,7 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation static_assert(static_cast(GetFilePathOptions::SearchFrameworkPackages) == static_cast(GetPackageFilePathOptions_SearchFrameworkPackages), "GetFilePathOptions::SearchFrameworkPackages!= GetPackageFilePathOptions_SearchFrameworkPackages"); static_assert(static_cast(GetFilePathOptions::SearchOptionalPackages) == static_cast(GetPackageFilePathOptions_SearchOptionalPackages), "GetFilePathOptions::SearchOptionalPackages!= GetPackageFilePathOptions_SearchOptionalPackages"); static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages"); + static_assert(static_cast(GetFilePathOptions::SearchBundlePackages) == static_cast(GetPackageFilePathOptions_SearchBundlePackages), "GetFilePathOptions::SearchBundlePackages!= GetPackageFilePathOptions_SearchBundlePackages"); static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies"); static_assert(static_cast(GetFilePathOptions::SearchStaticDependencies) == static_cast(GetPackageFilePathOptions_SearchStaticDependencies), "GetFilePathOptions::SearchStaticDependencies!= GetPackageFilePathOptions_SearchStaticDependencies"); static_assert(static_cast(GetFilePathOptions::SearchDynamicDependencies) == static_cast(GetPackageFilePathOptions_SearchDynamicDependencies), "GetFilePathOptions::SearchDynamicDependencies!= GetPackageFilePathOptions_SearchDynamicDependencies"); diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl index 4428332118..eb38c6cd7f 100644 --- a/dev/Package/Package.idl +++ b/dev/Package/Package.idl @@ -19,39 +19,74 @@ namespace Microsoft.Windows.ApplicationModel None = 0, /// Include the package's Install path in the file search order + /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). SearchInstallPath = 0x0001, /// Include the package's Mutable path (if it has one) in the file search order + /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). SearchMutablePath = 0x0002, /// Include the package's Machine External path (if it has one) in the file search order + /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). SearchMachineExternalPath = 0x0004, /// Include the package's User External path (if it has one) in the file search order + /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). SearchUserExternalPath = 0x0008, /// Include Main packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). SearchMainPackages = 0x0010, /// Include Framework packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). SearchFrameworkPackages = 0x0020, /// Include Optional packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). SearchOptionalPackages = 0x0040, /// Include Resource packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). SearchResourcePackages = 0x0080, + /// Include Bundle packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). + SearchBundlePackages = 0x0100, + /// Include HostRuntime dependencies in the file search order - SearchHostRuntimeDependencies = 0x0100, + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). + SearchHostRuntimeDependencies = 0x0200, /// Include Static package dependencies in the file search order /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). - SearchStaticDependencies = 0x0200, + SearchStaticDependencies = 0x0400, /// Include Dynamic package dependencies in the file search order /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). - SearchDynamicDependencies = 0x0400, + SearchDynamicDependencies = 0x0800, }; [contract(PackageRuntimeContract, 1)] diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index ad1761d004..79d04877bd 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -7,33 +7,108 @@ namespace appmodel { -inline std::wstring get_package_path( +inline LONG get_package_info( + _In_opt_ PACKAGE_INFO_REFERENCE packageInfoReference, + UINT32 flags, + _Inout_ BYTE* bufferLength, + _Out_writes_bytes_opt_(*bufferLength) BYTE* buffer, + _Out_opt_ std::uint32 count) +{ + return packageInfoReference ? + ::GetPackageInfo(packageInfoReference, flags, bufferLength, buffer, count) : + ::GetCurrentPackageInfo(flags, bufferLength, buffer, count); +} + +inline GetPackageFilePathOptions get_package_properties( PCWSTR packageFullName, - PackagePathType packagePathType) + PACKAGE_INFO_REFERENCE packageInfoReference) { - // Paths can be long but typically short(ish). We can use a quick fixed buffer - // as an optimization and fallback to dynamic allocation if need be - WCHAR path[MAX_PATH]{}; - uint32_t pathLength{ ARRAYSIZE(path) }; - const auto rc{ ::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, path) }; - if (rc == ERROR_SUCCESS) + constexpr auto flags{ PACKAGE_FILTER_BUNDLE | PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_HOSTRUNTIME | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC }; + std::uint32_t bufferLength{}; + std::uint32_t count{}; + auto rc{ get_package_info(packageInfoReference, flags, &bufferLength, nullptr, &count) }; + if (rc != ERROR_INSUFFICIENT_BUFFER) + { + if (rc == ERROR_SUCCESS) + { + if (count == 0) + { + // Package not found + return GetPackageFilePathOptions_None; + } + THROW_HR(E_UNEXPECTED); // This should never occur + } + THROW_WIN32_MSG(rc, "GetPackageInfo(...query...) %ls", packageFullName); + } + std::unique_ptr buffer{ std::make_unique(bufferLength) }; + THROW_IF_WIN32_ERROR_MSG(::GetPackageInfo(packageInfoReference.get(), flags, &bufferLength, buffer.get(), &count), + "GetPackageInfo: %ls", packageFullName); + THROW_HR_IF(E_UNEXPECTED, count == 0); // This should never occur + const auto& packageInfo{ *reinterpret_cast(buffer.get()) }; + + const auto hostRuntimeMatch{ WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_HOSTRUNTIME) ? + GetPackageFilePathOptions_SearchHostRuntimeDependencies : + GetPackageFilePathOptions_None }; + const auto isStaticDependency{ WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_STATIC) ? + GetPackageFilePathOptions_SearchStaticDependencies : + GetPackageFilePathOptions_None }; + const auto isDynamicDependency{ WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_DYNAMIC) ? + GetPackageFilePathOptions_SearchDynamicDependencies : + GetPackageFilePathOptions_None }; + if (WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_FRAMEWORK)) { - return path; + return GetPackageFilePathOptions_SearchFrameworkPackages | hostRuntimeMatch; } - else if (rc == ERROR_NOT_FOUND) + else if (WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_OPTIONAL)) { - return std::wstring{}; + return GetPackageFilePathOptions_SearchOptionalPackages | hostRuntimeMatch; } - else if (rc != ERROR_INSUFFICIENT_BUFFER) + else if (WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_RESOURCE)) + { + return GetPackageFilePathOptions_SearchResourcePackages | hostRuntimeMatch; + } + else if (WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_BUNDLE)) + { + return GetPackageFilePathOptions_SearchBundlePackages | hostRuntimeMatch; + } + else + { + // PACKAGE_INFO.Flags has no PACKAGE_PROPERTY_MAIN so we can only determine PackageType=Main + // by first verifying it's not any other type of package (Bundle|Framework|Optional|Resource). + // When all else is ruled out what we're left with must be a Main package + return GetPackageFilePathOptions_SearchMainPackages | hostRuntimeMatch; + } +} + +inline bool is_match_for_package_properties( + PCWSTR packageFullName, + _In_ GetPackageFilePathOptions options, + PACKAGE_INFO_REFERENCE packageInfoReference) +{ + // Detect PackageType|HostRuntimeDependency and Static|DynamicDependency + // + // If options = All or None specified then all packages are a match thus no need to fetch the package's properties + constexpr auto maskMatchPackageType{ GetPackageFilePathOptions_SearchMainPackages | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchOptionalPackages | + GetPackageFilePathOptions_SearchResourcePackages | + GetPackageFilePathOptions_SearchBundlePackages | + GetPackageFilePathOptions_SearchHostRuntimeDependencies }; + constexpr auto maskMatchStaticDynamic{ GetPackageFilePathOptions_SearchStaticDependencies | + GetPackageFilePathOptions_SearchDynamicDependencies }; + constexpr auto maskMatchAll{ maskMatchPackageType | maskMatchStaticDynamic }; + const auto optionsToMatch{ options & maskMatchAll }; + if ((optionsToMatch == GetPackageFilePathOptions_None) || (optionsToMatch == maskMatchAll)) { - THROW_WIN32(rc); + return true; } - // It's bigger than a breadbox. Allocate memory - std::unique_ptr pathBuffer{ std::make_unique(pathLength) }; - THROW_IF_WIN32_ERROR_MSG(::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, pathBuffer.get()), - "PackageFullName=%ls PackagePathType=%d", packageFullName ? packageFullName : L"", static_cast(packagePathType)); - return std::wstring{ pathBuffer.get() }; + // Fetch the package's properties + const auto packageProperties{ get_package_properties(packageFullName, packageInfoReference) }; + + // Does this package meet the criteria? + const auto optionsToMatchPackageType{ options & maskMatchPackageType }; + return WI_IsAnyFlagSet(packageProperties, maskMatchPackageType) && WI_IsAnyFlagSet(packageProperties, maskMatchStaticDynamic); } inline std::filesystem::path get_package_file( @@ -44,7 +119,7 @@ inline std::filesystem::path get_package_file( { std::filesystem::path absoluteFilename; - auto packagePath{ appmodel::get_package_path(packageFullName, packagePathType) }; + auto packagePath{ ::AppModel::Package::GetPath(packageFullName, packagePathType) }; if (!packagePath.empty()) { absoluteFilename = packagePath; @@ -60,46 +135,99 @@ inline std::filesystem::path get_package_file( inline std::filesystem::path get_package_file( PCWSTR packageFullName, _In_ PCWSTR filename, - _In_ GetPackageFilePathOptions options) + _In_ GetPackageFilePathOptions effectiveOptions, + PACKAGE_INFO_REFERENCE packageInfoReference) { - std::filesystem::path path; + // Restrict matches to specific package types? + if (!is_match_for_package_properties(packageFullName, effectiveOptions, packageInfoReference)) + { + return std::filesystem::path{}; + } // Search External location + std::filesystem::path path; if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchUserExternalPath)) { if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) { // EffectiveExternal == UserExternal if package/user has one else MachineExternal - path = get_package_file(packageFullName, filename, options, PackagePathType_EffectiveExternal); + path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_EffectiveExternal); } else { - path = get_package_file(packageFullName, filename, options, PackagePathType_UserExternal); + path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_UserExternal); } } else if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) { - path = get_package_file(packageFullName, filename, options, PackagePathType_MachineExternal); + path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_MachineExternal); } if (path.empty()) { // Search Mutable location if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMutablePath)) { - path = get_package_file(packageFullName, filename, options, PackagePathType_Mutable); + path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_Mutable); } if (path.empty()) { // Search Install location if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchInstallPath)) { - path = get_package_file(packageFullName, filename, options, PackagePathType_Install); + path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_Install); } } } + return path; +} - // Not found - return std::filesystem::path{}; +inline GetPackageFilePathOptions ToEffectiveOptions( + GetPackageFilePathOptions options) +{ + // If options == None then use default behavior (search everything) + if (options == GetPackageFilePathOptions_None) + { + return GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchMutablePath | + GetPackageFilePathOptions_SearchMachineExternalPath | + GetPackageFilePathOptions_SearchUserExternalPath | + GetPackageFilePathOptions_SearchMainPackages | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchOptionalPackages | + GetPackageFilePathOptions_SearchResourcePackages | + GetPackageFilePathOptions_SearchBundlePackages | + GetPackageFilePathOptions_SearchHostRuntimeDependencies | + GetPackageFilePathOptions_SearchStaticDependencies | + GetPackageFilePathOptions_SearchDynamicDependencies; + } + + // If Search*Dependencies are all clear then search them all + // where * = Main | Framework | Optional | Resource | Bundle | HostRuntime + // + // NOTE: HostRuntime isn't a PackageType but little white lie here for our filtering. + // For example, a Main package shouldn't be searched given options=SearchFrameworkDependnecies + // but it should be search if the Main package declares a and + // options=SearchFrameworkDependencies | SearchHostRuntimeDependencies. + constexpr auto maskPackageTypes{ GetPackageFilePathOptions_SearchMainPackages | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchOptionalPackages | + GetPackageFilePathOptions_SearchResourcePackages | + GetPackageFilePathOptions_SearchBundlePackages | + GetPackageFilePathOptions_SearchHostRuntimeDependencies }; + if (WI_AreAllFlagsClear(options, maskPackageTypes)) + { + // If SearchStaticDependencies and SearchDynamicDependencies are clear then search both + options |= maskPackageTypes; + } + + // If SearchStaticDependencies and SearchDynamicDependencies are all clear then search both + constexpr auto maskStaticDynamicDependencies{ GetPackageFilePathOptions_SearchStaticDependencies | GetPackageFilePathOptions_SearchDynamicDependencies }; + if (WI_AreAllFlagsClear(options, maskStaticDynamicDependencies)) + { + options |= maskStaticDynamicDependencies; + } + + return options; } } @@ -117,12 +245,20 @@ STDAPI GetPackageFilePath( WCHAR packageFullNameBuffer[PACKAGE_FULL_NAME_MAX_LENGTH + 1]{}; if (::Microsoft::Foundation::String::IsNullOrEmpty(packageFullName)) { - uint32_t packageFullNameBufferLength{ ARRAYSIZE(packageFullNameBuffer) }; + std::uint32_t packageFullNameBufferLength{ ARRAYSIZE(packageFullNameBuffer) }; RETURN_IF_WIN32_ERROR(::GetCurrentPackageFullName(&packageFullNameBufferLength, packageFullNameBuffer)); packageFullName = packageFullNameBuffer; } - auto path{ appmodel::get_package_file(packageFullName, filename, options) }; + // Let's do it... + const auto effectiveOptions{ appmodel::ToEffectiveOptions(options) }; + wil::unique_package_info_reference packageInfoReference; + auto rc{ ::OpenPackageInfoByFullName(packageFullName, 0, wil::out_param(packageInfoReference)) }; + if (rc != ERROR_SUCCESS) + { + THROW_WIN32_MSG(rc, "OpenPackageInfoByFullName(%ls,...)", packageFullName); + } + auto path{ appmodel::get_package_file(packageFullName, filename, effectiveOptions, packageInfoReference.get()) }; if (!path.empty()) { auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) }; @@ -149,25 +285,29 @@ STDAPI GetPackageFilePathInPackageGraph( RETURN_HR_IF(E_INVALIDARG, ::Microsoft::Foundation::String::IsNullOrEmpty(filename)); + // Compute the effective options + const auto effectiveOptions{ appmodel::ToEffectiveOptions(options) }; + // Ideally we'd pass our filtering needs down to package graph query API (e.g. GetCurrentPackageGraph) // but it doesn't quite give us the semantics we need, so we'll do it the hard way. // - // We can (partially) optimize filtering checks for PackageType=Framework|Resource|Optional and HostRuntime|Static|Dynamic + // We can (partially) optimize filtering checks for PackageType=Framework|Resource|Optional|Bundle and HostRuntime|Static|Dynamic // by a simple bitmask check. We can only determine if PackageType=Main by the absence of other properties. - const UINT32 flagsMask{ (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchFrameworkPackages) ? PACKAGE_PROPERTY_FRAMEWORK : 0u) | - (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchResourcePackages) ? PACKAGE_PROPERTY_RESOURCE : 0u) | - (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchOptionalPackages) ? PACKAGE_PROPERTY_OPTIONAL : 0u) | - (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchHostRuntimeDependencies) ? PACKAGE_PROPERTY_HOSTRUNTIME : 0u) | - (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchStaticDependencies) ? PACKAGE_PROPERTY_STATIC : 0u) | - (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchDynamicDependencies) ? PACKAGE_PROPERTY_DYNAMIC : 0u) }; + const UINT32 flagsMask{ (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchFrameworkPackages) ? PACKAGE_PROPERTY_FRAMEWORK : 0u) | + (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchOptionalPackages) ? PACKAGE_PROPERTY_OPTIONAL : 0u) | + (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchResourcePackages) ? PACKAGE_PROPERTY_RESOURCE : 0u) | + (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchBundlePackages) ? PACKAGE_PROPERTY_BUNDLE : 0u) | + (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchHostRuntimeDependencies) ? PACKAGE_PROPERTY_HOSTRUNTIME : 0u) | + (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchStaticDependencies) ? PACKAGE_PROPERTY_STATIC : 0u) | + (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchDynamicDependencies) ? PACKAGE_PROPERTY_DYNAMIC : 0u) }; // Search the package graph - UINT32 flags{ PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC }; - uint32_t packageGraphCount{}; + UINT32 flags{ PACKAGE_FILTER_BUNDLE | PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_HOSTRUNTIME | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC }; + std::uint32_t packageGraphCount{}; const PACKAGE_INFO* packageInfo{}; wil::unique_cotaskmem_ptr buffer; RETURN_IF_FAILED(::AppModel::PackageGraph::GetCurrentPackageGraph(flags, packageGraphCount, packageInfo, buffer)); - for (uint32_t index=0; index < packageGraphCount; ++index) + for (std::uint32_t index=0; index < packageGraphCount; ++index) { const auto& pi{ packageInfo[index] }; @@ -197,7 +337,7 @@ STDAPI GetPackageFilePathInPackageGraph( // This package is included in our search. Check for the file const auto packageFullName{ pi.packageFullName }; - auto path{ appmodel::get_package_file(packageFullName, filename, options) }; + auto path{ appmodel::get_package_file(packageFullName, filename, options, nullptr) }; if (!path.empty()) { auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) }; diff --git a/dev/Package/package_runtime.h b/dev/Package/package_runtime.h index 9e28ea5088..6fce2c92a0 100644 --- a/dev/Package/package_runtime.h +++ b/dev/Package/package_runtime.h @@ -11,42 +11,82 @@ typedef enum GetPackageFilePathOptions GetPackageFilePathOptions_None = 0, /// Include the package's Install path in the file search order + /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath, + /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchInstallPath = 0x0001, /// Include the package's Mutable path (if it has one) in the file search order + /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath, + /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchMutablePath = 0x0002, /// Include the package's Machine External path (if it has one) in the file search order + /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath, + /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchMachineExternalPath = 0x0004, /// Include the package's User External path (if it has one) in the file search order + /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath, + /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchUserExternalPath = 0x0008, /// Include Main packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchMainPackages = 0x0010, /// Include Framework packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchFrameworkPackages = 0x0020, /// Include Optional packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchOptionalPackages = 0x0040, /// Include Resource packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchResourcePackages = 0x0080, + /// Include Bundle packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). + GetPackageFilePathOptions_SearchBundlePackages = 0x0100, + /// Include HostRuntime dependencies in the file search order - GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0100, + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). + GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0200, /// Include Static package dependencies in the file search order /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). - GetPackageFilePathOptions_SearchStaticDependencies = 0x0200, + GetPackageFilePathOptions_SearchStaticDependencies = 0x0400, /// Include Dynamic package dependencies in the file search order /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). - GetPackageFilePathOptions_SearchDynamicDependencies = 0x0400, + GetPackageFilePathOptions_SearchDynamicDependencies = 0x0800, } GetPackageFilePathOptions; +DEFINE_ENUM_FLAG_OPERATORS(GetPackageFilePathOptions) /// Return the absolute path to the file in the package. /// @param packageFullName the package, or NULL or "" to use the current process' package identity. diff --git a/dev/Package/pch.h b/dev/Package/pch.h index 50deffc909..ec82c53552 100644 --- a/dev/Package/pch.h +++ b/dev/Package/pch.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -27,4 +28,5 @@ #include #include +#include #include diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index d790ea81f5..95fa5ae234 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -54,6 +54,7 @@ #include #include +#include #include #include #include diff --git a/specs/package/Package.md b/specs/package/Package.md index 0de5f61fa0..7e02154a24 100644 --- a/specs/package/Package.md +++ b/specs/package/Package.md @@ -297,8 +297,8 @@ string GetResourcesPri(string packageFullName) std::wstring GetResourcesPri(PCWSTR packageFullName) { GetPackageFilePathOptions options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchMachineExternalPath | - GetPackageFilePathOptions_SearchUserExternalPath }; + GetPackageFilePathOptions_SearchMachineExternalPath | + GetPackageFilePathOptions_SearchUserExternalPath }; wil::unique_process_heap_string absoluteFilename; const HRESULT hr{ GetPackageFilePath( packageFullName, L"resources.pri", options, wistd::out_param(absoluteFilename)) }; @@ -363,7 +363,7 @@ std::wstring GetXamlWinMD() ## 4.5. Get a file path in the current process' package graph with options Locate `Microsoft.UI.Xaml.winmd` in the current process' package graph but ignore Mutable locations, -Resource packages and HostRuntime dependencies. +Resource and Resource packages and HostRuntime dependencies. ### 4.5.1. C# Example @@ -447,38 +447,75 @@ namespace Microsoft.Windows.ApplicationModel None = 0, /// Include the package's Install path in the file search order + /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). SearchInstallPath = 0x0001, /// Include the package's Mutable path (if it has one) in the file search order + /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). SearchMutablePath = 0x0002, /// Include the package's Machine External path (if it has one) in the file search order + /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). SearchMachineExternalPath = 0x0004, /// Include the package's User External path (if it has one) in the file search order + /// @note If SearchInstallPath, SearchMutablePath, SearchMachineExternalPath and SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). SearchUserExternalPath = 0x0008, /// Include Main packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). SearchMainPackages = 0x0010, /// Include Framework packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). SearchFrameworkPackages = 0x0020, /// Include Optional packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). SearchOptionalPackages = 0x0040, /// Include Resource packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). SearchResourcePackages = 0x0080, + /// Include Bundle packages in the file search order + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). + SearchBundlePackages = 0x0100, + /// Include HostRuntime dependencies in the file search order - SearchHostRuntimeDependencies = 0x0100, + /// @note If SearchMainPackages, SearchFrameworkPackages, SearchOptionalPackages, + /// SearchResourcePackages, SearchBundlePackages and SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none + /// yields the same result). + SearchHostRuntimeDependencies = 0x0200, /// Include Static package dependencies in the file search order - SearchStaticDependencies = 0x0200, + /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + SearchStaticDependencies = 0x0400, /// Include Dynamic package dependencies in the file search order - SearchDynamicDependencies = 0x0400, - } + /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + SearchDynamicDependencies = 0x0800, + }; [contract(PackageRuntimeContract, 1)] runtimeclass Package @@ -541,7 +578,7 @@ namespace Microsoft.Windows.ApplicationModel /// @see Package.GetFilePath /// @see GetPackageFilePathOptions [method_name("GetFilePathWithOptions")] - static String GetFilePath(String filename, GetPackageFilePathOptions options); + static String GetFilePath(String filename, GetFilePathOptions options); }; } ``` @@ -564,38 +601,82 @@ typedef enum GetPackageFilePathOptions GetPackageFilePathOptions_None = 0, /// Include the package's Install path in the file search order + /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath, + /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchInstallPath = 0x0001, /// Include the package's Mutable path (if it has one) in the file search order + /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath, + /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchMutablePath = 0x0002, /// Include the package's Machine External path (if it has one) in the file search order + /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath, + /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchMachineExternalPath = 0x0004, /// Include the package's User External path (if it has one) in the file search order + /// @note If GetPackageFilePathOptions_SearchInstallPath, GetPackageFilePathOptions_SearchMutablePath, + /// GetPackageFilePathOptions_SearchMachineExternalPath and GetPackageFilePathOptions_SearchUserExternalPath + /// are omitted then all locations are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchUserExternalPath = 0x0008, /// Include Main packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchMainPackages = 0x0010, /// Include Framework packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchFrameworkPackages = 0x0020, /// Include Optional packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchOptionalPackages = 0x0040, /// Include Resource packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchResourcePackages = 0x0080, + /// Include Bundle packages in the file search order + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). + GetPackageFilePathOptions_SearchBundlePackages = 0x0100, + /// Include HostRuntime dependencies in the file search order - GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0100, + /// @note If GetPackageFilePathOptions_SearchMainPackages, GetPackageFilePathOptions_SearchFrameworkPackages, + /// GetPackageFilePathOptions_SearchOptionalPackages, GetPackageFilePathOptions_SearchResourcePackages, + /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies + /// are omitted then all package types are searched (i.e. specify all or none yields the same result). + GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0200, /// Include Static package dependencies in the file search order - GetPackageFilePathOptions_SearchStaticDependencies = 0x0200, + /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted + /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + GetPackageFilePathOptions_SearchStaticDependencies = 0x0400, /// Include Dynamic package dependencies in the file search order - GetPackageFilePathOptions_SearchDynamicDependencies = 0x0400, -} + /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted + /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + GetPackageFilePathOptions_SearchDynamicDependencies = 0x0800, +} GetPackageFilePathOptions; +DEFINE_ENUM_FLAG_OPERATORS(GetPackageFilePathOptions) /// Return the absolute path to the file in the package. /// @param packageFullName the package, or NULL or "" to use the current process' package identity. diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h index cba5b0cd7b..dce41c79d4 100644 --- a/test/Package/API/PackageTests.Packages.h +++ b/test/Package/API/PackageTests.Packages.h @@ -122,6 +122,10 @@ namespace Test::Package::Tests const auto path{ TP::GetMsixPackagePath(TP::UserExternal::c_packageDirName).parent_path() }; TP::StagePackageIfNecessary(TP::UserExternal::c_packageDirName, TP::UserExternal::c_packageFullName, path.c_str()); } + inline void RegisterPackage_UserExternal() + { + TP::RegisterPackageIfNecessary(TP::UserExternal::c_packageFullName); + } inline void RemovePackage_UserExternal() { if (IsPackageRegistered_UserExternal()) @@ -167,15 +171,18 @@ namespace Test::Package::Tests } inline void AddPackage_MachineExternal() { - TP::AddPackageIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName); + const auto path{ TP::GetMsixPackagePath(TP::MachineExternal::c_packageDirName).parent_path()}; + TP::AddPackageIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName, path.c_str()); } inline void AddPackageDefer_MachineExternal() { - TP::AddPackageDeferIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName); + const auto path{ TP::GetMsixPackagePath(TP::MachineExternal::c_packageDirName).parent_path() }; + TP::AddPackageDeferIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName, path.c_str()); } inline void StagePackage_MachineExternal() { - TP::StagePackageIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName); + const auto path{ TP::GetMsixPackagePath(TP::MachineExternal::c_packageDirName).parent_path() }; + TP::StagePackageIfNecessary(TP::MachineExternal::c_packageDirName, TP::MachineExternal::c_packageFullName, path.c_str()); } inline void RegisterPackage_MachineExternal() { diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp index 5837b6a054..1c3ce59294 100644 --- a/test/Package/API/PackageTests_CPP.cpp +++ b/test/Package/API/PackageTests_CPP.cpp @@ -32,13 +32,14 @@ namespace Test::Package::Tests { ::TB::Setup(); - //RemovePackage_MachineExternal(); + RemovePackage_MachineExternal(); RemovePackage_UserExternal(); RemovePackage_Mutable(); AddPackage_Mutable(); AddPackage_UserExternal(); - //AddPackage_MachineExternal(); + StagePackage_MachineExternal(); + AddPackage_MachineExternal(); return true; } @@ -85,6 +86,7 @@ namespace Test::Package::Tests wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); //TODO + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); } TEST_METHOD(GetPackageFilePath_InstallPath) diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index ab37095103..7b44cb8a83 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -31,11 +31,11 @@ namespace Test::Package::Tests ::TB::Setup(); //RemovePackage_MachineExternal(); - //RemovePackage_UserExternal(); + RemovePackage_UserExternal(); RemovePackage_Mutable(); AddPackage_Mutable(); - //AddPackage_UserExternal(); + AddPackage_UserExternal(); //AddPackage_MachineExternal(); return true; @@ -58,7 +58,7 @@ namespace Test::Package::Tests { winrt::hstring packageFullName{ Framework_PackageFullName }; winrt::hstring noFileName; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(packageFullName, noFileName); + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noFileName, packageFullName); VERIFY_FAIL(L"Success is not expected"); } catch (winrt::hresult_error& e) @@ -71,7 +71,7 @@ namespace Test::Package::Tests winrt::hstring packageFullName{ Framework_PackageFullName }; winrt::hstring noFileName; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(packageFullName, noFileName, options); + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noFileName, packageFullName, options); VERIFY_FAIL(L"Success is not expected"); } catch (winrt::hresult_error& e) @@ -86,7 +86,7 @@ namespace Test::Package::Tests { winrt::hstring noPackageFullName; winrt::hstring fileName{ L"AppxManifest.xml" }; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noPackageFullName, fileName); + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, noPackageFullName); VERIFY_FAIL(L"Success is not expected"); } catch (winrt::hresult_error& e) @@ -99,7 +99,7 @@ namespace Test::Package::Tests winrt::hstring noPackageFullName; winrt::hstring fileName{ L"AppxManifest.xml" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noPackageFullName, fileName, options); + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, noPackageFullName, options); VERIFY_FAIL(L"Success is not expected"); } catch (winrt::hresult_error& e) From 2d14aff0bcaf9850950a8f5e49abfba0ea021d5f Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 25 Jan 2026 23:41:39 -0800 Subject: [PATCH 12/33] Added TAEF VERIFY_* support for std::filesystem::path. More fixes and test updates --- dev/Package/Package.idl | 12 +- dev/Package/package_runtime.cpp | 216 +++++++++--------- dev/Package/package_runtime.h | 6 + specs/package/Package.md | 18 +- test/Package/API/PackageTests_CPP.cpp | 94 ++++++-- test/Package/API/PackageTests_WinRT.cpp | 10 +- test/Package/API/pch.h | 1 + .../WindowsAppRuntime.Test.TAEF.cppwinrt.h | 2 +- test/inc/WindowsAppRuntime.Test.TAEF.stl.h | 104 +++++++++ 9 files changed, 334 insertions(+), 129 deletions(-) create mode 100644 test/inc/WindowsAppRuntime.Test.TAEF.stl.h diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl index eb38c6cd7f..d3902b57b1 100644 --- a/dev/Package/Package.idl +++ b/dev/Package/Package.idl @@ -81,11 +81,19 @@ namespace Microsoft.Windows.ApplicationModel SearchHostRuntimeDependencies = 0x0200, /// Include Static package dependencies in the file search order - /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and + /// dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note This option is only relevant when searching the package graph i.e. methods of PackageGraph. + /// @see PackageGraph::GetFilePath() + /// @see SearchDynamicDependencies SearchStaticDependencies = 0x0400, /// Include Dynamic package dependencies in the file search order - /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and + /// dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note This option is only relevant when searching the package graph i.e. methods of PackageGraph. + /// @see PackageGraph::GetFilePath() + /// @see SearchStaticDependencies SearchDynamicDependencies = 0x0800, }; diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index 79d04877bd..410f9e0129 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -7,26 +7,53 @@ namespace appmodel { -inline LONG get_package_info( - _In_opt_ PACKAGE_INFO_REFERENCE packageInfoReference, - UINT32 flags, - _Inout_ BYTE* bufferLength, - _Out_writes_bytes_opt_(*bufferLength) BYTE* buffer, - _Out_opt_ std::uint32 count) +inline GetPackageFilePathOptions package_properties_to_options( + PCWSTR packageFullName, + std::uint32_t packageInfoFlags) { - return packageInfoReference ? - ::GetPackageInfo(packageInfoReference, flags, bufferLength, buffer, count) : - ::GetCurrentPackageInfo(flags, bufferLength, buffer, count); + const auto hostRuntimeMatch{ WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_HOSTRUNTIME) ? + GetPackageFilePathOptions_SearchHostRuntimeDependencies : + GetPackageFilePathOptions_None }; + const auto isStaticDependency{ WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_STATIC) ? + GetPackageFilePathOptions_SearchStaticDependencies : + GetPackageFilePathOptions_None }; + const auto isDynamicDependency{ WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_DYNAMIC) ? + GetPackageFilePathOptions_SearchDynamicDependencies : + GetPackageFilePathOptions_None }; + if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_FRAMEWORK)) + { + return GetPackageFilePathOptions_SearchFrameworkPackages | hostRuntimeMatch; + } + else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_OPTIONAL)) + { + return GetPackageFilePathOptions_SearchOptionalPackages | hostRuntimeMatch; + } + else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_RESOURCE)) + { + return GetPackageFilePathOptions_SearchResourcePackages | hostRuntimeMatch; + } + else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_BUNDLE)) + { + return GetPackageFilePathOptions_SearchBundlePackages | hostRuntimeMatch; + } + else + { + // PACKAGE_INFO.flags has no PACKAGE_PROPERTY_MAIN so we can only determine PackageType=Main + // by first verifying it's not any other type of package (Bundle|Framework|Optional|Resource). + // When all else is ruled out what we're left with must be a Main package + return GetPackageFilePathOptions_SearchMainPackages | hostRuntimeMatch; + } } inline GetPackageFilePathOptions get_package_properties( PCWSTR packageFullName, PACKAGE_INFO_REFERENCE packageInfoReference) { + // Fetch the package's properties constexpr auto flags{ PACKAGE_FILTER_BUNDLE | PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_HOSTRUNTIME | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC }; std::uint32_t bufferLength{}; std::uint32_t count{}; - auto rc{ get_package_info(packageInfoReference, flags, &bufferLength, nullptr, &count) }; + auto rc{ ::GetPackageInfo(packageInfoReference, flags, &bufferLength, nullptr, &count) }; if (rc != ERROR_INSUFFICIENT_BUFFER) { if (rc == ERROR_SUCCESS) @@ -41,49 +68,49 @@ inline GetPackageFilePathOptions get_package_properties( THROW_WIN32_MSG(rc, "GetPackageInfo(...query...) %ls", packageFullName); } std::unique_ptr buffer{ std::make_unique(bufferLength) }; - THROW_IF_WIN32_ERROR_MSG(::GetPackageInfo(packageInfoReference.get(), flags, &bufferLength, buffer.get(), &count), + THROW_IF_WIN32_ERROR_MSG(::GetPackageInfo(packageInfoReference, flags, &bufferLength, buffer.get(), &count), "GetPackageInfo: %ls", packageFullName); THROW_HR_IF(E_UNEXPECTED, count == 0); // This should never occur const auto& packageInfo{ *reinterpret_cast(buffer.get()) }; - const auto hostRuntimeMatch{ WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_HOSTRUNTIME) ? - GetPackageFilePathOptions_SearchHostRuntimeDependencies : - GetPackageFilePathOptions_None }; - const auto isStaticDependency{ WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_STATIC) ? - GetPackageFilePathOptions_SearchStaticDependencies : - GetPackageFilePathOptions_None }; - const auto isDynamicDependency{ WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_DYNAMIC) ? - GetPackageFilePathOptions_SearchDynamicDependencies : - GetPackageFilePathOptions_None }; - if (WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_FRAMEWORK)) - { - return GetPackageFilePathOptions_SearchFrameworkPackages | hostRuntimeMatch; - } - else if (WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_OPTIONAL)) - { - return GetPackageFilePathOptions_SearchOptionalPackages | hostRuntimeMatch; - } - else if (WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_RESOURCE)) - { - return GetPackageFilePathOptions_SearchResourcePackages | hostRuntimeMatch; - } - else if (WI_IsFlagSet(packageInfo.flags, PACKAGE_PROPERTY_BUNDLE)) - { - return GetPackageFilePathOptions_SearchBundlePackages | hostRuntimeMatch; - } - else - { - // PACKAGE_INFO.Flags has no PACKAGE_PROPERTY_MAIN so we can only determine PackageType=Main - // by first verifying it's not any other type of package (Bundle|Framework|Optional|Resource). - // When all else is ruled out what we're left with must be a Main package - return GetPackageFilePathOptions_SearchMainPackages | hostRuntimeMatch; - } + // Convert the package properties to options + return package_properties_to_options(packageFullName, packageInfo.flags); } inline bool is_match_for_package_properties( PCWSTR packageFullName, _In_ GetPackageFilePathOptions options, PACKAGE_INFO_REFERENCE packageInfoReference) +{ + // We're processing a package definition i.e. always static information. + // Thus ignore GetPackageFilePathOptions_SearchStaticDependencies + // and GetPackageFilePathOptions_SearchDynamicDependencies options. + + // Detect PackageType|HostRuntimeDependency + // + // If options = All or None specified then all packages are a match thus no need to fetch the package's properties + constexpr auto maskMatchPackageType{ GetPackageFilePathOptions_SearchMainPackages | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchOptionalPackages | + GetPackageFilePathOptions_SearchResourcePackages | + GetPackageFilePathOptions_SearchBundlePackages | + GetPackageFilePathOptions_SearchHostRuntimeDependencies }; + const auto optionsToMatch{ options & maskMatchPackageType }; + if ((optionsToMatch == GetPackageFilePathOptions_None) || (optionsToMatch == maskMatchPackageType)) + { + return true; + } + + // Fetch the package's properties + const auto packageProperties{ get_package_properties(packageFullName, packageInfoReference) }; + + // Does this package meet the criteria? + return WI_IsAnyFlagSet(packageProperties, optionsToMatch); +} + +inline bool is_match_for_package_properties( + _In_ GetPackageFilePathOptions options, + std::uint32_t packageInfoFlags) { // Detect PackageType|HostRuntimeDependency and Static|DynamicDependency // @@ -103,15 +130,11 @@ inline bool is_match_for_package_properties( return true; } - // Fetch the package's properties - const auto packageProperties{ get_package_properties(packageFullName, packageInfoReference) }; - // Does this package meet the criteria? - const auto optionsToMatchPackageType{ options & maskMatchPackageType }; - return WI_IsAnyFlagSet(packageProperties, maskMatchPackageType) && WI_IsAnyFlagSet(packageProperties, maskMatchStaticDynamic); + return WI_IsAnyFlagSet(packageInfoFlags, maskMatchPackageType) && WI_IsAnyFlagSet(packageInfoFlags, maskMatchStaticDynamic); } -inline std::filesystem::path get_package_file( +inline std::filesystem::path get_package_file_for_location( PCWSTR packageFullName, _In_ PCWSTR filename, _In_ GetPackageFilePathOptions options, @@ -135,15 +158,8 @@ inline std::filesystem::path get_package_file( inline std::filesystem::path get_package_file( PCWSTR packageFullName, _In_ PCWSTR filename, - _In_ GetPackageFilePathOptions effectiveOptions, - PACKAGE_INFO_REFERENCE packageInfoReference) + _In_ GetPackageFilePathOptions options) { - // Restrict matches to specific package types? - if (!is_match_for_package_properties(packageFullName, effectiveOptions, packageInfoReference)) - { - return std::filesystem::path{}; - } - // Search External location std::filesystem::path path; if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchUserExternalPath)) @@ -151,36 +167,52 @@ inline std::filesystem::path get_package_file( if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) { // EffectiveExternal == UserExternal if package/user has one else MachineExternal - path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_EffectiveExternal); + path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_EffectiveExternal); } else { - path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_UserExternal); + path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_UserExternal); } } else if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) { - path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_MachineExternal); + path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_MachineExternal); } if (path.empty()) { // Search Mutable location if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMutablePath)) { - path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_Mutable); + path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_Mutable); } if (path.empty()) { // Search Install location if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchInstallPath)) { - path = get_package_file(packageFullName, filename, effectiveOptions, PackagePathType_Install); + path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_Install); } } } return path; } +inline std::filesystem::path get_package_file( + PCWSTR packageFullName, + _In_ PCWSTR filename, + _In_ GetPackageFilePathOptions effectiveOptions, + PACKAGE_INFO_REFERENCE packageInfoReference) +{ + // Does the package's properties match our search criteria? + if (!is_match_for_package_properties(packageFullName, effectiveOptions, packageInfoReference)) + { + return std::filesystem::path{}; + } + + // Search the package's locations for the file + return get_package_file(packageFullName, filename, effectiveOptions); +} + inline GetPackageFilePathOptions ToEffectiveOptions( GetPackageFilePathOptions options) { @@ -268,14 +300,6 @@ STDAPI GetPackageFilePath( } CATCH_RETURN(); -/// Is a PACKAGE_INFO entry a Main package? -/// @note There's no direct propery to check indicating a Main package. -/// That's only detectable by the absence of any other type of package. -inline constexpr bool IsMainPackage(const UINT32 packageInfoFlags) -{ - return WI_AreAllFlagsClear(packageInfoFlags, PACKAGE_PROPERTY_BUNDLE | PACKAGE_PROPERTY_FRAMEWORK | PACKAGE_PROPERTY_OPTIONAL | PACKAGE_PROPERTY_RESOURCE); -} - STDAPI GetPackageFilePathInPackageGraph( _In_ PCWSTR filename, _In_ GetPackageFilePathOptions options, @@ -288,56 +312,28 @@ STDAPI GetPackageFilePathInPackageGraph( // Compute the effective options const auto effectiveOptions{ appmodel::ToEffectiveOptions(options) }; - // Ideally we'd pass our filtering needs down to package graph query API (e.g. GetCurrentPackageGraph) - // but it doesn't quite give us the semantics we need, so we'll do it the hard way. - // - // We can (partially) optimize filtering checks for PackageType=Framework|Resource|Optional|Bundle and HostRuntime|Static|Dynamic - // by a simple bitmask check. We can only determine if PackageType=Main by the absence of other properties. - const UINT32 flagsMask{ (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchFrameworkPackages) ? PACKAGE_PROPERTY_FRAMEWORK : 0u) | - (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchOptionalPackages) ? PACKAGE_PROPERTY_OPTIONAL : 0u) | - (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchResourcePackages) ? PACKAGE_PROPERTY_RESOURCE : 0u) | - (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchBundlePackages) ? PACKAGE_PROPERTY_BUNDLE : 0u) | - (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchHostRuntimeDependencies) ? PACKAGE_PROPERTY_HOSTRUNTIME : 0u) | - (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchStaticDependencies) ? PACKAGE_PROPERTY_STATIC : 0u) | - (WI_IsFlagSet(effectiveOptions, GetPackageFilePathOptions_SearchDynamicDependencies) ? PACKAGE_PROPERTY_DYNAMIC : 0u) }; - // Search the package graph - UINT32 flags{ PACKAGE_FILTER_BUNDLE | PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_HOSTRUNTIME | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC }; + // + // Ideally we'd pass our filtering needs down to package graph query API (e.g. GetCurrentPackageGraph) + // but it doesn't quite give us the semantics we need, so we'll do it the hard way + constexpr std::uint32_t flags{ PACKAGE_FILTER_BUNDLE | PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_RESOURCE | PACKAGE_FILTER_OPTIONAL | PACKAGE_FILTER_HOSTRUNTIME | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC }; std::uint32_t packageGraphCount{}; - const PACKAGE_INFO* packageInfo{}; + const PACKAGE_INFO* packageInfos{}; wil::unique_cotaskmem_ptr buffer; - RETURN_IF_FAILED(::AppModel::PackageGraph::GetCurrentPackageGraph(flags, packageGraphCount, packageInfo, buffer)); + RETURN_IF_FAILED(::AppModel::PackageGraph::GetCurrentPackageGraph(flags, packageGraphCount, packageInfos, buffer)); for (std::uint32_t index=0; index < packageGraphCount; ++index) { - const auto& pi{ packageInfo[index] }; + const auto& packageInfo{ packageInfos[index] }; - // Default behavior is search everything. Do we need to filter to a subset? - if (options != GetPackageFilePathOptions_None) + // Does the package's properties match our search criteria? + const auto packageFullName{ packageInfo.packageFullName }; + if (!appmodel::is_match_for_package_properties(effectiveOptions, packageInfo.flags)) { - // Does this package meet any of the simple filtering criteria: Framework|Resource|Optional|HostRuntime|Static|Dynamic - if (WI_AreAllFlagsClear(pi.flags, flagsMask)) - { - // Nope! Complex filtering time. Is this a Main package? - if (IsMainPackage(pi.flags)) - { - // Are Main packages included in our search? - if (WI_IsFlagClear(options, GetPackageFilePathOptions::GetPackageFilePathOptions_SearchMainPackages)) - { - // It's a Main package but we're not interested in Main packages. Skip it - continue; - } - } - else - { - // It's not a Main package, and it doesn't meet any other filter criteria. Skip it - continue; - } - } + continue; } // This package is included in our search. Check for the file - const auto packageFullName{ pi.packageFullName }; - auto path{ appmodel::get_package_file(packageFullName, filename, options, nullptr) }; + auto path{ appmodel::get_package_file(packageFullName, filename, options) }; if (!path.empty()) { auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) }; diff --git a/dev/Package/package_runtime.h b/dev/Package/package_runtime.h index 6fce2c92a0..a4fd9c8831 100644 --- a/dev/Package/package_runtime.h +++ b/dev/Package/package_runtime.h @@ -79,11 +79,17 @@ typedef enum GetPackageFilePathOptions /// Include Static package dependencies in the file search order /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note This option is only relevant when searching the package graph i.e. GetPackageFilePathInPackageGraph(); + /// @see GetPackageFilePathInPackageGraph() + /// @see GetPackageFilePathOptions_SearchDynamicDependencies GetPackageFilePathOptions_SearchStaticDependencies = 0x0400, /// Include Dynamic package dependencies in the file search order /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note This option is only relevant when searching the package graph i.e. GetPackageFilePathInPackageGraph(); + /// @see GetPackageFilePathInPackageGraph() + /// @see GetPackageFilePathOptions_SearchStaticDependencies GetPackageFilePathOptions_SearchDynamicDependencies = 0x0800, } GetPackageFilePathOptions; DEFINE_ENUM_FLAG_OPERATORS(GetPackageFilePathOptions) diff --git a/specs/package/Package.md b/specs/package/Package.md index 7e02154a24..7354c0d2b5 100644 --- a/specs/package/Package.md +++ b/specs/package/Package.md @@ -509,11 +509,19 @@ namespace Microsoft.Windows.ApplicationModel SearchHostRuntimeDependencies = 0x0200, /// Include Static package dependencies in the file search order - /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and + /// dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note This option is only relevant when searching the package graph i.e. methods of PackageGraph. + /// @see PackageGraph::GetFilePath() + /// @see SearchDynamicDependencies SearchStaticDependencies = 0x0400, /// Include Dynamic package dependencies in the file search order - /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and + /// dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note This option is only relevant when searching the package graph i.e. methods of PackageGraph. + /// @see PackageGraph::GetFilePath() + /// @see SearchStaticDependencies SearchDynamicDependencies = 0x0800, }; @@ -669,11 +677,17 @@ typedef enum GetPackageFilePathOptions /// Include Static package dependencies in the file search order /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note This option is only relevant when searching the package graph i.e. GetPackageFilePathInPackageGraph(); + /// @see GetPackageFilePathInPackageGraph() + /// @see GetPackageFilePathOptions_SearchDynamicDependencies GetPackageFilePathOptions_SearchStaticDependencies = 0x0400, /// Include Dynamic package dependencies in the file search order /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). + /// @note This option is only relevant when searching the package graph i.e. GetPackageFilePathInPackageGraph(); + /// @see GetPackageFilePathInPackageGraph() + /// @see GetPackageFilePathOptions_SearchStaticDependencies GetPackageFilePathOptions_SearchDynamicDependencies = 0x0800, } GetPackageFilePathOptions; DEFINE_ENUM_FLAG_OPERATORS(GetPackageFilePathOptions) diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp index 1c3ce59294..6cbe36952b 100644 --- a/test/Package/API/PackageTests_CPP.cpp +++ b/test/Package/API/PackageTests_CPP.cpp @@ -19,6 +19,8 @@ namespace Test::Package::Tests const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; + const auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName }; + const auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName }; class PackageTests_CPP { @@ -55,6 +57,17 @@ namespace Test::Package::Tests return true; } + std::filesystem::path ToAbsoluteFilename( + PCWSTR packageFullName, + PCWSTR filename, + PackagePathType packageType) + { + const auto path{ ::AppModel::Package::GetPath(packageFullName, packageType) }; + std::filesystem::path absoluteFilename{ path }; + absoluteFilename /= filename; + return absoluteFilename; + } + TEST_METHOD(GetPackageFilePath_InvalidParameter) { PCWSTR packageFullName{ Framework_PackageFullName }; @@ -85,8 +98,11 @@ namespace Test::Package::Tests const auto options{ GetPackageFilePathOptions_None }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - //TODO + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } TEST_METHOD(GetPackageFilePath_InstallPath) @@ -95,9 +111,12 @@ namespace Test::Package::Tests PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath }; wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)), - WEX::Common::String().Format(L"AbsoluteFilename:%s", absoluteFilename.get())); - //TODO + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } TEST_METHOD(GetPackageFilePath_MutablePath) @@ -106,39 +125,87 @@ namespace Test::Package::Tests PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchMutablePath }; wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename)), - WEX::Common::String().Format(L"AbsoluteFilename:%s", absoluteFilename.get())); - //TODO + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } TEST_METHOD(GetPackageFilePath_MachineExternalPath) { - //TODO + PCWSTR packageFullName{ MachineExternal_PackageFullName }; + PCWSTR fileName{ L"msix\\AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } TEST_METHOD(GetPackageFilePath_UserExternalPath) { - //TODO + PCWSTR packageFullName{ UserExternal_PackageFullName }; + PCWSTR fileName{ L"msix\\AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchUserExternalPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch) { - //TODO + PCWSTR packageFullName{ Main_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); } TEST_METHOD(GetPackageFilePath_FilterPackageType_Framework_NoMatch) { - //TODO + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchMainPackages }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); } +#if 0 TEST_METHOD(GetPackageFilePath_Filter_Static_NoMatch) { - //TODO + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchStaticDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); } TEST_METHOD(GetPackageFilePath_Filter_Dynamic_NoMatch) { - //TODO + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchDynamicDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); } TEST_METHOD(GetPackageFilePath_Filter_Static) @@ -150,5 +217,6 @@ namespace Test::Package::Tests { //TODO } +#endif }; } diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index 7b44cb8a83..69661af6a8 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -165,9 +165,16 @@ namespace Test::Package::Tests VERIFY_IS_TRUE(absoluteFilename.empty()); } +#if 0 TEST_METHOD(GetFilePath_Filter_Static_NoMatch) { - //TODO + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchStaticDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); } TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) @@ -190,5 +197,6 @@ namespace Test::Package::Tests { //TODO } +#endif }; } diff --git a/test/Package/API/pch.h b/test/Package/API/pch.h index efe9e7ce67..c02f871a4d 100644 --- a/test/Package/API/pch.h +++ b/test/Package/API/pch.h @@ -31,6 +31,7 @@ #include #include #include +#include #include diff --git a/test/inc/WindowsAppRuntime.Test.TAEF.cppwinrt.h b/test/inc/WindowsAppRuntime.Test.TAEF.cppwinrt.h index 2662a1eb27..22734fee7c 100644 --- a/test/inc/WindowsAppRuntime.Test.TAEF.cppwinrt.h +++ b/test/inc/WindowsAppRuntime.Test.TAEF.cppwinrt.h @@ -71,7 +71,7 @@ namespace WEX::TestExecution } else { - return CompareStringOrdinal(left .c_str(), -1, right.c_str(), -1, FALSE) - CSTR_EQUAL; + return CompareStringOrdinal(left.c_str(), -1, right.c_str(), -1, FALSE) - CSTR_EQUAL; } } }; diff --git a/test/inc/WindowsAppRuntime.Test.TAEF.stl.h b/test/inc/WindowsAppRuntime.Test.TAEF.stl.h new file mode 100644 index 0000000000..17e2e39287 --- /dev/null +++ b/test/inc/WindowsAppRuntime.Test.TAEF.stl.h @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation and Contributors. All rights reserved. +// Licensed under the MIT License. + +#ifndef __WINDOWSAPPRUNTIME_TEST_TAEF_CPPWINRT_H +#define __WINDOWSAPPRUNTIME_TEST_TAEF_CPPWINRT_H + +namespace WEX::TestExecution +{ + // Teach TAEF how to format a std::wstring + template <> + class VerifyOutputTraits + { + public: + static WEX::Common::NoThrowString ToString(std::wstring const& value) + { + return WEX::Common::NoThrowString().Format(L"%s", s); + } + }; + + // Teach TAEF how to compare a std::wstring + template <> + class VerifyCompareTraits + { + public: + static bool AreEqual(std::wstring const& expected, std::wstring const& actual) + { + return Compare(expected, actual) == 0; + } + + static bool AreSame(std::wstring const& expected, std::wstring const& actual) + { + return &expected == &actual; + } + + static bool IsLessThan(std::wstring const& expectedLess, std::wstring const& expectedGreater) + { + return Compare(expectedLess, expectedGreater) < 0; + } + + static bool IsGreaterThan(std::wstring const& expectedGreater, std::wstring const& expectedLess) + { + return Compare(expectedGreater, expectedLess) > 0; + } + + static bool IsNull(std::wstring const& object) + { + return object.c_str() == nullptr; + } + private: + static int Compare(std::wstring const& left, std::wstring const& right) + { + return CompareStringOrdinal(left.c_str(), -1, right.c_str(), -1, FALSE) - CSTR_EQUAL; + } + }; + + // Teach TAEF how to format a std::filesystem::path + template <> + class VerifyOutputTraits + { + public: + static WEX::Common::NoThrowString ToString(std::filesystem::path const& value) + { + return WEX::Common::NoThrowString().Format(L"%s", s); + } + }; + + // Teach TAEF how to compare a std::filesystem::path + template <> + class VerifyCompareTraits + { + public: + static bool AreEqual(std::filesystem::path const& expected, std::filesystem::path const& actual) + { + return Compare(expected, actual) == 0; + } + + static bool AreSame(std::filesystem::path const& expected, std::filesystem::path const& actual) + { + return &expected == &actual; + } + + static bool IsLessThan(std::filesystem::path const& expectedLess, std::filesystem::path const& expectedGreater) + { + return Compare(expectedLess, expectedGreater) < 0; + } + + static bool IsGreaterThan(std::filesystem::path const& expectedGreater, std::filesystem::path const& expectedLess) + { + return Compare(expectedGreater, expectedLess) > 0; + } + + static bool IsNull(std::filesystem::path const& object) + { + return object.c_str() == nullptr; + } + private: + static int Compare(std::filesystem::path const& left, std::filesystem::path const& right) + { + return CompareStringOrdinal(left.c_str(), -1, right.c_str(), -1, FALSE) - CSTR_EQUAL; + } + }; +} + +#endif // __WINDOWSAPPRUNTIME_TEST_TAEF_CPPWINRT_H From 85716e85c2e43eba3fa0050442d31588304efa6a Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 1 Feb 2026 22:24:10 -0800 Subject: [PATCH 13/33] Expanded tests. Bug fixes --- dev/Common/AppModel.Package.h | 14 ++ dev/Common/AppModel.PackageGraph.h | 4 +- dev/Package/package_runtime.cpp | 15 +- test/Package/API/PackageTests.vcxproj | 10 +- test/Package/API/PackageTests.vcxproj.filters | 19 +- test/Package/API/PackageTests_CPP.cpp | 25 +- .../API/PackageTests_PackageGraph_Base.h | 98 ++++++++ ...PackageTests_PackageGraph_Packaged_CPP.cpp | 194 ++++++++++++++ ...ckageTests_PackageGraph_Packaged_WinRT.cpp | 213 ++++++++++++++++ ...ckageTests_PackageGraph_Unpackaged_CPP.cpp | 197 +++++++++++++++ ...ageTests_PackageGraph_Unpackaged_WinRT.cpp | 212 ++++++++++++++++ test/Package/API/PackageTests_Package_CPP.cpp | 209 +++++++++++++++ .../API/PackageTests_Package_WinRT.cpp | 237 ++++++++++++++++++ test/Package/API/PackageTests_WinRT.cpp | 42 +++- test/Package/API/pch.h | 3 + .../Package.Test.MachineExternal.msix.vcxproj | 3 + test/Package/data/MachineExternal/Shadow.cat | 1 + .../Package.Test.UserExternal.msix.vcxproj | 3 + test/Package/data/UserExternal/Shadow.cat | 1 + 19 files changed, 1463 insertions(+), 37 deletions(-) create mode 100644 test/Package/API/PackageTests_PackageGraph_Base.h create mode 100644 test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp create mode 100644 test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp create mode 100644 test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp create mode 100644 test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp create mode 100644 test/Package/API/PackageTests_Package_CPP.cpp create mode 100644 test/Package/API/PackageTests_Package_WinRT.cpp create mode 100644 test/Package/data/MachineExternal/Shadow.cat create mode 100644 test/Package/data/UserExternal/Shadow.cat diff --git a/dev/Common/AppModel.Package.h b/dev/Common/AppModel.Package.h index d8cd1bc641..852cf63649 100644 --- a/dev/Common/AppModel.Package.h +++ b/dev/Common/AppModel.Package.h @@ -6,6 +6,9 @@ #include +#include +#include + #include namespace AppModel::Package @@ -182,6 +185,17 @@ inline Tstring GetEffectivePath(_In_ PCWSTR packageFullName) { return GetPath(packageFullName, PackagePathType_Effective); } + +inline std::filesystem::path GetAbsoluteFilename( + PCWSTR packageFullName, + PCWSTR filename, + PackagePathType packageType) +{ + const auto path{ ::AppModel::Package::GetPath(packageFullName, packageType) }; + std::filesystem::path pathName{ path }; + pathName /= filename; + return std::filesystem::absolute(pathName); +} } #endif // __APPMODEL_PACKAGE_H diff --git a/dev/Common/AppModel.PackageGraph.h b/dev/Common/AppModel.PackageGraph.h index 43a502e42e..97fcb8cb4a 100644 --- a/dev/Common/AppModel.PackageGraph.h +++ b/dev/Common/AppModel.PackageGraph.h @@ -10,14 +10,14 @@ namespace AppModel::PackageGraph { inline HRESULT GetCurrentPackageGraph( const UINT32 flags, - uint32_t& packageInfoCount, + std::uint32_t& packageInfoCount, const PACKAGE_INFO*& packageInfo, wil::unique_cotaskmem_ptr& buffer) { packageInfoCount = 0; packageInfo = nullptr; - uint32_t bufferLength{}; + std::uint32_t bufferLength{}; LONG rc{ ::GetCurrentPackageInfo(flags, &bufferLength, nullptr, &packageInfoCount) }; if ((rc == APPMODEL_ERROR_NO_PACKAGE) || (packageInfoCount == 0)) { diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index 410f9e0129..8cdcac6234 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -8,7 +8,6 @@ namespace appmodel { inline GetPackageFilePathOptions package_properties_to_options( - PCWSTR packageFullName, std::uint32_t packageInfoFlags) { const auto hostRuntimeMatch{ WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_HOSTRUNTIME) ? @@ -22,26 +21,26 @@ inline GetPackageFilePathOptions package_properties_to_options( GetPackageFilePathOptions_None }; if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_FRAMEWORK)) { - return GetPackageFilePathOptions_SearchFrameworkPackages | hostRuntimeMatch; + return GetPackageFilePathOptions_SearchFrameworkPackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; } else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_OPTIONAL)) { - return GetPackageFilePathOptions_SearchOptionalPackages | hostRuntimeMatch; + return GetPackageFilePathOptions_SearchOptionalPackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; } else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_RESOURCE)) { - return GetPackageFilePathOptions_SearchResourcePackages | hostRuntimeMatch; + return GetPackageFilePathOptions_SearchResourcePackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; } else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_BUNDLE)) { - return GetPackageFilePathOptions_SearchBundlePackages | hostRuntimeMatch; + return GetPackageFilePathOptions_SearchBundlePackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; } else { // PACKAGE_INFO.flags has no PACKAGE_PROPERTY_MAIN so we can only determine PackageType=Main // by first verifying it's not any other type of package (Bundle|Framework|Optional|Resource). // When all else is ruled out what we're left with must be a Main package - return GetPackageFilePathOptions_SearchMainPackages | hostRuntimeMatch; + return GetPackageFilePathOptions_SearchMainPackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; } } @@ -74,7 +73,7 @@ inline GetPackageFilePathOptions get_package_properties( const auto& packageInfo{ *reinterpret_cast(buffer.get()) }; // Convert the package properties to options - return package_properties_to_options(packageFullName, packageInfo.flags); + return package_properties_to_options(packageInfo.flags); } inline bool is_match_for_package_properties( @@ -333,7 +332,7 @@ STDAPI GetPackageFilePathInPackageGraph( } // This package is included in our search. Check for the file - auto path{ appmodel::get_package_file(packageFullName, filename, options) }; + auto path{ appmodel::get_package_file(packageFullName, filename, effectiveOptions) }; if (!path.empty()) { auto absoluteFilename{ wil::make_process_heap_string(path.c_str()) }; diff --git a/test/Package/API/PackageTests.vcxproj b/test/Package/API/PackageTests.vcxproj index eff4a2b62a..5d8b590aa1 100644 --- a/test/Package/API/PackageTests.vcxproj +++ b/test/Package/API/PackageTests.vcxproj @@ -89,6 +89,7 @@ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) + api-ms-win-appmodel-runtime-l1-1-5.dll;%(DelayLoadDLLs) @@ -111,11 +112,16 @@ Create - - + + + + + + + diff --git a/test/Package/API/PackageTests.vcxproj.filters b/test/Package/API/PackageTests.vcxproj.filters index 6b38491398..930d5a96a5 100644 --- a/test/Package/API/PackageTests.vcxproj.filters +++ b/test/Package/API/PackageTests.vcxproj.filters @@ -21,10 +21,22 @@ Source Files - + Source Files - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + Source Files @@ -32,6 +44,9 @@ Header Files + + Header Files + Header Files diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp index 6cbe36952b..ca3bf27464 100644 --- a/test/Package/API/PackageTests_CPP.cpp +++ b/test/Package/API/PackageTests_CPP.cpp @@ -57,17 +57,6 @@ namespace Test::Package::Tests return true; } - std::filesystem::path ToAbsoluteFilename( - PCWSTR packageFullName, - PCWSTR filename, - PackagePathType packageType) - { - const auto path{ ::AppModel::Package::GetPath(packageFullName, packageType) }; - std::filesystem::path absoluteFilename{ path }; - absoluteFilename /= filename; - return absoluteFilename; - } - TEST_METHOD(GetPackageFilePath_InvalidParameter) { PCWSTR packageFullName{ Framework_PackageFullName }; @@ -101,7 +90,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } @@ -115,7 +104,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } @@ -129,35 +118,35 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } TEST_METHOD(GetPackageFilePath_MachineExternalPath) { PCWSTR packageFullName{ MachineExternal_PackageFullName }; - PCWSTR fileName{ L"msix\\AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } TEST_METHOD(GetPackageFilePath_UserExternalPath) { PCWSTR packageFullName{ UserExternal_PackageFullName }; - PCWSTR fileName{ L"msix\\AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchUserExternalPath }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ToAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); } diff --git a/test/Package/API/PackageTests_PackageGraph_Base.h b/test/Package/API/PackageTests_PackageGraph_Base.h new file mode 100644 index 0000000000..ad5bba9375 --- /dev/null +++ b/test/Package/API/PackageTests_PackageGraph_Base.h @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +namespace Test::Package::Tests +{ + constexpr auto Main_PackageFamilyName{ ::TP::WindowsAppRuntimeMain::c_PackageFamilyName }; + constexpr auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; + constexpr auto Framework_PackageFamilyName{ ::TP::WindowsAppRuntimeFramework::c_PackageFamilyName }; + constexpr auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + constexpr auto Mutable_PackageFamilyName{ ::TP::Mutable::c_packageFamilyName }; + constexpr auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; + constexpr auto UserExternal_PackageFamilyName{ ::TP::UserExternal::c_packageFamilyName }; + constexpr auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName }; + constexpr auto MachineExternal_PackageFamilyName{ ::TP::MachineExternal::c_packageFamilyName }; + constexpr auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName }; + + class PackageTests_PackageGraph_Base + { + protected: + bool ClassSetup() + { + if (!::WindowsVersion::IsWindows11_24H2OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); + return true; + } + + ::TB::Setup(); + + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + RemovePackage_Mutable(); + + AddPackage_Mutable(); + AddPackage_UserExternal(); + StagePackage_MachineExternal(); + AddPackage_MachineExternal(); + + return true; + } + + bool ClassCleanup() + { + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + RemovePackage_Mutable(); + + ::TB::Cleanup(); + + return true; + } + + PACKAGEDEPENDENCY_CONTEXT AddDynamicDependency( + PCWSTR packageFamilyName) + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddDynamicDependency(): %ls", packageFamilyName)); + + const PACKAGE_VERSION minVersion{}; + const auto architectures{ PackageDependencyProcessorArchitectures_None }; + const auto lifetimeKind{ PackageDependencyLifetimeKind_Process }; + const auto tryCreateOptions{ CreatePackageDependencyOptions_None }; + wil::unique_process_heap_string packageDependencyId; + VERIFY_SUCCEEDED(::TryCreatePackageDependency(nullptr, packageFamilyName, minVersion, architectures, lifetimeKind, nullptr, tryCreateOptions, wil::out_param(packageDependencyId))); + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageDependencyId: %ls", packageDependencyId.get())); + + PACKAGEDEPENDENCY_CONTEXT packageDependencyContext{}; + const std::int32_t rank{ -1000 }; + const auto addOptions{ AddPackageDependencyOptions_None }; + wil::unique_process_heap_string packageFullName; + VERIFY_SUCCEEDED(::AddPackageDependency(packageDependencyId.get(), rank, addOptions, &packageDependencyContext, wil::out_param(packageFullName))); + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageDependencyContext: %p", packageDependencyId.get())); + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageFullName: %ls", packageFullName.get())); + + VERIFY_SUCCEEDED(::DeletePackageDependency(packageDependencyId.get())); + + return packageDependencyContext; + } + + PACKAGEDEPENDENCY_CONTEXT AddDynamicDependency( + const std::wstring& packageFamilyName) + { + return AddDynamicDependency(packageFamilyName.c_str()); + } + + PACKAGEDEPENDENCY_CONTEXT AddDynamicDependency( + const winrt::hstring& packageFamilyName) + { + return AddDynamicDependency(packageFamilyName.c_str()); + } + }; +} diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp new file mode 100644 index 0000000000..5b3ad60ee5 --- /dev/null +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp @@ -0,0 +1,194 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include + +#include + +#include "PackageTests_PackageGraph_Base.h" + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +namespace Test::Package::Tests +{ + class PackageTests_PackageGraph_Packaged_CPP : PackageTests_PackageGraph_Base + { + public: + BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_CPP) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"UAP") + TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows11_24H2OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); + return true; + } + + return PackageTests_PackageGraph_Base::ClassSetup(); + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + return PackageTests_PackageGraph_Base::ClassCleanup(); + } + + TEST_METHOD(GetFilePath) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_None }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_InstallPath) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_MutablePath) + { + PCWSTR packageFullName{ Mutable_PackageFullName }; + PCWSTR packageFamilyName{ Mutable_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchMutablePath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_MachineExternalPath) + { + PCWSTR packageFullName{ MachineExternal_PackageFullName }; + PCWSTR packageFamilyName{ MachineExternal_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"Shadow.cat" }; + const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_UserExternalPath) + { + PCWSTR packageFullName{ UserExternal_PackageFullName }; + PCWSTR packageFamilyName{ UserExternal_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"Shadow.cat" }; + const auto options{ GetPackageFilePathOptions_SearchUserExternalPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) + { + const auto packageFullName{ ::AppModel::Identity::GetCurrentPackageFullName() }; + const auto packageFamilyName{ ::AppModel::Identity::GetCurrentPackageFamilyName() }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) + { + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchMainPackages }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetFilePath_Filter_Static_NoMatch) + { + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchStaticDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) + { + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchDynamicDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetFilePath_Filter_Static) + { + //TODO + } + + TEST_METHOD(GetFilePath_Filter_Dynamic) + { + //TODO + } + }; +} diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp new file mode 100644 index 0000000000..5991558416 --- /dev/null +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp @@ -0,0 +1,213 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include + +#include "PackageTests_PackageGraph_Base.h" + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +static const winrt::hstring null_hstring; + +namespace Test::Package::Tests +{ + class PackageTests_PackageGraph_Packaged_WinRT : PackageTests_PackageGraph_Base + { + public: + BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_WinRT) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"UAP") + TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows11_24H2OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); + return true; + } + + return PackageTests_PackageGraph_Base::ClassSetup(); + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + return PackageTests_PackageGraph_Base::ClassCleanup(); + } + + TEST_METHOD(GetFilePath_InvalidParameter) + { + try + { + winrt::hstring noFileName; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(noFileName); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + + try + { + winrt::hstring noFileName; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(noFileName, options); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + } + + TEST_METHOD(GetFilePath) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_InstallPath) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_MutablePath) + { + winrt::hstring packageFullName{ Mutable_PackageFullName }; + winrt::hstring packageFamilyName{ Mutable_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_MachineExternalPath) + { + winrt::hstring packageFullName{ MachineExternal_PackageFullName }; + winrt::hstring packageFamilyName{ MachineExternal_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_UserExternalPath) + { + winrt::hstring packageFullName{ UserExternal_PackageFullName }; + winrt::hstring packageFamilyName{ UserExternal_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) + { + winrt::hstring packageFullName{ Main_PackageFullName }; + winrt::hstring packageFamilyName{ Main_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Static_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchStaticDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Static) + { + //TODO + } + + TEST_METHOD(GetFilePath_Filter_Dynamic) + { + //TODO + } + }; +} diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp new file mode 100644 index 0000000000..da67ee3f54 --- /dev/null +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp @@ -0,0 +1,197 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include + +#include + +#include "PackageTests_PackageGraph_Base.h" + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +namespace Test::Package::Tests +{ + class PackageTests_PackageGraph_Unpackaged_CPP : PackageTests_PackageGraph_Base + { + public: + BEGIN_TEST_CLASS(PackageTests_PackageGraph_Unpackaged_CPP) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows11_24H2OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); + return true; + } + + return PackageTests_PackageGraph_Base::ClassSetup(); + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + return PackageTests_PackageGraph_Base::ClassCleanup(); + } + + TEST_METHOD(GetFilePath_InvalidParameter) + { + PCWSTR noFileName{}; + wil::unique_process_heap_ptr absoluteFilename; + const auto options{ GetPackageFilePathOptions_None }; + VERIFY_ARE_EQUAL(E_INVALIDARG, ::GetPackageFilePathInPackageGraph(noFileName, options, wil::out_param(absoluteFilename))); + } + + TEST_METHOD(GetFilePath) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_None }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_InstallPath) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_MutablePath) + { + PCWSTR packageFullName{ Mutable_PackageFullName }; + PCWSTR packageFamilyName{ Mutable_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchMutablePath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_MachineExternalPath) + { + PCWSTR packageFullName{ MachineExternal_PackageFullName }; + PCWSTR packageFamilyName{ MachineExternal_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"Shadow.cat" }; + const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_UserExternalPath) + { + PCWSTR packageFullName{ UserExternal_PackageFullName }; + PCWSTR packageFamilyName{ UserExternal_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"Shadow.cat" }; + const auto options{ GetPackageFilePathOptions_SearchUserExternalPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) + { + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) + { + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchMainPackages }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetFilePath_Filter_Static_NoMatch) + { + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchStaticDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) + { + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchDynamicDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetFilePath_Filter_Static) + { + //TODO + } + + TEST_METHOD(GetFilePath_Filter_Dynamic) + { + //TODO + } + }; +} diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp new file mode 100644 index 0000000000..c0b27ea952 --- /dev/null +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp @@ -0,0 +1,212 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include + +#include "PackageTests_PackageGraph_Base.h" + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +static const winrt::hstring null_hstring; + +namespace Test::Package::Tests +{ + class PackageTests_PackageGraph_Unpackaged_WinRT : PackageTests_PackageGraph_Base + { + public: + BEGIN_TEST_CLASS(PackageTests_PackageGraph_Unpackaged_WinRT) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows11_24H2OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); + return true; + } + + return PackageTests_PackageGraph_Base::ClassSetup(); + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + return PackageTests_PackageGraph_Base::ClassCleanup(); + } + + TEST_METHOD(GetFilePath_InvalidParameter) + { + try + { + winrt::hstring noFileName; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(noFileName); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + + try + { + winrt::hstring noFileName; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(noFileName, options); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + } + + TEST_METHOD(GetFilePath) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_InstallPath) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_MutablePath) + { + winrt::hstring packageFullName{ Mutable_PackageFullName }; + winrt::hstring packageFamilyName{ Mutable_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_MachineExternalPath) + { + winrt::hstring packageFullName{ MachineExternal_PackageFullName }; + winrt::hstring packageFamilyName{ MachineExternal_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_UserExternalPath) + { + winrt::hstring packageFullName{ UserExternal_PackageFullName }; + winrt::hstring packageFamilyName{ UserExternal_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) + { + winrt::hstring packageFullName{ Main_PackageFullName }; + winrt::hstring packageFamilyName{ Main_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Static_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchStaticDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Static) + { + //TODO + } + + TEST_METHOD(GetFilePath_Filter_Dynamic) + { + //TODO + } + }; +} diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp new file mode 100644 index 0000000000..514d392a3c --- /dev/null +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -0,0 +1,209 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +namespace Test::Package::Tests +{ + const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; + const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; + const auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName }; + const auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName }; + + class PackageTests_Package_CPP + { + public: + BEGIN_TEST_CLASS(PackageTests_Package_CPP) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + ::TB::Setup(); + + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + RemovePackage_Mutable(); + + AddPackage_Mutable(); + AddPackage_UserExternal(); + StagePackage_MachineExternal(); + AddPackage_MachineExternal(); + + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + ::TB::Cleanup(); + + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + RemovePackage_Mutable(); + + return true; + } + + TEST_METHOD(GetPackageFilePath_InvalidParameter) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR noFileName{}; + wil::unique_process_heap_ptr absoluteFilename; + const auto options{ GetPackageFilePathOptions_None }; + VERIFY_ARE_EQUAL(E_INVALIDARG, ::GetPackageFilePath(packageFullName, noFileName, options, wil::out_param(absoluteFilename))); + } + + TEST_METHOD(GetPackageFilePath_NullPackageFullName_UnpackagedProcess_NoPackage) + { + PCWSTR noPackageFullName{}; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_None }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), ::GetPackageFilePath(noPackageFullName, fileName, options, wil::out_param(absoluteFilename))); + } + + TEST_METHOD(GetPackageFilePath_NullPackageFullName_PackagedProcess_InstallPath) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_None }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetPackageFilePath_InstallPath) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetPackageFilePath_MutablePath) + { + PCWSTR packageFullName{ Mutable_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchMutablePath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetPackageFilePath_MachineExternalPath) + { + PCWSTR packageFullName{ MachineExternal_PackageFullName }; + PCWSTR fileName{ L"Shadow.cat" }; + const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetPackageFilePath_UserExternalPath) + { + PCWSTR packageFullName{ UserExternal_PackageFullName }; + PCWSTR fileName{ L"Shadow.cat" }; + const auto options{ GetPackageFilePathOptions_SearchUserExternalPath }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + } + + TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch) + { + PCWSTR packageFullName{ Main_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetPackageFilePath_FilterPackageType_Framework_NoMatch) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchMainPackages }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + +#if 0 + TEST_METHOD(GetPackageFilePath_Filter_Static_NoMatch) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchStaticDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetPackageFilePath_Filter_Dynamic_NoMatch) + { + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchDynamicDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + VERIFY_IS_NULL(absoluteFilename); + } + + TEST_METHOD(GetPackageFilePath_Filter_Static) + { + //TODO + } + + TEST_METHOD(GetPackageFilePath_Filter_Dynamic) + { + //TODO + } +#endif + }; +} diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp new file mode 100644 index 0000000000..f4912c6417 --- /dev/null +++ b/test/Package/API/PackageTests_Package_WinRT.cpp @@ -0,0 +1,237 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TD = ::Test::Diagnostics; + +static const winrt::hstring null_hstring; + +namespace Test::Package::Tests +{ + const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; + const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; + const auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName }; + const auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName }; + + class PackageTests_Package_WinRT + { + public: + BEGIN_TEST_CLASS(PackageTests_Package_WinRT) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + ::TB::Setup(); + + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + RemovePackage_Mutable(); + + AddPackage_Mutable(); + AddPackage_UserExternal(); + StagePackage_MachineExternal(); + AddPackage_MachineExternal(); + + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + ::TB::Cleanup(); + + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + RemovePackage_Mutable(); + + return true; + } + + TEST_METHOD(GetFilePath_InvalidParameter) + { + try + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring noFileName; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noFileName, packageFullName); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + + try + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring noFileName; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noFileName, packageFullName, options); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + } + + TEST_METHOD(GetFilePath_NullPackageFullName_UnpackagedProcess_NoPackage) + { + try + { + winrt::hstring noPackageFullName; + winrt::hstring fileName{ L"AppxManifest.xml" }; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, noPackageFullName); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + + try + { + winrt::hstring noPackageFullName; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; + std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, noPackageFullName, options); + VERIFY_FAIL(L"Success is not expected"); + } + catch (winrt::hresult_error& e) + { + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); + } + } + + TEST_METHOD(GetFilePath_NullPackageFullName_PackagedProcess_InstallPath) + { + //TODO + } + + TEST_METHOD(GetFilePath) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_InstallPath) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_MutablePath) + { + winrt::hstring packageFullName{ Mutable_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_MachineExternalPath) + { + winrt::hstring packageFullName{ MachineExternal_PackageFullName }; + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_UserExternalPath) + { + winrt::hstring packageFullName{ UserExternal_PackageFullName }; + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) + { + winrt::hstring packageFullName{ Main_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + +#if 0 + TEST_METHOD(GetFilePath_Filter_Static_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchStaticDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) + { + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + VERIFY_IS_TRUE(absoluteFilename.empty()); + } + + TEST_METHOD(GetFilePath_Filter_Static) + { + //TODO + } + + TEST_METHOD(GetFilePath_Filter_Dynamic) + { + //TODO + } +#endif + }; +} diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index 69661af6a8..513415a5c5 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -118,7 +118,11 @@ namespace Test::Package::Tests winrt::hstring packageFullName{ Framework_PackageFullName }; winrt::hstring fileName{ L"AppxManifest.xml" }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) }; - //TODO + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); } TEST_METHOD(GetFilePath_InstallPath) @@ -127,22 +131,50 @@ namespace Test::Package::Tests winrt::hstring fileName{ L"AppxManifest.xml" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - //TODO + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); } TEST_METHOD(GetFilePath_MutablePath) { - //TODO + winrt::hstring packageFullName{ Mutable_PackageFullName }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); } TEST_METHOD(GetFilePath_MachineExternalPath) { - //TODO + winrt::hstring packageFullName{ MachineExternal_PackageFullName }; + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); } TEST_METHOD(GetFilePath_UserExternalPath) { - //TODO + winrt::hstring packageFullName{ UserExternal_PackageFullName }; + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/pch.h b/test/Package/API/pch.h index c02f871a4d..fcd644fd66 100644 --- a/test/Package/API/pch.h +++ b/test/Package/API/pch.h @@ -9,6 +9,8 @@ #include #include +#include + #include #include @@ -25,6 +27,7 @@ #include #include +#include #include #include diff --git a/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj b/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj index ca587985ff..dcfd668959 100644 --- a/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj +++ b/test/Package/data/MachineExternal/Package.Test.MachineExternal.msix.vcxproj @@ -117,4 +117,7 @@ + + + diff --git a/test/Package/data/MachineExternal/Shadow.cat b/test/Package/data/MachineExternal/Shadow.cat new file mode 100644 index 0000000000..defd12bba0 --- /dev/null +++ b/test/Package/data/MachineExternal/Shadow.cat @@ -0,0 +1 @@ +Catch me if you can... diff --git a/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj b/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj index 37699d7afb..ee56886400 100644 --- a/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj +++ b/test/Package/data/UserExternal/Package.Test.UserExternal.msix.vcxproj @@ -117,4 +117,7 @@ + + + diff --git a/test/Package/data/UserExternal/Shadow.cat b/test/Package/data/UserExternal/Shadow.cat new file mode 100644 index 0000000000..defd12bba0 --- /dev/null +++ b/test/Package/data/UserExternal/Shadow.cat @@ -0,0 +1 @@ +Catch me if you can... From 16b7acfa3d83f626de4c83a704ea2e4aa395bedd Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 1 Feb 2026 22:34:23 -0800 Subject: [PATCH 14/33] Added missing test type --- .../data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml index 05c9770421..6823ceb41a 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -70,6 +70,7 @@ Microsoft.WindowsAppRuntime.dll + From e3004bb3d057724512960e222b9465dbb52b56cd Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 8 Feb 2026 16:23:49 -0800 Subject: [PATCH 15/33] Checkpoint --- .../API/PackageTests_PackageGraph_Base.h | 59 ++++++++++++++++--- ...PackageTests_PackageGraph_Packaged_CPP.cpp | 41 +++++++------ ...ckageTests_PackageGraph_Packaged_WinRT.cpp | 6 +- ...ckageTests_PackageGraph_Unpackaged_CPP.cpp | 38 ++++++------ ...ageTests_PackageGraph_Unpackaged_WinRT.cpp | 4 +- .../data/MachineExternal/appxmanifest.xml | 4 +- test/Package/data/Mutable/appxmanifest.xml | 4 +- .../data/UserExternal/appxmanifest.xml | 4 +- 8 files changed, 110 insertions(+), 50 deletions(-) diff --git a/test/Package/API/PackageTests_PackageGraph_Base.h b/test/Package/API/PackageTests_PackageGraph_Base.h index ad5bba9375..cfd10d940b 100644 --- a/test/Package/API/PackageTests_PackageGraph_Base.h +++ b/test/Package/API/PackageTests_PackageGraph_Base.h @@ -24,7 +24,30 @@ namespace Test::Package::Tests class PackageTests_PackageGraph_Base { protected: - bool ClassSetup() + bool PackagedClassSetup() + { + return ClassSetup(true); + } + + bool PackagedClassCleanup() + { + return ClassCleanup(false); + } + + bool UnpackagedClassSetup() + { + return ClassSetup(true); + } + + bool UnpackagedClassCleanup() + { + return ClassCleanup(false); + } + + private: + wil::unique_package_dependency_context m_windowsAppRuntimeFramework_packageDependencyContext; + + bool ClassSetup(const bool callerIsPackaged) { if (!::WindowsVersion::IsWindows11_24H2OrGreater()) { @@ -32,7 +55,18 @@ namespace Test::Package::Tests return true; } - ::TB::Setup(); + //***SEEME***if (callerIsPackaged) + //***SEEME***{ + ::TP::RemovePackage_WindowsAppRuntimeFramework(); + ::TP::AddPackage_WindowsAppRuntimeFramework(); + + constexpr std::int32_t frameworkRank{ 1000 }; + m_windowsAppRuntimeFramework_packageDependencyContext.reset(AddDynamicDependency(Framework_PackageFamilyName, frameworkRank)); + //***SEEME***} + //***SEEME***else + //***SEEME***{ + //***SEEME*** ::TB::Setup(); + //***SEEME***} RemovePackage_MachineExternal(); RemovePackage_UserExternal(); @@ -41,37 +75,46 @@ namespace Test::Package::Tests AddPackage_Mutable(); AddPackage_UserExternal(); StagePackage_MachineExternal(); - AddPackage_MachineExternal(); + RegisterPackage_MachineExternal(); return true; } - bool ClassCleanup() + bool ClassCleanup(const bool callerIsPackaged = true) { RemovePackage_MachineExternal(); RemovePackage_UserExternal(); RemovePackage_Mutable(); - ::TB::Cleanup(); + if (callerIsPackaged) + { + m_windowsAppRuntimeFramework_packageDependencyContext.reset(); + ::TP::RemovePackage_WindowsAppRuntimeFramework(); + } + else + { + ::TB::Cleanup(); + } return true; } + public: PACKAGEDEPENDENCY_CONTEXT AddDynamicDependency( - PCWSTR packageFamilyName) + PCWSTR packageFamilyName, + const std::int32_t rank = -1000) { WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddDynamicDependency(): %ls", packageFamilyName)); const PACKAGE_VERSION minVersion{}; const auto architectures{ PackageDependencyProcessorArchitectures_None }; - const auto lifetimeKind{ PackageDependencyLifetimeKind_Process }; + const auto lifetimeKind{ PackageDependencyLifetimeKind_Process}; const auto tryCreateOptions{ CreatePackageDependencyOptions_None }; wil::unique_process_heap_string packageDependencyId; VERIFY_SUCCEEDED(::TryCreatePackageDependency(nullptr, packageFamilyName, minVersion, architectures, lifetimeKind, nullptr, tryCreateOptions, wil::out_param(packageDependencyId))); WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageDependencyId: %ls", packageDependencyId.get())); PACKAGEDEPENDENCY_CONTEXT packageDependencyContext{}; - const std::int32_t rank{ -1000 }; const auto addOptions{ AddPackageDependencyOptions_None }; wil::unique_process_heap_string packageFullName; VERIFY_SUCCEEDED(::AddPackageDependency(packageDependencyId.get(), rank, addOptions, &packageDependencyContext, wil::out_param(packageFullName))); diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp index 5b3ad60ee5..3610a0aa66 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp @@ -22,30 +22,35 @@ namespace Test::Package::Tests BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_CPP) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") TEST_CLASS_PROPERTY(L"RunAs", L"UAP") - TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust") +//***SEEME*** TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust") +//***SEEME*** TEST_METHOD_PROPERTY(L"UAP:RuntimeBehavior", L"Win32App") + TEST_METHOD_PROPERTY(L"UAP:RuntimeBehavior", L"PackagedClassicApp") + TEST_METHOD_PROPERTY(L"UAP:TrustLevel", L"MediumIL") END_TEST_CLASS() TEST_CLASS_SETUP(ClassSetup) { + // Windows App SDK's Dynamic Dependency API doesn't support packaged processes + // Ue the OS Dynamic Dependency API (if available) if (!::WindowsVersion::IsWindows11_24H2OrGreater()) { WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); return true; } - return PackageTests_PackageGraph_Base::ClassSetup(); + return PackageTests_PackageGraph_Base::PackagedClassSetup(); } TEST_CLASS_CLEANUP(ClassCleanup) { - return PackageTests_PackageGraph_Base::ClassCleanup(); + return PackageTests_PackageGraph_Base::PackagedClassCleanup(); } TEST_METHOD(GetFilePath) { PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_None }; @@ -55,14 +60,14 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_InstallPath) { PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath }; @@ -72,7 +77,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_MutablePath) @@ -89,7 +94,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_MachineExternalPath) @@ -106,7 +111,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_UserExternalPath) @@ -123,7 +128,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) @@ -142,8 +147,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) { - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | @@ -155,8 +160,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Static_NoMatch) { - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | @@ -169,8 +174,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) { - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp index 5991558416..e76e09e06c 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp @@ -27,18 +27,20 @@ namespace Test::Package::Tests TEST_CLASS_SETUP(ClassSetup) { + // Windows App SDK's Dynamic Dependency API doesn't support packaged processes + // Ue the OS Dynamic Dependency API (if available) if (!::WindowsVersion::IsWindows11_24H2OrGreater()) { WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); return true; } - return PackageTests_PackageGraph_Base::ClassSetup(); + return PackageTests_PackageGraph_Base::PackagedClassSetup(); } TEST_CLASS_CLEANUP(ClassCleanup) { - return PackageTests_PackageGraph_Base::ClassCleanup(); + return PackageTests_PackageGraph_Base::PackagedClassCleanup(); } TEST_METHOD(GetFilePath_InvalidParameter) diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp index da67ee3f54..689fc82dd3 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp @@ -22,6 +22,7 @@ namespace Test::Package::Tests BEGIN_TEST_CLASS(PackageTests_PackageGraph_Unpackaged_CPP) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") + TEST_CLASS_PROPERTY(L"RunFixtureAs", L"RestrictedUser") END_TEST_CLASS() TEST_CLASS_SETUP(ClassSetup) @@ -32,16 +33,19 @@ namespace Test::Package::Tests return true; } - return PackageTests_PackageGraph_Base::ClassSetup(); + return PackageTests_PackageGraph_Base::UnpackagedClassSetup(); } TEST_CLASS_CLEANUP(ClassCleanup) { - return PackageTests_PackageGraph_Base::ClassCleanup(); + return PackageTests_PackageGraph_Base::UnpackagedClassCleanup(); } TEST_METHOD(GetFilePath_InvalidParameter) { + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR noFileName{}; wil::unique_process_heap_ptr absoluteFilename; const auto options{ GetPackageFilePathOptions_None }; @@ -51,8 +55,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath) { PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_None }; @@ -62,14 +66,14 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_InstallPath) { PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath }; @@ -79,7 +83,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_MutablePath) @@ -96,7 +100,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_MachineExternalPath) @@ -113,7 +117,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_UserExternalPath) @@ -130,7 +134,7 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) @@ -145,8 +149,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) { - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | @@ -158,8 +162,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Static_NoMatch) { - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | @@ -172,8 +176,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) { - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp index c0b27ea952..a24e0564b5 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp @@ -32,12 +32,12 @@ namespace Test::Package::Tests return true; } - return PackageTests_PackageGraph_Base::ClassSetup(); + return PackageTests_PackageGraph_Base::UnpackagedClassSetup(); } TEST_CLASS_CLEANUP(ClassCleanup) { - return PackageTests_PackageGraph_Base::ClassCleanup(); + return PackageTests_PackageGraph_Base::UnpackagedClassCleanup(); } TEST_METHOD(GetFilePath_InvalidParameter) diff --git a/test/Package/data/MachineExternal/appxmanifest.xml b/test/Package/data/MachineExternal/appxmanifest.xml index 27858672e3..d07bd05176 100644 --- a/test/Package/data/MachineExternal/appxmanifest.xml +++ b/test/Package/data/MachineExternal/appxmanifest.xml @@ -4,7 +4,8 @@ xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10" - IgnorableNamespaces="uap uap10"> + xmlns:uap15="http://schemas.microsoft.com/appx/manifest/uap/windows10/15" + IgnorableNamespaces="uap uap10 uap15"> Test.Package.MachineExternal Microsoft Corporation logo.png + true true diff --git a/test/Package/data/Mutable/appxmanifest.xml b/test/Package/data/Mutable/appxmanifest.xml index 9a5b4b8f69..b1b209ff7b 100644 --- a/test/Package/data/Mutable/appxmanifest.xml +++ b/test/Package/data/Mutable/appxmanifest.xml @@ -3,9 +3,10 @@ + IgnorableNamespaces="uap uap15 desktop6 rescap"> Test.Package.Mutable Microsoft Corporation logo.png + true diff --git a/test/Package/data/UserExternal/appxmanifest.xml b/test/Package/data/UserExternal/appxmanifest.xml index 006cb58f5f..d88a374f93 100644 --- a/test/Package/data/UserExternal/appxmanifest.xml +++ b/test/Package/data/UserExternal/appxmanifest.xml @@ -4,7 +4,8 @@ xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10" - IgnorableNamespaces="uap uap10"> + xmlns:uap15="http://schemas.microsoft.com/appx/manifest/uap/windows10/15" + IgnorableNamespaces="uap uap10 uap15"> Test.Package.UserExternal Microsoft Corporation logo.png + true true From 9db496585ef77a64df0f29cbbaf067fd0b95695f Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 8 Feb 2026 21:35:42 -0800 Subject: [PATCH 16/33] Fixes --- WindowsAppRuntime.sln | 49 +++++++ dev/Common/AppModel.PackageGraph.h | 2 +- test/Package/API/PackageTests.Packages.h | 130 ++++++++++++++++++ test/Package/API/PackageTests_CPP.cpp | 41 +----- .../API/PackageTests_PackageGraph_Base.h | 45 +++--- ...PackageTests_PackageGraph_Packaged_CPP.cpp | 45 +++--- ...ckageTests_PackageGraph_Packaged_WinRT.cpp | 20 ++- ...ckageTests_PackageGraph_Unpackaged_CPP.cpp | 50 ++++--- ...ageTests_PackageGraph_Unpackaged_WinRT.cpp | 26 ++-- test/Package/API/PackageTests_Package_CPP.cpp | 36 ----- .../API/PackageTests_Package_WinRT.cpp | 34 ----- test/Package/API/PackageTests_WinRT.cpp | 34 ----- .../Package.Framework.vcxproj.filters | 17 +++ .../Package.Test.Framework.msix.vcxproj | 121 ++++++++++++++++ ...ackage.Test.Framework.msix.vcxproj.filters | 17 +++ test/Package/data/Framework/Shadow.cat | 1 + test/Package/data/Framework/appxmanifest.xml | 30 ++++ test/Package/data/Framework/logo.png | Bin 0 -> 5632 bytes test/Package/data/Framework/packages.config | 6 + .../data/MachineExternal/appxmanifest.xml | 2 +- .../data/Main/Package.Main.vcxproj.filters | 17 +++ .../data/Main/Package.Test.Main.msix.vcxproj | 121 ++++++++++++++++ .../Package.Test.Main.msix.vcxproj.filters | 17 +++ test/Package/data/Main/Shadow.cat | 1 + test/Package/data/Main/appxmanifest.xml | 31 +++++ test/Package/data/Main/logo.png | Bin 0 -> 5632 bytes test/Package/data/Main/packages.config | 6 + test/Package/data/Mutable/appxmanifest.xml | 2 +- .../data/UserExternal/appxmanifest.xml | 2 +- test/inc/WindowsAppRuntime.Test.Package.h | 10 +- 30 files changed, 687 insertions(+), 226 deletions(-) create mode 100644 test/Package/data/Framework/Package.Framework.vcxproj.filters create mode 100644 test/Package/data/Framework/Package.Test.Framework.msix.vcxproj create mode 100644 test/Package/data/Framework/Package.Test.Framework.msix.vcxproj.filters create mode 100644 test/Package/data/Framework/Shadow.cat create mode 100644 test/Package/data/Framework/appxmanifest.xml create mode 100644 test/Package/data/Framework/logo.png create mode 100644 test/Package/data/Framework/packages.config create mode 100644 test/Package/data/Main/Package.Main.vcxproj.filters create mode 100644 test/Package/data/Main/Package.Test.Main.msix.vcxproj create mode 100644 test/Package/data/Main/Package.Test.Main.msix.vcxproj.filters create mode 100644 test/Package/data/Main/Shadow.cat create mode 100644 test/Package/data/Main/appxmanifest.xml create mode 100644 test/Package/data/Main/logo.png create mode 100644 test/Package/data/Main/packages.config diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index d3592a9f64..49d0218225 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -758,7 +758,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API", "API", "{BF763B12-77A EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageTests", "test\Package\API\PackageTests.vcxproj", "{F8A40421-CEDE-4BA2-8DF5-D00C33DF16B7}" ProjectSection(ProjectDependencies) = postProject + {28CEF2AF-174B-4EE9-B71E-D596C5E1E563} = {28CEF2AF-174B-4EE9-B71E-D596C5E1E563} + {3347E246-6BF5-469F-9C91-7D6E33B66786} = {3347E246-6BF5-469F-9C91-7D6E33B66786} + {469EE821-0FB5-4B9A-82D9-91292B0593D0} = {469EE821-0FB5-4B9A-82D9-91292B0593D0} + {472B8D93-9200-48B7-BFB6-9D9B85AA4025} = {472B8D93-9200-48B7-BFB6-9D9B85AA4025} {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1} + {F41B5211-4E18-4625-96A3-0130001B57C8} = {F41B5211-4E18-4625-96A3-0130001B57C8} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Windows.ApplicationModel.Resources", "dev\MRTCore\mrt\Microsoft.Windows.ApplicationModel.Resources\src\Microsoft.Windows.ApplicationModel.Resources.vcxproj", "{9B3B03BC-1BC0-43EA-B3FF-D5214F3CF5CF}" @@ -791,6 +796,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.MachineExterna EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.UserExternal.msix", "test\Package\data\UserExternal\Package.Test.UserExternal.msix.vcxproj", "{28CEF2AF-174B-4EE9-B71E-D596C5E1E563}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Framework", "Framework", "{2F020A4F-E3ED-445F-9D17-4149F198006A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.Framework.msix", "test\Package\data\Framework\Package.Test.Framework.msix.vcxproj", "{F41B5211-4E18-4625-96A3-0130001B57C8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{537704A1-B275-436E-A9AC-11A8A9398F27}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Package.Test.Main.msix", "test\Package\data\Main\Package.Test.Main.msix.vcxproj", "{472B8D93-9200-48B7-BFB6-9D9B85AA4025}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2765,6 +2778,38 @@ Global {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x64.Build.0 = Release|x64 {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x86.ActiveCfg = Release|Win32 {28CEF2AF-174B-4EE9-B71E-D596C5E1E563}.Release|x86.Build.0 = Release|Win32 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|Any CPU.ActiveCfg = Debug|x64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|Any CPU.Build.0 = Debug|x64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|ARM64.Build.0 = Debug|ARM64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|x64.ActiveCfg = Debug|x64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|x64.Build.0 = Debug|x64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|x86.ActiveCfg = Debug|Win32 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Debug|x86.Build.0 = Debug|Win32 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|Any CPU.ActiveCfg = Release|x64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|Any CPU.Build.0 = Release|x64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|ARM64.ActiveCfg = Release|ARM64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|ARM64.Build.0 = Release|ARM64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|x64.ActiveCfg = Release|x64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|x64.Build.0 = Release|x64 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|x86.ActiveCfg = Release|Win32 + {F41B5211-4E18-4625-96A3-0130001B57C8}.Release|x86.Build.0 = Release|Win32 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|Any CPU.ActiveCfg = Debug|x64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|Any CPU.Build.0 = Debug|x64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|ARM64.Build.0 = Debug|ARM64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|x64.ActiveCfg = Debug|x64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|x64.Build.0 = Debug|x64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|x86.ActiveCfg = Debug|Win32 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Debug|x86.Build.0 = Debug|Win32 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|Any CPU.ActiveCfg = Release|x64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|Any CPU.Build.0 = Release|x64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|ARM64.ActiveCfg = Release|ARM64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|ARM64.Build.0 = Release|ARM64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|x64.ActiveCfg = Release|x64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|x64.Build.0 = Release|x64 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|x86.ActiveCfg = Release|Win32 + {472B8D93-9200-48B7-BFB6-9D9B85AA4025}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -3005,6 +3050,10 @@ Global {469EE821-0FB5-4B9A-82D9-91292B0593D0} = {39ADE0B0-74E8-478A-9AE1-EFB568985AA5} {3347E246-6BF5-469F-9C91-7D6E33B66786} = {862A4050-B803-493D-89C2-09390141C774} {28CEF2AF-174B-4EE9-B71E-D596C5E1E563} = {70317696-8BDE-4D1E-99DE-5CD722EB86B1} + {2F020A4F-E3ED-445F-9D17-4149F198006A} = {2BF5AE78-D16A-402B-84C1-2164B887D858} + {F41B5211-4E18-4625-96A3-0130001B57C8} = {2F020A4F-E3ED-445F-9D17-4149F198006A} + {537704A1-B275-436E-A9AC-11A8A9398F27} = {2BF5AE78-D16A-402B-84C1-2164B887D858} + {472B8D93-9200-48B7-BFB6-9D9B85AA4025} = {537704A1-B275-436E-A9AC-11A8A9398F27} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/dev/Common/AppModel.PackageGraph.h b/dev/Common/AppModel.PackageGraph.h index 97fcb8cb4a..1770f04beb 100644 --- a/dev/Common/AppModel.PackageGraph.h +++ b/dev/Common/AppModel.PackageGraph.h @@ -21,7 +21,7 @@ inline HRESULT GetCurrentPackageGraph( LONG rc{ ::GetCurrentPackageInfo(flags, &bufferLength, nullptr, &packageInfoCount) }; if ((rc == APPMODEL_ERROR_NO_PACKAGE) || (packageInfoCount == 0)) { - // No packages. We�re done + // No packages. We're done return S_OK; } RETURN_HR_IF(HRESULT_FROM_WIN32(rc), rc != ERROR_INSUFFICIENT_BUFFER); diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h index dce41c79d4..b4f7f5872e 100644 --- a/test/Package/API/PackageTests.Packages.h +++ b/test/Package/API/PackageTests.Packages.h @@ -12,6 +12,18 @@ namespace TP = ::Test::Packages; namespace Test::Packages { +namespace Framework +{ + constexpr PCWSTR c_packageDirName = L"Package.Test.Framework.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.Package.Framework_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName = L"Test.Package.Framework_1.2.3.4_neutral__8wekyb3d8bbwe"; +} +namespace Main +{ + constexpr PCWSTR c_packageDirName = L"Package.Test.Main.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.Package.Main_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName = L"Test.Package.Main_1.2.3.4_neutral__8wekyb3d8bbwe"; +} namespace Mutable { constexpr PCWSTR c_packageDirName = L"Package.Test.Mutable.msix"; @@ -36,6 +48,124 @@ namespace Test::Package::Tests { namespace TP = ::Test::Packages; + inline bool IsPackageRegistered_Framework() + { + return TP::IsPackageRegistered(TP::Framework::c_packageFullName); + } + inline bool IsPackageStaged_Framework() + { + return TP::IsPackageStaged(TP::Framework::c_packageFullName); + } + inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_Framework() + { + return TP::GetPackageStatus(TP::Framework::c_packageFullName); + } + inline void AddPackage_Framework() + { + TP::AddPackageIfNecessary(TP::Framework::c_packageDirName, TP::Framework::c_packageFullName); + } + inline void AddPackageDefer_Framework() + { + TP::AddPackageDeferIfNecessary(TP::Framework::c_packageDirName, TP::Framework::c_packageFullName); + } + inline void StagePackage_Framework() + { + TP::StagePackageIfNecessary(TP::Framework::c_packageDirName, TP::Framework::c_packageFullName); + } + inline void RegisterPackage_Framework() + { + TP::RegisterPackageIfNecessary(TP::Framework::c_packageFullName); + } + inline void RemovePackage_Framework() + { + if (IsPackageRegistered_Framework()) + { + TP::RemovePackage(TP::Framework::c_packageFullName); + } + else if (IsPackageStaged_Framework()) + { + // We can't directly remove a Stage package not registered for current user + // w/o admin privilege but we can add it to make it registered and then remove it. + AddPackage_Framework(); + TP::RemovePackage(TP::Framework::c_packageFullName); + } + } + inline void RemovePackageFamily_Framework() + { + RemovePackage_Framework(); + } + inline bool IsPackageProvisioned_Framework() + { + return TP::IsPackageProvisioned(TP::Framework::c_packageFamilyName); + } + inline void ProvisionPackage_Framework() + { + TP::ProvisionPackage(TP::Framework::c_packageFamilyName); + } + inline void DeprovisionPackage_Framework() + { + TP::DeprovisionPackageIfNecessary(TP::Framework::c_packageFamilyName); + } + + inline bool IsPackageRegistered_Main() + { + return TP::IsPackageRegistered(TP::Main::c_packageFullName); + } + inline bool IsPackageStaged_Main() + { + return TP::IsPackageStaged(TP::Main::c_packageFullName); + } + inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus_Main() + { + return TP::GetPackageStatus(TP::Main::c_packageFullName); + } + inline void AddPackage_Main() + { + TP::AddPackageIfNecessary(TP::Main::c_packageDirName, TP::Main::c_packageFullName); + } + inline void AddPackageDefer_Main() + { + TP::AddPackageDeferIfNecessary(TP::Main::c_packageDirName, TP::Main::c_packageFullName); + } + inline void StagePackage_Main() + { + TP::StagePackageIfNecessary(TP::Main::c_packageDirName, TP::Main::c_packageFullName); + } + inline void RegisterPackage_Main() + { + TP::RegisterPackageIfNecessary(TP::Main::c_packageFullName); + } + inline void RemovePackage_Main() + { + if (IsPackageRegistered_Main()) + { + TP::RemovePackage(TP::Main::c_packageFullName); + } + else if (IsPackageStaged_Main()) + { + // We can't directly remove a Stage package not registered for current user + // w/o admin privilege but we can add it to make it registered and then remove it. + AddPackage_Main(); + TP::RemovePackage(TP::Main::c_packageFullName); + } + } + inline void RemovePackageFamily_Main() + { + RemovePackage_Main(); + } + inline bool IsPackageProvisioned_Main() + { + return TP::IsPackageProvisioned(TP::Main::c_packageFamilyName); + } + inline void ProvisionPackage_Main() + { + TP::ProvisionPackage(TP::Main::c_packageFamilyName); + } + inline void DeprovisionPackage_Main() + { + TP::DeprovisionPackageIfNecessary(TP::Main::c_packageFamilyName); + } + inline bool IsPackageRegistered_Mutable() { return TP::IsPackageRegistered(TP::Mutable::c_packageFullName); diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp index ca3bf27464..f3ba0f2c54 100644 --- a/test/Package/API/PackageTests_CPP.cpp +++ b/test/Package/API/PackageTests_CPP.cpp @@ -17,7 +17,7 @@ namespace TD = ::Test::Diagnostics; namespace Test::Package::Tests { const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; - const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + const auto Framework_PackageFullName{ ::TP::Framework::c_packageFullName }; const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; const auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName }; const auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName }; @@ -37,7 +37,9 @@ namespace Test::Package::Tests RemovePackage_MachineExternal(); RemovePackage_UserExternal(); RemovePackage_Mutable(); + RemovePackage_Framework(); + AddPackage_Framework(); AddPackage_Mutable(); AddPackage_UserExternal(); StagePackage_MachineExternal(); @@ -53,6 +55,7 @@ namespace Test::Package::Tests RemovePackage_MachineExternal(); RemovePackage_UserExternal(); RemovePackage_Mutable(); + RemovePackage_Framework(); return true; } @@ -171,41 +174,5 @@ namespace Test::Package::Tests VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); VERIFY_IS_NULL(absoluteFilename); } - -#if 0 - TEST_METHOD(GetPackageFilePath_Filter_Static_NoMatch) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchStaticDependencies }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetPackageFilePath_Filter_Dynamic_NoMatch) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchDynamicDependencies }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetPackageFilePath_Filter_Static) - { - //TODO - } - - TEST_METHOD(GetPackageFilePath_Filter_Dynamic) - { - //TODO - } -#endif }; } diff --git a/test/Package/API/PackageTests_PackageGraph_Base.h b/test/Package/API/PackageTests_PackageGraph_Base.h index cfd10d940b..f7132dfbba 100644 --- a/test/Package/API/PackageTests_PackageGraph_Base.h +++ b/test/Package/API/PackageTests_PackageGraph_Base.h @@ -10,10 +10,10 @@ namespace TD = ::Test::Diagnostics; namespace Test::Package::Tests { - constexpr auto Main_PackageFamilyName{ ::TP::WindowsAppRuntimeMain::c_PackageFamilyName }; - constexpr auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; - constexpr auto Framework_PackageFamilyName{ ::TP::WindowsAppRuntimeFramework::c_PackageFamilyName }; - constexpr auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; + constexpr auto Framework_PackageFamilyName{ ::TP::Framework::c_packageFamilyName }; + constexpr auto Framework_PackageFullName{ ::TP::Framework::c_packageFullName }; + constexpr auto Main_PackageFamilyName{ ::TP::Main::c_packageFamilyName }; + constexpr auto Main_PackageFullName{ ::TP::Main::c_packageFullName }; constexpr auto Mutable_PackageFamilyName{ ::TP::Mutable::c_packageFamilyName }; constexpr auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; constexpr auto UserExternal_PackageFamilyName{ ::TP::UserExternal::c_packageFamilyName }; @@ -55,46 +55,37 @@ namespace Test::Package::Tests return true; } - //***SEEME***if (callerIsPackaged) - //***SEEME***{ - ::TP::RemovePackage_WindowsAppRuntimeFramework(); - ::TP::AddPackage_WindowsAppRuntimeFramework(); - - constexpr std::int32_t frameworkRank{ 1000 }; - m_windowsAppRuntimeFramework_packageDependencyContext.reset(AddDynamicDependency(Framework_PackageFamilyName, frameworkRank)); - //***SEEME***} - //***SEEME***else - //***SEEME***{ - //***SEEME*** ::TB::Setup(); - //***SEEME***} - RemovePackage_MachineExternal(); RemovePackage_UserExternal(); RemovePackage_Mutable(); + RemovePackage_Main(); + RemovePackage_Framework(); + ::TP::RemovePackage_WindowsAppRuntimeFramework(); + ::TP::AddPackage_WindowsAppRuntimeFramework(); + AddPackage_Framework(); + AddPackage_Main(); AddPackage_Mutable(); AddPackage_UserExternal(); StagePackage_MachineExternal(); RegisterPackage_MachineExternal(); + constexpr std::int32_t frameworkRank{ 1000 }; + m_windowsAppRuntimeFramework_packageDependencyContext.reset(AddDynamicDependency(::TP::WindowsAppRuntimeFramework::c_PackageFamilyName, frameworkRank)); + return true; } bool ClassCleanup(const bool callerIsPackaged = true) { + m_windowsAppRuntimeFramework_packageDependencyContext.reset(); + RemovePackage_MachineExternal(); RemovePackage_UserExternal(); RemovePackage_Mutable(); - - if (callerIsPackaged) - { - m_windowsAppRuntimeFramework_packageDependencyContext.reset(); - ::TP::RemovePackage_WindowsAppRuntimeFramework(); - } - else - { - ::TB::Cleanup(); - } + RemovePackage_Main(); + RemovePackage_Framework(); + ::TP::RemovePackage_WindowsAppRuntimeFramework(); return true; } diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp index 3610a0aa66..953f4ae947 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp @@ -22,8 +22,6 @@ namespace Test::Package::Tests BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_CPP) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") TEST_CLASS_PROPERTY(L"RunAs", L"UAP") -//***SEEME*** TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust") -//***SEEME*** TEST_METHOD_PROPERTY(L"UAP:RuntimeBehavior", L"Win32App") TEST_METHOD_PROPERTY(L"UAP:RuntimeBehavior", L"PackagedClassicApp") TEST_METHOD_PROPERTY(L"UAP:TrustLevel", L"MediumIL") END_TEST_CLASS() @@ -49,8 +47,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath) { PCWSTR packageFullName{ Framework_PackageFullName }; - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_None }; @@ -66,8 +64,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_InstallPath) { PCWSTR packageFullName{ Framework_PackageFullName }; - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath }; @@ -133,11 +131,11 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) { - const auto packageFullName{ ::AppModel::Identity::GetCurrentPackageFullName() }; - const auto packageFamilyName{ ::AppModel::Identity::GetCurrentPackageFamilyName() }; + PCWSTR packageFullName{ Main_PackageFullName }; + PCWSTR packageFamilyName{ Main_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - PCWSTR fileName{ L"AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | GetPackageFilePathOptions_SearchFrameworkPackages }; wil::unique_process_heap_ptr absoluteFilename; @@ -147,8 +145,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) { - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | @@ -160,8 +158,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Static_NoMatch) { - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | @@ -174,10 +172,7 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) { - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - PCWSTR fileName{ L"AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | GetPackageFilePathOptions_SearchFrameworkPackages | GetPackageFilePathOptions_SearchDynamicDependencies }; @@ -193,7 +188,21 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Dynamic) { - //TODO + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"Shadow.cat" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchDynamicDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } }; } diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp index e76e09e06c..53f94e1394 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp @@ -22,7 +22,8 @@ namespace Test::Package::Tests BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_WinRT) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") TEST_CLASS_PROPERTY(L"RunAs", L"UAP") - TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust") + TEST_METHOD_PROPERTY(L"UAP:RuntimeBehavior", L"PackagedClassicApp") + TEST_METHOD_PROPERTY(L"UAP:TrustLevel", L"MediumIL") END_TEST_CLASS() TEST_CLASS_SETUP(ClassSetup) @@ -154,7 +155,7 @@ namespace Test::Package::Tests winrt::hstring packageFamilyName{ Main_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - winrt::hstring fileName{ L"AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; @@ -209,7 +210,20 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Dynamic) { - //TODO + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); } }; } diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp index 689fc82dd3..19a55ecdf0 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp @@ -22,7 +22,6 @@ namespace Test::Package::Tests BEGIN_TEST_CLASS(PackageTests_PackageGraph_Unpackaged_CPP) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") - TEST_CLASS_PROPERTY(L"RunFixtureAs", L"RestrictedUser") END_TEST_CLASS() TEST_CLASS_SETUP(ClassSetup) @@ -43,8 +42,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_InvalidParameter) { - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR noFileName{}; wil::unique_process_heap_ptr absoluteFilename; @@ -55,8 +54,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath) { PCWSTR packageFullName{ Framework_PackageFullName }; - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_None }; @@ -72,8 +71,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_InstallPath) { PCWSTR packageFullName{ Framework_PackageFullName }; - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath }; @@ -139,6 +138,9 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) { + PCWSTR packageFamilyName{ Main_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | GetPackageFilePathOptions_SearchFrameworkPackages }; @@ -149,8 +151,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) { - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | @@ -162,8 +164,8 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Static_NoMatch) { - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | @@ -176,10 +178,7 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) { - //***SEEME***PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - //***SEEME***wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - PCWSTR fileName{ L"AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | GetPackageFilePathOptions_SearchFrameworkPackages | GetPackageFilePathOptions_SearchDynamicDependencies }; @@ -188,14 +187,23 @@ namespace Test::Package::Tests VERIFY_IS_NULL(absoluteFilename); } - TEST_METHOD(GetFilePath_Filter_Static) - { - //TODO - } - TEST_METHOD(GetFilePath_Filter_Dynamic) { - //TODO + PCWSTR packageFullName{ Framework_PackageFullName }; + PCWSTR packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + PCWSTR fileName{ L"Shadow.cat" }; + const auto options{ GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchDynamicDependencies }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NOT_NULL(absoluteFilename); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); } }; } diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp index a24e0564b5..909a9a020a 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp @@ -147,8 +147,7 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) { - winrt::hstring packageFullName{ Main_PackageFullName }; - winrt::hstring packageFamilyName{ Main_PackageFamilyName }; + PCWSTR packageFamilyName{ Main_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; winrt::hstring fileName{ L"AppxManifest.xml" }; @@ -160,7 +159,6 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) { - winrt::hstring packageFullName{ Framework_PackageFullName }; winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; @@ -173,7 +171,6 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Static_NoMatch) { - winrt::hstring packageFullName{ Framework_PackageFullName }; winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; @@ -187,7 +184,6 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) { - winrt::hstring packageFullName{ Framework_PackageFullName }; winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; @@ -199,14 +195,22 @@ namespace Test::Package::Tests VERIFY_IS_TRUE(absoluteFilename.empty()); } - TEST_METHOD(GetFilePath_Filter_Static) - { - //TODO - } - TEST_METHOD(GetFilePath_Filter_Dynamic) { - //TODO + winrt::hstring packageFullName{ Framework_PackageFullName }; + winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; + wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; + + winrt::hstring fileName{ L"Shadow.cat" }; + const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_FALSE(absoluteFilename.empty()); + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; + VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); } }; } diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index 514d392a3c..3f4da1945a 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -169,41 +169,5 @@ namespace Test::Package::Tests VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); VERIFY_IS_NULL(absoluteFilename); } - -#if 0 - TEST_METHOD(GetPackageFilePath_Filter_Static_NoMatch) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchStaticDependencies }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetPackageFilePath_Filter_Dynamic_NoMatch) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchDynamicDependencies }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetPackageFilePath_Filter_Static) - { - //TODO - } - - TEST_METHOD(GetPackageFilePath_Filter_Dynamic) - { - //TODO - } -#endif }; } diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp index f4912c6417..78062b3cd5 100644 --- a/test/Package/API/PackageTests_Package_WinRT.cpp +++ b/test/Package/API/PackageTests_Package_WinRT.cpp @@ -199,39 +199,5 @@ namespace Test::Package::Tests const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; VERIFY_IS_TRUE(absoluteFilename.empty()); } - -#if 0 - TEST_METHOD(GetFilePath_Filter_Static_NoMatch) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchStaticDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Static) - { - //TODO - } - - TEST_METHOD(GetFilePath_Filter_Dynamic) - { - //TODO - } -#endif }; } diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index 513415a5c5..64d224efab 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -196,39 +196,5 @@ namespace Test::Package::Tests const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; VERIFY_IS_TRUE(absoluteFilename.empty()); } - -#if 0 - TEST_METHOD(GetFilePath_Filter_Static_NoMatch) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchStaticDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Static) - { - //TODO - } - - TEST_METHOD(GetFilePath_Filter_Dynamic) - { - //TODO - } -#endif }; } diff --git a/test/Package/data/Framework/Package.Framework.vcxproj.filters b/test/Package/data/Framework/Package.Framework.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/Package/data/Framework/Package.Framework.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + + + diff --git a/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj b/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj new file mode 100644 index 0000000000..2fcb8fc520 --- /dev/null +++ b/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj @@ -0,0 +1,121 @@ + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {F41B5211-4E18-4625-96A3-0130001B57C8} + VCProjectVersion + Package.Test.Mutable.Msix + en-US + 16.0 + 10.0.26100.0 + 10.0.17763.0 + 10.0 + + + Utility + v143 + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(TargetName) + + + + + + + + $(RepoTestCertificatePFX) + $(RepoTestCertificatePassword) + + + + + + + + + + + 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}. + + + + + + + + + diff --git a/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj.filters b/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/Package/data/Framework/Package.Test.Framework.msix.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + + + diff --git a/test/Package/data/Framework/Shadow.cat b/test/Package/data/Framework/Shadow.cat new file mode 100644 index 0000000000..defd12bba0 --- /dev/null +++ b/test/Package/data/Framework/Shadow.cat @@ -0,0 +1 @@ +Catch me if you can... diff --git a/test/Package/data/Framework/appxmanifest.xml b/test/Package/data/Framework/appxmanifest.xml new file mode 100644 index 0000000000..35e0cfed85 --- /dev/null +++ b/test/Package/data/Framework/appxmanifest.xml @@ -0,0 +1,30 @@ + + + + + + + + Test.Package.Framework + Microsoft Corporation + logo.png + true + + + + + + + + + + diff --git a/test/Package/data/Framework/logo.png b/test/Package/data/Framework/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd7c0ce4d75499f6bcf2224412a39a23d5298a3 GIT binary patch literal 5632 zcmai2`%{$H8D2nfVVCw>^?ljX7tuE<3$yP(3tg4|V>Nn)Bz+ezBQ zbWA7d)V68bM#q_4S~J>arrIP;tc^))sw6s2e(A)S=3nUZ@Sc3D&U8BSywCfd_k8=E zbKcAO7{0yy{<9tG%vg8TubDZH^3c8trD--94Z+2(Su? z5HsbgC&gI%`pJu8fpc>~!^c2+%~yT!#8n_WfU-7Gn$4ZZQu-ol0o~ zTPDSG>sis|={t?EtOY!P^#}vBFa^qjm=uYrAApxI)xNXAi)bgE+#)!`OSo?6nuda0i%*VMzV;7r|qY zBO4KeA=tY|G=H}i3Gzb5xXZ*-DD9NuIQ9omf;6Kfv#hB0jySF2c%8R%BjrN3Kq=D-%f*D zqoeIIk>%u(90gupF#xLw=!WEpNso#{Q^S;U?w7gD9V&9CWGu|(UH5-*4vO!o7O!yO zk$PsbrWP~^u|fPNcq8Nt9_5}EAU#{c_(SGP!1$@xcn|;Q`Cq70$z(WGpNg=pa;Q~3^zyoJ4(>@558F}$FD`(YZ_=DF zxIo2NHETyhaja>$*)PKr@je*l$u#i2%OD+W+mfcZ8ce=)1P zUd&FGBQO-f8WyxnaG@JNZ|6@Y#aHj=a)PMR4j9|Dv6;~<7-wqvkT-7^_?s7gL>t2T zUVfxtCg1@AT&8R~UPfVIqI*RNs}@R`zo*uQJJS+Z4#npfX@P#PX7auSg85?I3I6@! zX&6kG25&0N{yNY`EAe}!Is=yP?mOV4rTabI2}SN5%~{PD0(}gtAkq!Jp9B=J1puoH zRQlCx;Cb;dsVtCX8UE#M=->{^4B`gQSBiN|^T6<*0)2IPk!8`qAzzmiJ(za7` z@or6un_6CG+75_2>Y%HCkY7k(WB}9=3S#N;X$@OK#H{2+4Ycu0V=6YP9pEWmDVF&? z9{24xZ=ILHJYPBc`P?9>E! zm+oB99){7q2J)oGh>sTrz}47&y4+y9W7rSjehe8S z0YfPm@FuJpc|)l{?Ka>4;d6Y@Ci5(l$Dk5EIRt-Y@a?f1f9Q3>>ByH~c&)xWmtgj@ z2Q>s>sl7A&ON^MHO`XMyq50bPN{rDkdLb+$TZS_yR(H(!`A-uu+PMuR;EF&VWYnr` zt^wTqwZ(dJX{k&`$5o$iOHDV8!gc+X9V!mZSphqXZg{sm8TR3O-dPiCpI@wmUas%_ z`uusQij3J3ZeZgNY`>KW&D;6$yHH%agBJy`Q25s?{P|JHo)pWm`JRLv-XvoXfVF2) zK?zrV`bdlnHS*w=tUwD_%j4;c(MIb`ej~5d{Zk{M>eFTq=N!PQIj%0`{4L@W9z6-& zk_&pIj0PCPKte6}`qLmT#As{aj0R?#$EnY03JtMXf_c}TXokg2C|r3dfm_vZ`%=J$ z0dp=0-j`h2VTw<;@G37-=V{d*6eEl=;T2>qnbnJ{GO3Tv^sfun6D)VOy`YU13?wkm zCVK_Xu3`4pndv7i?6>u2K-_j*CPNfg7di|D=+_4P=5#l#cyS~{S>{38%SqyNLK(zN zi#x#4n2aV^X%qZu@U$|c@ux3|S*3Zn10e0jt6-zi$dhenrD*v0-Gf6c$gFEu*y~p> zhRak_nR#~G?b8^j27<-=BO*!W6E^dEqhW?Y0T@q)jX`H-0eAJ@!BSp24#*a!9Qg8Q zpn`*+y;5pO*_jw;W2Q>=;(nReS z1&;PIXJ!Vh1=7pTs)hiCZI#?B@F@?epYq*(UB(<`XaD()Qf&xh{l}_;7*X8^FF$zx zZ5Soxs<~mes*|ZrsI$~E;(xyg0+!dj^B$E>3~M$r>XW%1s0jmG#Z>^R%mBqke0T}! z^Yd%`(NI9$n^Q{|3DQdbXEA8cFlzf5p-qt42Jx#`gxuiaf$6p`@Z=FU(`#&IL9#pr z4X2=&GF0T4D!~_Tx+7SS+`E9ECORrXHm*_3xIYXPp2=d5c$3%9c2ABSRD}v(lLchm z5u>sbgAsdhg1t2e*{UXB0uBqWz;XV8F~#!qvnq6Eo*5Wood8w2w=No6^rrF|PIE#O zPqb3f5B9~0CoTfIm}>!pS)ghU8$HaKuNS9qqBe-s?Gihei#0RIz;vi+Fe^ZXd;Oj3 z?`i&_4~Sr3QJ)^p%MdKq)aE4>o}7#b~%{%)&E4D6~DnKD8# zX_4GcgwGJng4&5Z1|F=^O#7ijX*!G;V0BniFxa`lyOS3tuoW^03CIxKz;$C{J1zF9 zr0@Pk({G7qO^t@hQ%o0-0AbGgp$^N|?{hKZk>G9pd$5m?~`QKgGu-lTy z^7myjx4gZoc>$ENuZmn%VBR9CAi~RBJfUR`#I^Xfst!pqZe`eeA6$5j1st|?91N%* zWy55N4{$ft3m{fRm5O>8>y_bRj~0i39tIz3%ButOlK>?0-JhKUO|RU1!@vaMU$eT_ O#tu8o`e9I1 + + + + + diff --git a/test/Package/data/MachineExternal/appxmanifest.xml b/test/Package/data/MachineExternal/appxmanifest.xml index d07bd05176..eb2ff59152 100644 --- a/test/Package/data/MachineExternal/appxmanifest.xml +++ b/test/Package/data/MachineExternal/appxmanifest.xml @@ -22,7 +22,7 @@ - + diff --git a/test/Package/data/Main/Package.Main.vcxproj.filters b/test/Package/data/Main/Package.Main.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/Package/data/Main/Package.Main.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + + + diff --git a/test/Package/data/Main/Package.Test.Main.msix.vcxproj b/test/Package/data/Main/Package.Test.Main.msix.vcxproj new file mode 100644 index 0000000000..dfd05f7fc9 --- /dev/null +++ b/test/Package/data/Main/Package.Test.Main.msix.vcxproj @@ -0,0 +1,121 @@ + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {472B8D93-9200-48B7-BFB6-9D9B85AA4025} + VCProjectVersion + Package.Test.Mutable.Msix + en-US + 16.0 + 10.0.26100.0 + 10.0.17763.0 + 10.0 + + + Utility + v143 + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(TargetName) + + + + + + + + $(RepoTestCertificatePFX) + $(RepoTestCertificatePassword) + + + + + + + + + + + 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}. + + + + + + + + + diff --git a/test/Package/data/Main/Package.Test.Main.msix.vcxproj.filters b/test/Package/data/Main/Package.Test.Main.msix.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/Package/data/Main/Package.Test.Main.msix.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + + + diff --git a/test/Package/data/Main/Shadow.cat b/test/Package/data/Main/Shadow.cat new file mode 100644 index 0000000000..defd12bba0 --- /dev/null +++ b/test/Package/data/Main/Shadow.cat @@ -0,0 +1 @@ +Catch me if you can... diff --git a/test/Package/data/Main/appxmanifest.xml b/test/Package/data/Main/appxmanifest.xml new file mode 100644 index 0000000000..55c6405f73 --- /dev/null +++ b/test/Package/data/Main/appxmanifest.xml @@ -0,0 +1,31 @@ + + + + + + + + Test.Package.Main + Microsoft Corporation + logo.png + true + + + + + + + + + + diff --git a/test/Package/data/Main/logo.png b/test/Package/data/Main/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd7c0ce4d75499f6bcf2224412a39a23d5298a3 GIT binary patch literal 5632 zcmai2`%{$H8D2nfVVCw>^?ljX7tuE<3$yP(3tg4|V>Nn)Bz+ezBQ zbWA7d)V68bM#q_4S~J>arrIP;tc^))sw6s2e(A)S=3nUZ@Sc3D&U8BSywCfd_k8=E zbKcAO7{0yy{<9tG%vg8TubDZH^3c8trD--94Z+2(Su? z5HsbgC&gI%`pJu8fpc>~!^c2+%~yT!#8n_WfU-7Gn$4ZZQu-ol0o~ zTPDSG>sis|={t?EtOY!P^#}vBFa^qjm=uYrAApxI)xNXAi)bgE+#)!`OSo?6nuda0i%*VMzV;7r|qY zBO4KeA=tY|G=H}i3Gzb5xXZ*-DD9NuIQ9omf;6Kfv#hB0jySF2c%8R%BjrN3Kq=D-%f*D zqoeIIk>%u(90gupF#xLw=!WEpNso#{Q^S;U?w7gD9V&9CWGu|(UH5-*4vO!o7O!yO zk$PsbrWP~^u|fPNcq8Nt9_5}EAU#{c_(SGP!1$@xcn|;Q`Cq70$z(WGpNg=pa;Q~3^zyoJ4(>@558F}$FD`(YZ_=DF zxIo2NHETyhaja>$*)PKr@je*l$u#i2%OD+W+mfcZ8ce=)1P zUd&FGBQO-f8WyxnaG@JNZ|6@Y#aHj=a)PMR4j9|Dv6;~<7-wqvkT-7^_?s7gL>t2T zUVfxtCg1@AT&8R~UPfVIqI*RNs}@R`zo*uQJJS+Z4#npfX@P#PX7auSg85?I3I6@! zX&6kG25&0N{yNY`EAe}!Is=yP?mOV4rTabI2}SN5%~{PD0(}gtAkq!Jp9B=J1puoH zRQlCx;Cb;dsVtCX8UE#M=->{^4B`gQSBiN|^T6<*0)2IPk!8`qAzzmiJ(za7` z@or6un_6CG+75_2>Y%HCkY7k(WB}9=3S#N;X$@OK#H{2+4Ycu0V=6YP9pEWmDVF&? z9{24xZ=ILHJYPBc`P?9>E! zm+oB99){7q2J)oGh>sTrz}47&y4+y9W7rSjehe8S z0YfPm@FuJpc|)l{?Ka>4;d6Y@Ci5(l$Dk5EIRt-Y@a?f1f9Q3>>ByH~c&)xWmtgj@ z2Q>s>sl7A&ON^MHO`XMyq50bPN{rDkdLb+$TZS_yR(H(!`A-uu+PMuR;EF&VWYnr` zt^wTqwZ(dJX{k&`$5o$iOHDV8!gc+X9V!mZSphqXZg{sm8TR3O-dPiCpI@wmUas%_ z`uusQij3J3ZeZgNY`>KW&D;6$yHH%agBJy`Q25s?{P|JHo)pWm`JRLv-XvoXfVF2) zK?zrV`bdlnHS*w=tUwD_%j4;c(MIb`ej~5d{Zk{M>eFTq=N!PQIj%0`{4L@W9z6-& zk_&pIj0PCPKte6}`qLmT#As{aj0R?#$EnY03JtMXf_c}TXokg2C|r3dfm_vZ`%=J$ z0dp=0-j`h2VTw<;@G37-=V{d*6eEl=;T2>qnbnJ{GO3Tv^sfun6D)VOy`YU13?wkm zCVK_Xu3`4pndv7i?6>u2K-_j*CPNfg7di|D=+_4P=5#l#cyS~{S>{38%SqyNLK(zN zi#x#4n2aV^X%qZu@U$|c@ux3|S*3Zn10e0jt6-zi$dhenrD*v0-Gf6c$gFEu*y~p> zhRak_nR#~G?b8^j27<-=BO*!W6E^dEqhW?Y0T@q)jX`H-0eAJ@!BSp24#*a!9Qg8Q zpn`*+y;5pO*_jw;W2Q>=;(nReS z1&;PIXJ!Vh1=7pTs)hiCZI#?B@F@?epYq*(UB(<`XaD()Qf&xh{l}_;7*X8^FF$zx zZ5Soxs<~mes*|ZrsI$~E;(xyg0+!dj^B$E>3~M$r>XW%1s0jmG#Z>^R%mBqke0T}! z^Yd%`(NI9$n^Q{|3DQdbXEA8cFlzf5p-qt42Jx#`gxuiaf$6p`@Z=FU(`#&IL9#pr z4X2=&GF0T4D!~_Tx+7SS+`E9ECORrXHm*_3xIYXPp2=d5c$3%9c2ABSRD}v(lLchm z5u>sbgAsdhg1t2e*{UXB0uBqWz;XV8F~#!qvnq6Eo*5Wood8w2w=No6^rrF|PIE#O zPqb3f5B9~0CoTfIm}>!pS)ghU8$HaKuNS9qqBe-s?Gihei#0RIz;vi+Fe^ZXd;Oj3 z?`i&_4~Sr3QJ)^p%MdKq)aE4>o}7#b~%{%)&E4D6~DnKD8# zX_4GcgwGJng4&5Z1|F=^O#7ijX*!G;V0BniFxa`lyOS3tuoW^03CIxKz;$C{J1zF9 zr0@Pk({G7qO^t@hQ%o0-0AbGgp$^N|?{hKZk>G9pd$5m?~`QKgGu-lTy z^7myjx4gZoc>$ENuZmn%VBR9CAi~RBJfUR`#I^Xfst!pqZe`eeA6$5j1st|?91N%* zWy55N4{$ft3m{fRm5O>8>y_bRj~0i39tIz3%ButOlK>?0-JhKUO|RU1!@vaMU$eT_ O#tu8o`e9I1 + + + + + diff --git a/test/Package/data/Mutable/appxmanifest.xml b/test/Package/data/Mutable/appxmanifest.xml index b1b209ff7b..ad6306b1dd 100644 --- a/test/Package/data/Mutable/appxmanifest.xml +++ b/test/Package/data/Mutable/appxmanifest.xml @@ -22,7 +22,7 @@ - + diff --git a/test/Package/data/UserExternal/appxmanifest.xml b/test/Package/data/UserExternal/appxmanifest.xml index d88a374f93..421446df6e 100644 --- a/test/Package/data/UserExternal/appxmanifest.xml +++ b/test/Package/data/UserExternal/appxmanifest.xml @@ -22,7 +22,7 @@ - + diff --git a/test/inc/WindowsAppRuntime.Test.Package.h b/test/inc/WindowsAppRuntime.Test.Package.h index b372cc3455..7dc64c24fb 100644 --- a/test/inc/WindowsAppRuntime.Test.Package.h +++ b/test/inc/WindowsAppRuntime.Test.Package.h @@ -284,7 +284,14 @@ inline std::filesystem::path GetMsixPackagePath(PCWSTR packageDirName) WIN32_FILE_ATTRIBUTE_DATA data{}; const auto ok{ GetFileAttributesExW(msix.c_str(), GetFileExInfoStandard, &data) }; const auto lastError{ ::GetLastError() }; - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"GetFileAttributesExW(%ls):%d LastError:%u", msix.c_str(), static_cast(ok), lastError)); + if (ok) + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"GetFileAttributesExW(%ls):TRUE", msix.c_str())); + } + else + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"GetFileAttributesExW(%ls):FALSE LastError:%u", msix.c_str(), lastError)); + } std::error_code errorcode{}; auto isregularfile{ std::filesystem::is_regular_file(msix, errorcode) }; @@ -317,6 +324,7 @@ inline void AddPackage(PCWSTR packageDirName, PCWSTR packageFullName) { auto msixUri{ GetMsixPackageUri(packageDirName) }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"packageManager.AddPackageAsync(): uri=%ls", msixUri.ToString().c_str())); winrt::Windows::Management::Deployment::PackageManager packageManager; auto options{ winrt::Windows::Management::Deployment::DeploymentOptions::None }; auto deploymentResult{ packageManager.AddPackageAsync(msixUri, nullptr, options).get() }; From 9f4fbc9f9baa38bf03b79c28b5d5a10315414a9b Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 8 Feb 2026 22:14:37 -0800 Subject: [PATCH 17/33] Removed SearchStatic/DynamicDependencies options as we can't determine it (Windows/GetCurrentPackageInfo doesn't return that distinction) --- dev/Package/M.W.A.Package.cpp | 2 - dev/Package/M.W.A.PackageGraph.cpp | 2 - dev/Package/Package.idl | 16 ----- dev/Package/package_runtime.cpp | 48 ++++----------- dev/Package/package_runtime.h | 16 ----- specs/package/Package.md | 40 +----------- test/Package/API/PackageTests.Packages.h | 30 ++++----- .../API/PackageTests_PackageGraph_Base.h | 26 +------- ...PackageTests_PackageGraph_Packaged_CPP.cpp | 59 ++---------------- ...ckageTests_PackageGraph_Packaged_WinRT.cpp | 61 ++----------------- ...ckageTests_PackageGraph_Unpackaged_CPP.cpp | 56 ++--------------- ...ageTests_PackageGraph_Unpackaged_WinRT.cpp | 58 +++--------------- test/Package/API/PackageTests_Package_CPP.cpp | 4 +- .../API/PackageTests_Package_WinRT.cpp | 8 +-- test/Package/API/PackageTests_WinRT.cpp | 4 +- .../Mutable/Package.Test.Mutable.msix.vcxproj | 1 + test/Package/data/Mutable/Shadow.cat | 1 + 17 files changed, 66 insertions(+), 366 deletions(-) create mode 100644 test/Package/data/Mutable/Shadow.cat diff --git a/dev/Package/M.W.A.Package.cpp b/dev/Package/M.W.A.Package.cpp index d52199aa39..a455ad54a1 100644 --- a/dev/Package/M.W.A.Package.cpp +++ b/dev/Package/M.W.A.Package.cpp @@ -23,8 +23,6 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages"); static_assert(static_cast(GetFilePathOptions::SearchBundlePackages) == static_cast(GetPackageFilePathOptions_SearchBundlePackages), "GetFilePathOptions::SearchBundlePackages!= GetPackageFilePathOptions_SearchBundlePackages"); static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies"); - static_assert(static_cast(GetFilePathOptions::SearchStaticDependencies) == static_cast(GetPackageFilePathOptions_SearchStaticDependencies), "GetFilePathOptions::SearchStaticDependencies!= GetPackageFilePathOptions_SearchStaticDependencies"); - static_assert(static_cast(GetFilePathOptions::SearchDynamicDependencies) == static_cast(GetPackageFilePathOptions_SearchDynamicDependencies), "GetFilePathOptions::SearchDynamicDependencies!= GetPackageFilePathOptions_SearchDynamicDependencies"); hstring Package::GetFilePath(hstring const& filename) { diff --git a/dev/Package/M.W.A.PackageGraph.cpp b/dev/Package/M.W.A.PackageGraph.cpp index 7979f555a1..f29bfde230 100644 --- a/dev/Package/M.W.A.PackageGraph.cpp +++ b/dev/Package/M.W.A.PackageGraph.cpp @@ -23,8 +23,6 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages"); static_assert(static_cast(GetFilePathOptions::SearchBundlePackages) == static_cast(GetPackageFilePathOptions_SearchBundlePackages), "GetFilePathOptions::SearchBundlePackages!= GetPackageFilePathOptions_SearchBundlePackages"); static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies"); - static_assert(static_cast(GetFilePathOptions::SearchStaticDependencies) == static_cast(GetPackageFilePathOptions_SearchStaticDependencies), "GetFilePathOptions::SearchStaticDependencies!= GetPackageFilePathOptions_SearchStaticDependencies"); - static_assert(static_cast(GetFilePathOptions::SearchDynamicDependencies) == static_cast(GetPackageFilePathOptions_SearchDynamicDependencies), "GetFilePathOptions::SearchDynamicDependencies!= GetPackageFilePathOptions_SearchDynamicDependencies"); hstring PackageGraph::GetFilePath(hstring const& filename) { diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl index d3902b57b1..edecd47b6d 100644 --- a/dev/Package/Package.idl +++ b/dev/Package/Package.idl @@ -79,22 +79,6 @@ namespace Microsoft.Windows.ApplicationModel /// are omitted then all package types are searched (i.e. specify all or none /// yields the same result). SearchHostRuntimeDependencies = 0x0200, - - /// Include Static package dependencies in the file search order - /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and - /// dynamic packages are searched (i.e. specify both or neither yields the same result). - /// @note This option is only relevant when searching the package graph i.e. methods of PackageGraph. - /// @see PackageGraph::GetFilePath() - /// @see SearchDynamicDependencies - SearchStaticDependencies = 0x0400, - - /// Include Dynamic package dependencies in the file search order - /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and - /// dynamic packages are searched (i.e. specify both or neither yields the same result). - /// @note This option is only relevant when searching the package graph i.e. methods of PackageGraph. - /// @see PackageGraph::GetFilePath() - /// @see SearchStaticDependencies - SearchDynamicDependencies = 0x0800, }; [contract(PackageRuntimeContract, 1)] diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index 8cdcac6234..6f1da653e5 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -13,34 +13,28 @@ inline GetPackageFilePathOptions package_properties_to_options( const auto hostRuntimeMatch{ WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_HOSTRUNTIME) ? GetPackageFilePathOptions_SearchHostRuntimeDependencies : GetPackageFilePathOptions_None }; - const auto isStaticDependency{ WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_STATIC) ? - GetPackageFilePathOptions_SearchStaticDependencies : - GetPackageFilePathOptions_None }; - const auto isDynamicDependency{ WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_DYNAMIC) ? - GetPackageFilePathOptions_SearchDynamicDependencies : - GetPackageFilePathOptions_None }; if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_FRAMEWORK)) { - return GetPackageFilePathOptions_SearchFrameworkPackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; + return GetPackageFilePathOptions_SearchFrameworkPackages | hostRuntimeMatch; } else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_OPTIONAL)) { - return GetPackageFilePathOptions_SearchOptionalPackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; + return GetPackageFilePathOptions_SearchOptionalPackages | hostRuntimeMatch; } else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_RESOURCE)) { - return GetPackageFilePathOptions_SearchResourcePackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; + return GetPackageFilePathOptions_SearchResourcePackages | hostRuntimeMatch; } else if (WI_IsFlagSet(packageInfoFlags, PACKAGE_PROPERTY_BUNDLE)) { - return GetPackageFilePathOptions_SearchBundlePackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; + return GetPackageFilePathOptions_SearchBundlePackages | hostRuntimeMatch; } else { // PACKAGE_INFO.flags has no PACKAGE_PROPERTY_MAIN so we can only determine PackageType=Main // by first verifying it's not any other type of package (Bundle|Framework|Optional|Resource). // When all else is ruled out what we're left with must be a Main package - return GetPackageFilePathOptions_SearchMainPackages | hostRuntimeMatch | isStaticDependency | isDynamicDependency; + return GetPackageFilePathOptions_SearchMainPackages | hostRuntimeMatch; } } @@ -81,10 +75,6 @@ inline bool is_match_for_package_properties( _In_ GetPackageFilePathOptions options, PACKAGE_INFO_REFERENCE packageInfoReference) { - // We're processing a package definition i.e. always static information. - // Thus ignore GetPackageFilePathOptions_SearchStaticDependencies - // and GetPackageFilePathOptions_SearchDynamicDependencies options. - // Detect PackageType|HostRuntimeDependency // // If options = All or None specified then all packages are a match thus no need to fetch the package's properties @@ -111,7 +101,7 @@ inline bool is_match_for_package_properties( _In_ GetPackageFilePathOptions options, std::uint32_t packageInfoFlags) { - // Detect PackageType|HostRuntimeDependency and Static|DynamicDependency + // Detect PackageType|HostRuntimeDependency // // If options = All or None specified then all packages are a match thus no need to fetch the package's properties constexpr auto maskMatchPackageType{ GetPackageFilePathOptions_SearchMainPackages | @@ -120,9 +110,7 @@ inline bool is_match_for_package_properties( GetPackageFilePathOptions_SearchResourcePackages | GetPackageFilePathOptions_SearchBundlePackages | GetPackageFilePathOptions_SearchHostRuntimeDependencies }; - constexpr auto maskMatchStaticDynamic{ GetPackageFilePathOptions_SearchStaticDependencies | - GetPackageFilePathOptions_SearchDynamicDependencies }; - constexpr auto maskMatchAll{ maskMatchPackageType | maskMatchStaticDynamic }; + constexpr auto maskMatchAll{ maskMatchPackageType }; const auto optionsToMatch{ options & maskMatchAll }; if ((optionsToMatch == GetPackageFilePathOptions_None) || (optionsToMatch == maskMatchAll)) { @@ -130,7 +118,7 @@ inline bool is_match_for_package_properties( } // Does this package meet the criteria? - return WI_IsAnyFlagSet(packageInfoFlags, maskMatchPackageType) && WI_IsAnyFlagSet(packageInfoFlags, maskMatchStaticDynamic); + return WI_IsAnyFlagSet(packageInfoFlags, optionsToMatch); } inline std::filesystem::path get_package_file_for_location( @@ -227,9 +215,7 @@ inline GetPackageFilePathOptions ToEffectiveOptions( GetPackageFilePathOptions_SearchOptionalPackages | GetPackageFilePathOptions_SearchResourcePackages | GetPackageFilePathOptions_SearchBundlePackages | - GetPackageFilePathOptions_SearchHostRuntimeDependencies | - GetPackageFilePathOptions_SearchStaticDependencies | - GetPackageFilePathOptions_SearchDynamicDependencies; + GetPackageFilePathOptions_SearchHostRuntimeDependencies; } // If Search*Dependencies are all clear then search them all @@ -247,17 +233,8 @@ inline GetPackageFilePathOptions ToEffectiveOptions( GetPackageFilePathOptions_SearchHostRuntimeDependencies }; if (WI_AreAllFlagsClear(options, maskPackageTypes)) { - // If SearchStaticDependencies and SearchDynamicDependencies are clear then search both - options |= maskPackageTypes; - } - - // If SearchStaticDependencies and SearchDynamicDependencies are all clear then search both - constexpr auto maskStaticDynamicDependencies{ GetPackageFilePathOptions_SearchStaticDependencies | GetPackageFilePathOptions_SearchDynamicDependencies }; - if (WI_AreAllFlagsClear(options, maskStaticDynamicDependencies)) - { - options |= maskStaticDynamicDependencies; + return options | maskPackageTypes; } - return options; } } @@ -325,13 +302,14 @@ STDAPI GetPackageFilePathInPackageGraph( const auto& packageInfo{ packageInfos[index] }; // Does the package's properties match our search criteria? - const auto packageFullName{ packageInfo.packageFullName }; - if (!appmodel::is_match_for_package_properties(effectiveOptions, packageInfo.flags)) + const auto packageInfoFlags{ appmodel::package_properties_to_options(packageInfo.flags) }; + if (!appmodel::is_match_for_package_properties(effectiveOptions, packageInfoFlags)) { continue; } // This package is included in our search. Check for the file + const auto packageFullName{ packageInfo.packageFullName }; auto path{ appmodel::get_package_file(packageFullName, filename, effectiveOptions) }; if (!path.empty()) { diff --git a/dev/Package/package_runtime.h b/dev/Package/package_runtime.h index a4fd9c8831..633ce37fac 100644 --- a/dev/Package/package_runtime.h +++ b/dev/Package/package_runtime.h @@ -75,22 +75,6 @@ typedef enum GetPackageFilePathOptions /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0200, - - /// Include Static package dependencies in the file search order - /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted - /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). - /// @note This option is only relevant when searching the package graph i.e. GetPackageFilePathInPackageGraph(); - /// @see GetPackageFilePathInPackageGraph() - /// @see GetPackageFilePathOptions_SearchDynamicDependencies - GetPackageFilePathOptions_SearchStaticDependencies = 0x0400, - - /// Include Dynamic package dependencies in the file search order - /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted - /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). - /// @note This option is only relevant when searching the package graph i.e. GetPackageFilePathInPackageGraph(); - /// @see GetPackageFilePathInPackageGraph() - /// @see GetPackageFilePathOptions_SearchStaticDependencies - GetPackageFilePathOptions_SearchDynamicDependencies = 0x0800, } GetPackageFilePathOptions; DEFINE_ENUM_FLAG_OPERATORS(GetPackageFilePathOptions) diff --git a/specs/package/Package.md b/specs/package/Package.md index 7354c0d2b5..fd6fdeae6e 100644 --- a/specs/package/Package.md +++ b/specs/package/Package.md @@ -377,9 +377,7 @@ string GetXamlWinMD() GetPackageFilePathOptions.SearchUserExternalPath | GetPackageFilePathOptions.SearchMainPackages | GetPackageFilePathOptions.SearchFrameworkPath | - GetPackageFilePathOptions.SearchOptionalPath | - GetPackageFilePathOptions.SearchStaticDependencies | - GetPackageFilePathOptions.SearchDynamicDependencies; + GetPackageFilePathOptions.SearchOptionalPath; var absoluteFilename = PackageGraph.GetFilePath("Microsoft.UI.Xaml.winmd", options); if (absoluteFilename == null) { @@ -400,9 +398,7 @@ std::wstring GetXamlWinMD() GetPackageFilePathOptions_SearchUserExternalPath | GetPackageFilePathOptions_SearchMainPackages | GetPackageFilePathOptions_SearchFrameworkPath | - GetPackageFilePathOptions_SearchOptionalPath | - GetPackageFilePathOptions_SearchStaticDependencies | - GetPackageFilePathOptions_SearchDynamicDependencies }; + GetPackageFilePathOptions_SearchOptionalPath }; wil::unique_process_heap_string absoluteFilename; const HRESULT hr{ GetPackageFilePathInPackageGraph( L"Microsoft.UI.Xaml.winmd", options, wistd::out_param(absoluteFilename)) }; @@ -507,22 +503,6 @@ namespace Microsoft.Windows.ApplicationModel /// are omitted then all package types are searched (i.e. specify all or none /// yields the same result). SearchHostRuntimeDependencies = 0x0200, - - /// Include Static package dependencies in the file search order - /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and - /// dynamic packages are searched (i.e. specify both or neither yields the same result). - /// @note This option is only relevant when searching the package graph i.e. methods of PackageGraph. - /// @see PackageGraph::GetFilePath() - /// @see SearchDynamicDependencies - SearchStaticDependencies = 0x0400, - - /// Include Dynamic package dependencies in the file search order - /// @note If both SearchStaticDependencies and SearchDynamicDependencies are omitted then both static and - /// dynamic packages are searched (i.e. specify both or neither yields the same result). - /// @note This option is only relevant when searching the package graph i.e. methods of PackageGraph. - /// @see PackageGraph::GetFilePath() - /// @see SearchStaticDependencies - SearchDynamicDependencies = 0x0800, }; [contract(PackageRuntimeContract, 1)] @@ -673,22 +653,6 @@ typedef enum GetPackageFilePathOptions /// GetPackageFilePathOptions_SearchBundlePackages and GetPackageFilePathOptions_SearchHostRuntimeDependencies /// are omitted then all package types are searched (i.e. specify all or none yields the same result). GetPackageFilePathOptions_SearchHostRuntimeDependencies = 0x0200, - - /// Include Static package dependencies in the file search order - /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted - /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). - /// @note This option is only relevant when searching the package graph i.e. GetPackageFilePathInPackageGraph(); - /// @see GetPackageFilePathInPackageGraph() - /// @see GetPackageFilePathOptions_SearchDynamicDependencies - GetPackageFilePathOptions_SearchStaticDependencies = 0x0400, - - /// Include Dynamic package dependencies in the file search order - /// @note If both GetPackageFilePathOptions_SearchStaticDependencies and GetPackageFilePathOptions_SearchDynamicDependencies are omitted - /// then both static and dynamic packages are searched (i.e. specify both or neither yields the same result). - /// @note This option is only relevant when searching the package graph i.e. GetPackageFilePathInPackageGraph(); - /// @see GetPackageFilePathInPackageGraph() - /// @see GetPackageFilePathOptions_SearchStaticDependencies - GetPackageFilePathOptions_SearchDynamicDependencies = 0x0800, } GetPackageFilePathOptions; DEFINE_ENUM_FLAG_OPERATORS(GetPackageFilePathOptions) diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h index b4f7f5872e..5f72cc532d 100644 --- a/test/Package/API/PackageTests.Packages.h +++ b/test/Package/API/PackageTests.Packages.h @@ -14,33 +14,33 @@ namespace Test::Packages { namespace Framework { - constexpr PCWSTR c_packageDirName = L"Package.Test.Framework.msix"; - constexpr PCWSTR c_packageFamilyName = L"Test.Package.Framework_8wekyb3d8bbwe"; - constexpr PCWSTR c_packageFullName = L"Test.Package.Framework_1.2.3.4_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageDirName{ L"Package.Test.Framework.msix" }; + constexpr PCWSTR c_packageFamilyName{ L"Test.Package.Framework_8wekyb3d8bbwe" }; + constexpr PCWSTR c_packageFullName{ L"Test.Package.Framework_1.2.3.4_neutral__8wekyb3d8bbwe" }; } namespace Main { - constexpr PCWSTR c_packageDirName = L"Package.Test.Main.msix"; - constexpr PCWSTR c_packageFamilyName = L"Test.Package.Main_8wekyb3d8bbwe"; - constexpr PCWSTR c_packageFullName = L"Test.Package.Main_1.2.3.4_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageDirName{ L"Package.Test.Main.msix" }; + constexpr PCWSTR c_packageFamilyName{ L"Test.Package.Main_8wekyb3d8bbwe" }; + constexpr PCWSTR c_packageFullName{ L"Test.Package.Main_1.2.3.4_neutral__8wekyb3d8bbwe" }; } namespace Mutable { - constexpr PCWSTR c_packageDirName = L"Package.Test.Mutable.msix"; - constexpr PCWSTR c_packageFamilyName = L"Test.Package.Mutable_8wekyb3d8bbwe"; - constexpr PCWSTR c_packageFullName = L"Test.Package.Mutable_1.2.3.4_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageDirName{ L"Package.Test.Mutable.msix" }; + constexpr PCWSTR c_packageFamilyName{ L"Test.Package.Mutable_8wekyb3d8bbwe" }; + constexpr PCWSTR c_packageFullName{ L"Test.Package.Mutable_1.2.3.4_neutral__8wekyb3d8bbwe" }; } namespace UserExternal { - constexpr PCWSTR c_packageDirName = L"Package.Test.UserExternal.msix"; - constexpr PCWSTR c_packageFamilyName = L"Test.Package.UserExternal_8wekyb3d8bbwe"; - constexpr PCWSTR c_packageFullName = L"Test.Package.UserExternal_1.2.3.4_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageDirName{ L"Package.Test.UserExternal.msix" }; + constexpr PCWSTR c_packageFamilyName{ L"Test.Package.UserExternal_8wekyb3d8bbwe" }; + constexpr PCWSTR c_packageFullName{ L"Test.Package.UserExternal_1.2.3.4_neutral__8wekyb3d8bbwe" }; } namespace MachineExternal { - constexpr PCWSTR c_packageDirName = L"Package.Test.MachineExternal.msix"; - constexpr PCWSTR c_packageFamilyName = L"Test.Package.MachineExternal_8wekyb3d8bbwe"; - constexpr PCWSTR c_packageFullName = L"Test.Package.MachineExternal_1.2.3.4_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageDirName{ L"Package.Test.MachineExternal.msix" }; + constexpr PCWSTR c_packageFamilyName{ L"Test.Package.MachineExternal_8wekyb3d8bbwe" }; + constexpr PCWSTR c_packageFullName{ L"Test.Package.MachineExternal_1.2.3.4_neutral__8wekyb3d8bbwe" }; } } diff --git a/test/Package/API/PackageTests_PackageGraph_Base.h b/test/Package/API/PackageTests_PackageGraph_Base.h index f7132dfbba..90de854625 100644 --- a/test/Package/API/PackageTests_PackageGraph_Base.h +++ b/test/Package/API/PackageTests_PackageGraph_Base.h @@ -23,31 +23,11 @@ namespace Test::Package::Tests class PackageTests_PackageGraph_Base { - protected: - bool PackagedClassSetup() - { - return ClassSetup(true); - } - - bool PackagedClassCleanup() - { - return ClassCleanup(false); - } - - bool UnpackagedClassSetup() - { - return ClassSetup(true); - } - - bool UnpackagedClassCleanup() - { - return ClassCleanup(false); - } - private: wil::unique_package_dependency_context m_windowsAppRuntimeFramework_packageDependencyContext; - bool ClassSetup(const bool callerIsPackaged) + protected: + bool ClassSetup() { if (!::WindowsVersion::IsWindows11_24H2OrGreater()) { @@ -76,7 +56,7 @@ namespace Test::Package::Tests return true; } - bool ClassCleanup(const bool callerIsPackaged = true) + bool ClassCleanup() { m_windowsAppRuntimeFramework_packageDependencyContext.reset(); diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp index 953f4ae947..43d3895dee 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp @@ -36,12 +36,12 @@ namespace Test::Package::Tests return true; } - return PackageTests_PackageGraph_Base::PackagedClassSetup(); + return PackageTests_PackageGraph_Base::ClassSetup(); } TEST_CLASS_CLEANUP(ClassCleanup) { - return PackageTests_PackageGraph_Base::PackagedClassCleanup(); + return PackageTests_PackageGraph_Base::ClassCleanup(); } TEST_METHOD(GetFilePath) @@ -140,7 +140,7 @@ namespace Test::Package::Tests GetPackageFilePathOptions_SearchFrameworkPackages }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); + VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get()))); } TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) @@ -148,61 +148,12 @@ namespace Test::Package::Tests PCWSTR packageFamilyName{ Framework_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchMainPackages }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetFilePath_Filter_Static_NoMatch) - { - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchStaticDependencies }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) - { - PCWSTR fileName{ L"Shadow.cat" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchDynamicDependencies }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetFilePath_Filter_Static) - { - //TODO - } - - TEST_METHOD(GetFilePath_Filter_Dynamic) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchDynamicDependencies }; + GetPackageFilePathOptions_SearchMainPackages }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get()))); } }; } diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp index 53f94e1394..98ac3a8400 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp @@ -36,12 +36,12 @@ namespace Test::Package::Tests return true; } - return PackageTests_PackageGraph_Base::PackagedClassSetup(); + return PackageTests_PackageGraph_Base::ClassSetup(); } TEST_CLASS_CLEANUP(ClassCleanup) { - return PackageTests_PackageGraph_Base::PackagedClassCleanup(); + return PackageTests_PackageGraph_Base::ClassCleanup(); } TEST_METHOD(GetFilePath_InvalidParameter) @@ -155,11 +155,11 @@ namespace Test::Package::Tests winrt::hstring packageFamilyName{ Main_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - PCWSTR fileName{ L"Shadow.cat" }; + winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); + VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str())); } TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) @@ -172,58 +172,7 @@ namespace Test::Package::Tests const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Static_NoMatch) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchStaticDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Static) - { - //TODO - } - - TEST_METHOD(GetFilePath_Filter_Dynamic) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - winrt::hstring fileName{ L"Shadow.cat" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str())); } }; } diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp index 19a55ecdf0..5af7021a92 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp @@ -32,12 +32,12 @@ namespace Test::Package::Tests return true; } - return PackageTests_PackageGraph_Base::UnpackagedClassSetup(); + return PackageTests_PackageGraph_Base::ClassSetup(); } TEST_CLASS_CLEANUP(ClassCleanup) { - return PackageTests_PackageGraph_Base::UnpackagedClassCleanup(); + return PackageTests_PackageGraph_Base::ClassCleanup(); } TEST_METHOD(GetFilePath_InvalidParameter) @@ -141,12 +141,12 @@ namespace Test::Package::Tests PCWSTR packageFamilyName{ Main_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - PCWSTR fileName{ L"AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | GetPackageFilePathOptions_SearchFrameworkPackages }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); + VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get()))); } TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) @@ -154,56 +154,12 @@ namespace Test::Package::Tests PCWSTR packageFamilyName{ Framework_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchMainPackages }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetFilePath_Filter_Static_NoMatch) - { - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchStaticDependencies }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) - { - PCWSTR fileName{ L"Shadow.cat" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchDynamicDependencies }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetFilePath_Filter_Dynamic) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchDynamicDependencies }; + GetPackageFilePathOptions_SearchMainPackages }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePathInPackageGraph(fileName, options, wil::out_param(absoluteFilename))); - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get()))); } }; } diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp index 909a9a020a..73ce586327 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp @@ -32,12 +32,12 @@ namespace Test::Package::Tests return true; } - return PackageTests_PackageGraph_Base::UnpackagedClassSetup(); + return PackageTests_PackageGraph_Base::ClassSetup(); } TEST_CLASS_CLEANUP(ClassCleanup) { - return PackageTests_PackageGraph_Base::UnpackagedClassCleanup(); + return PackageTests_PackageGraph_Base::ClassCleanup(); } TEST_METHOD(GetFilePath_InvalidParameter) @@ -147,14 +147,14 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) { - PCWSTR packageFamilyName{ Main_PackageFamilyName }; + winrt::hstring packageFamilyName{ Main_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - winrt::hstring fileName{ L"AppxManifest.xml" }; + winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); + VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str())); } TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) @@ -162,55 +162,11 @@ namespace Test::Package::Tests winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Static_NoMatch) - { - winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchStaticDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Dynamic_NoMatch) - { - winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_Filter_Dynamic) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; - wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchDynamicDependencies }; + winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str())); } }; } diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index 3f4da1945a..a6d5093f96 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -156,7 +156,7 @@ namespace Test::Package::Tests GetPackageFilePathOptions_SearchFrameworkPackages }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); + VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get()))); } TEST_METHOD(GetPackageFilePath_FilterPackageType_Framework_NoMatch) @@ -167,7 +167,7 @@ namespace Test::Package::Tests GetPackageFilePathOptions_SearchMainPackages }; wil::unique_process_heap_ptr absoluteFilename; VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); + VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"AbsoluteFilename:%ls", (!absoluteFilename ? L"" : absoluteFilename.get()))); } }; } diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp index 78062b3cd5..c33e71ad7f 100644 --- a/test/Package/API/PackageTests_Package_WinRT.cpp +++ b/test/Package/API/PackageTests_Package_WinRT.cpp @@ -183,21 +183,21 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) { winrt::hstring packageFullName{ Main_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; + winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); + VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str())); } TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) { winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; + winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); + VERIFY_IS_TRUE(absoluteFilename.empty(), WEX::Common::String().Format(L"AbsoluteFilename:%ls", absoluteFilename.c_str())); } }; } diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index 64d224efab..845cc4f775 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -180,7 +180,7 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) { winrt::hstring packageFullName{ Main_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; + winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; @@ -190,7 +190,7 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) { winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; + winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; diff --git a/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj index f343603d1d..08fd96ab4e 100644 --- a/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj +++ b/test/Package/data/Mutable/Package.Test.Mutable.msix.vcxproj @@ -94,6 +94,7 @@ + $(RepoTestCertificatePFX) diff --git a/test/Package/data/Mutable/Shadow.cat b/test/Package/data/Mutable/Shadow.cat new file mode 100644 index 0000000000..defd12bba0 --- /dev/null +++ b/test/Package/data/Mutable/Shadow.cat @@ -0,0 +1 @@ +Catch me if you can... From 7f6c9af0053d96d4abdc3b20d8024fcfe9a2be86 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 8 Feb 2026 22:18:23 -0800 Subject: [PATCH 18/33] Tweaks --- test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp | 2 +- test/Package/API/PackageTests_Package_CPP.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp index 98ac3a8400..8ba918976a 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp @@ -168,7 +168,7 @@ namespace Test::Package::Tests winrt::hstring packageFamilyName{ Framework_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; - winrt::hstring fileName{ L"AppxManifest.xml" }; + winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::PackageGraph::GetFilePath(fileName, options) }; diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index a6d5093f96..d8ad9369bc 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -151,7 +151,7 @@ namespace Test::Package::Tests TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch) { PCWSTR packageFullName{ Main_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | GetPackageFilePathOptions_SearchFrameworkPackages }; wil::unique_process_heap_ptr absoluteFilename; @@ -162,7 +162,7 @@ namespace Test::Package::Tests TEST_METHOD(GetPackageFilePath_FilterPackageType_Framework_NoMatch) { PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; + PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchInstallPath | GetPackageFilePathOptions_SearchMainPackages }; wil::unique_process_heap_ptr absoluteFilename; From f491637317149ba391eedfebeabd3817848cc70f Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 9 Feb 2026 09:30:10 -0800 Subject: [PATCH 19/33] Fixed bad merge --- .../AccessControlTests.vcxproj | 115 +++++++++++++++--- 1 file changed, 100 insertions(+), 15 deletions(-) diff --git a/test/AccessControlTests/AccessControlTests.vcxproj b/test/AccessControlTests/AccessControlTests.vcxproj index 3c0d7741cd..3bbbdf09cb 100644 --- a/test/AccessControlTests/AccessControlTests.vcxproj +++ b/test/AccessControlTests/AccessControlTests.vcxproj @@ -35,16 +35,41 @@ AccessControlTests 10.0 - + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + Unicode + + + DynamicLibrary + false v143 Unicode - + + DynamicLibrary true + v143 + Unicode - + + DynamicLibrary false + v143 + Unicode @@ -71,35 +96,95 @@ - + + WIN32;_DEBUG;%(PreprocessorDefinitions) Use - true pch.h - $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;%(AdditionalIncludeDirectories);$(RepoRoot)\dev\common - %(PreprocessorDefinitions);INLINE_TEST_METHOD_MARKUP + $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories) Windows + false + onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) + Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) + + + + + WIN32;_DEBUG;%(PreprocessorDefinitions) + Use + pch.h + $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories) + + + Windows + false onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) - Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) + $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) + Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) - + - _DEBUG;%(PreprocessorDefinitions) + WIN32;NDEBUG;%(PreprocessorDefinitions) + Use + pch.h + $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories) + + Windows + false + onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) + $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) + Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) + - + - NDEBUG;%(PreprocessorDefinitions) + WIN32;NDEBUG;%(PreprocessorDefinitions) + Use + pch.h + $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories) + + + Windows + false + onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) + $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) + Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) + + + + + _DEBUG;%(PreprocessorDefinitions) + Use + pch.h + $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories) + + Windows + false + onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) + $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) + Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) + - + - WIN32;%(PreprocessorDefinitions) + NDEBUG;%(PreprocessorDefinitions) + Use + pch.h + $(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\test\inc;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common;%(AdditionalIncludeDirectories) + + Windows + false + onecore.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) + $(OutDir)\..\WindowsAppRuntime_DLL;%(AdditionalLibraryDirectories) + Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs) + @@ -130,7 +215,7 @@ - + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} From 110cda8102629141b561ac20dbcf307165c7f5d1 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 9 Feb 2026 09:30:22 -0800 Subject: [PATCH 20/33] Fixed warnings --- dev/Interop/StoragePickers/PickerCommon.cpp | 4 ++-- .../API/M.W.M.D.PackageDeploymentManager.cpp | 10 +++++----- .../API/PackageTests_PackageGraph_Packaged_CPP.cpp | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index d20a90d365..7f59104fe2 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -181,7 +181,7 @@ namespace PickerCommon { return; } - for (size_t i = 0; i < value.size(); i++) + for (std::uint32_t i = 0; i < value.size(); i++) { if (value[i] == L'\0') { @@ -204,7 +204,7 @@ namespace PickerCommon { PickerLocalization::GetStoragePickersLocalizationText(ImproperFileExtensionLocalizationKey)); } - for (size_t i = 1; i < filter.size(); i++) + for (std::uint32_t i = 1; i < filter.size(); i++) { if (filter[i] == L'.' || filter[i] == L'*' || filter[i] == L'?') { diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp index 6bbdabd248..18833ef4d1 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp @@ -1585,13 +1585,13 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str()); } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::ProvisionPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options) + PackageDeploymentManager::ProvisionPackageByUriAsync(winrt::Windows::Foundation::Uri /*packageUri*/, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions /*options*/) { //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() throw hresult_not_implemented(); } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::ProvisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options) + PackageDeploymentManager::ProvisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet /*packageSet*/, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions /*options*/) { //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() throw hresult_not_implemented(); @@ -1613,13 +1613,13 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str()); } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::DeprovisionPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri) + PackageDeploymentManager::DeprovisionPackageByUriAsync(winrt::Windows::Foundation::Uri /*packageUri*/) { //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() throw hresult_not_implemented(); } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::DeprovisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet) + PackageDeploymentManager::DeprovisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet /*packageSet*/ ) { //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() throw hresult_not_implemented(); @@ -1642,7 +1642,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::AddPackageByAppInstallerFileAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options) + PackageDeploymentManager::AddPackageByAppInstallerFileAsync(winrt::Windows::Foundation::Uri /*packageUri*/, winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions /*options*/) { //TODO add via AddPackageByAppInstallerFileAsync() throw hresult_not_implemented(); diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp index 43d3895dee..145cd5df09 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp @@ -131,7 +131,6 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) { - PCWSTR packageFullName{ Main_PackageFullName }; PCWSTR packageFamilyName{ Main_PackageFamilyName }; wil::unique_package_dependency_context packageDependencyContext{ AddDynamicDependency(packageFamilyName) }; From 996118e5c2194faea4847643036e33899a87a792 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 9 Feb 2026 10:09:13 -0800 Subject: [PATCH 21/33] Fixed warning --- dev/Package/package_runtime.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index 6f1da653e5..bb27f0b507 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -124,7 +124,6 @@ inline bool is_match_for_package_properties( inline std::filesystem::path get_package_file_for_location( PCWSTR packageFullName, _In_ PCWSTR filename, - _In_ GetPackageFilePathOptions options, PackagePathType packagePathType) { std::filesystem::path absoluteFilename; @@ -154,30 +153,30 @@ inline std::filesystem::path get_package_file( if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) { // EffectiveExternal == UserExternal if package/user has one else MachineExternal - path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_EffectiveExternal); + path = get_package_file_for_location(packageFullName, filename, PackagePathType_EffectiveExternal); } else { - path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_UserExternal); + path = get_package_file_for_location(packageFullName, filename, PackagePathType_UserExternal); } } else if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) { - path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_MachineExternal); + path = get_package_file_for_location(packageFullName, filename, PackagePathType_MachineExternal); } if (path.empty()) { // Search Mutable location if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMutablePath)) { - path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_Mutable); + path = get_package_file_for_location(packageFullName, filename, PackagePathType_Mutable); } if (path.empty()) { // Search Install location if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchInstallPath)) { - path = get_package_file_for_location(packageFullName, filename, options, PackagePathType_Install); + path = get_package_file_for_location(packageFullName, filename, PackagePathType_Install); } } } From 653d645ca63e53b1c7d9a1f3923ace9ca1fc9805 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 16 Feb 2026 00:07:54 -0800 Subject: [PATCH 22/33] Fix to dynamically use GetPackagePathByFullName2 if available --- dev/Common/AppModel.Package.h | 62 +++++++++-- dev/Common/Common.vcxitems.filters | 2 +- dev/Common/ExportLoader.h | 43 +++++++- dev/Package/M.W.A.Package.cpp | 29 +++-- dev/Package/M.W.A.Package.h | 1 + dev/Package/Package.idl | 18 ++++ dev/Package/package_runtime.cpp | 102 ++++++++++++++---- dev/Package/package_runtime.h | 18 ++++ .../WindowsAppRuntime.def | 1 + dev/WindowsAppRuntime_DLL/pch.h | 2 + test/Decimal/CS/DecimalTest_CS.csproj | 1 + test/Package/API/PackageTests_Package_CPP.cpp | 70 ++++++++++-- .../API/PackageTests_Package_WinRT.cpp | 69 ++++++++++-- .../AccessControlTestApp.vcxproj | 10 +- 14 files changed, 360 insertions(+), 68 deletions(-) diff --git a/dev/Common/AppModel.Package.h b/dev/Common/AppModel.Package.h index 852cf63649..1570889ba1 100644 --- a/dev/Common/AppModel.Package.h +++ b/dev/Common/AppModel.Package.h @@ -10,6 +10,7 @@ #include #include +#include namespace AppModel::Package { @@ -100,6 +101,53 @@ namespace details return wil::make_unique_string(s); } } + + // GetPackagePathByFullName2 requires >=19H1 + typedef LONG (WINAPI* GetPackagePathByFullName2Function)( + PCWSTR packageFullName, + PackagePathType packagePathType, + UINT32* pathLength, + PWSTR path); + + inline wil::unique_hmodule g_dll_apiset_appmodel_runtime_1_3; + inline GetPackagePathByFullName2Function g_getPackagePathByFullName2{}; + inline std::once_flag g_onceFlag{}; + + inline void initialize() + { + wil::unique_hmodule dll; + if (::ExportLoader::Load(L"api-ms-win-appmodel-runtime-l1-1-3.dll", wil::out_param(dll))) + { + return; + } + if (dll) + { + GetPackagePathByFullName2Function getPackagePathByFullName2{}; + if (FAILED(::ExportLoader::GetFunctionIfExists(dll.get(), "GetPackagePathByFullName2", &getPackagePathByFullName2))) + { + return; + } + if (getPackagePathByFullName2) + { + g_dll_apiset_appmodel_runtime_1_3 = std::move(dll); + g_getPackagePathByFullName2 = std::move(getPackagePathByFullName2); + } + } + } + + /// Get the path for a package, if GetPackagePathByFullName2() is available. + /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 + inline HRESULT GetPackagePathByFullName2IfSupported( + _In_ PCWSTR packageFullName, + PackagePathType packagePathType, + std::uint32_t* pathLength, + _Out_writes_opt_(*pathLength) PWSTR path) + { + std::call_once(g_onceFlag, initialize); + RETURN_HR_IF_NULL(E_NOTIMPL, g_getPackagePathByFullName2); + + return g_getPackagePathByFullName2(packageFullName, packagePathType, pathLength, path); + } } /// Get the path for a package. @@ -111,23 +159,25 @@ inline Tstring GetPath(_In_ PCWSTR packageFullName, PackagePathType packagePathT // as an optimization and fallback to dynamic allocation if need be WCHAR path[MAX_PATH]{}; uint32_t pathLength{ ARRAYSIZE(path) }; - const auto rc{ ::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, path) }; - if (rc == ERROR_SUCCESS) + const auto hr{ details::GetPackagePathByFullName2IfSupported(packageFullName, packagePathType, &pathLength, path) }; + if (SUCCEEDED(hr)) { return details::MakeFromPCWSTR(path); } - else if ((rc == ERROR_NOT_FOUND) || (rc == APPMODEL_ERROR_NO_MUTABLE_DIRECTORY)) + else if ((hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) || + (hr == HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_MUTABLE_DIRECTORY)) || + (hr == E_NOTIMPL)) { return Tstring{}; } - else if (rc != ERROR_INSUFFICIENT_BUFFER) + else if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { - THROW_WIN32(rc); + THROW_HR_MSG(hr, "PackageFullName=%ls PackagePathType=%d", packageFullName ? packageFullName : L"", static_cast(packagePathType)); } // It's bigger than a breadbox. Allocate memory std::unique_ptr pathBuffer{ std::make_unique(pathLength) }; - THROW_IF_WIN32_ERROR_MSG(::GetPackagePathByFullName2(packageFullName, packagePathType, &pathLength, pathBuffer.get()), + THROW_IF_WIN32_ERROR_MSG(details::GetPackagePathByFullName2IfSupported(packageFullName, packagePathType, &pathLength, pathBuffer.get()), "PackageFullName=%ls PackagePathType=%d", packageFullName ? packageFullName : L"", static_cast(packagePathType)); return details::MakeFromPCWSTR(pathBuffer.get()); } diff --git a/dev/Common/Common.vcxitems.filters b/dev/Common/Common.vcxitems.filters index cff6f33620..2bb427f321 100644 --- a/dev/Common/Common.vcxitems.filters +++ b/dev/Common/Common.vcxitems.filters @@ -56,4 +56,4 @@ Source Files - \ No newline at end of file + diff --git a/dev/Common/ExportLoader.h b/dev/Common/ExportLoader.h index 3906d65170..7d9384d732 100644 --- a/dev/Common/ExportLoader.h +++ b/dev/Common/ExportLoader.h @@ -6,6 +6,19 @@ namespace ExportLoader { +inline HRESULT Load(PCWSTR moduleName, _Out_ HMODULE* module) +{ + auto hmodule{ ::LoadLibraryExW(moduleName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) }; + if (!hmodule) + { + const auto rc{ GetLastError() }; + RETURN_HR_IF_MSG(HRESULT_FROM_WIN32(rc), rc != ERROR_MOD_NOT_FOUND, "%ls", moduleName); + RETURN_HR(E_NOTIMPL); + } + *module = hmodule; + return S_OK; +} + inline HMODULE Load(PCWSTR moduleName) { auto hmodule{ ::LoadLibraryExW(moduleName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) }; @@ -19,17 +32,41 @@ inline HMODULE Load(PCWSTR moduleName) } template -inline T GetFunction(HMODULE module, PCSTR functionName) +inline HRESULT GetFunctionIfExists(HMODULE module, PCSTR functionName, _Out_ T* function) +{ + auto fn{ reinterpret_cast(::GetProcAddress(module, functionName)) }; + if (!fn) + { + const auto rc{ GetLastError() }; + RETURN_HR_IF_MSG(HRESULT_FROM_WIN32(rc), rc != ERROR_PROC_NOT_FOUND, "%hs", functionName); + } + *function = fn; + return S_OK; +} + +template +inline T GetFunctionIfExists(HMODULE module, PCSTR functionName) { auto function{ reinterpret_cast(::GetProcAddress(module, functionName)) }; if (!function) { const auto rc{ GetLastError() }; - THROW_HR_IF_MSG(HRESULT_FROM_WIN32(rc), rc != ERROR_PROC_NOT_FOUND, "%hs", functionName); - THROW_HR(E_NOTIMPL); + if (rc == ERROR_PROC_NOT_FOUND) + { + return nullptr; + } + THROW_WIN32_MSG(rc, "%hs", functionName); } return function; } + +template +inline T GetFunction(HMODULE module, PCSTR functionName) +{ + auto function{ GetFunctionIfExists(module, functionName) }; + THROW_HR_IF_NULL_MSG(E_NOTIMPL, function, "%hs", functionName); + return function; +} } #endif // defined(__EXPORTLOADER_H) diff --git a/dev/Package/M.W.A.Package.cpp b/dev/Package/M.W.A.Package.cpp index a455ad54a1..bdcd73ac0e 100644 --- a/dev/Package/M.W.A.Package.cpp +++ b/dev/Package/M.W.A.Package.cpp @@ -12,18 +12,25 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation { - static_assert(static_cast(GetFilePathOptions::None) == static_cast(GetPackageFilePathOptions_None), "GetFilePathOptions::None != FindPackageFileOptions_None"); - static_assert(static_cast(GetFilePathOptions::SearchInstallPath) == static_cast(GetPackageFilePathOptions_SearchInstallPath), "GetFilePathOptions::SearchInstallPath != GetPackageFilePathOptions_SearchInstallPath"); - static_assert(static_cast(GetFilePathOptions::SearchMutablePath) == static_cast(GetPackageFilePathOptions_SearchMutablePath), "GetFilePathOptions::SearchMutablePath != GetPackageFilePathOptions_SearchMutablePath"); - static_assert(static_cast(GetFilePathOptions::SearchMachineExternalPath) == static_cast(GetPackageFilePathOptions_SearchMachineExternalPath), "GetFilePathOptions::SearchMachineExternalPath != GetPackageFilePathOptions_SearchMachineExternalPath"); - static_assert(static_cast(GetFilePathOptions::SearchUserExternalPath) == static_cast(GetPackageFilePathOptions_SearchUserExternalPath), "GetFilePathOptions::SearchUserExternalPath != GetPackageFilePathOptions_SearchUserExternalPath"); - static_assert(static_cast(GetFilePathOptions::SearchMainPackages) == static_cast(GetPackageFilePathOptions_SearchMainPackages), "GetFilePathOptions::SearchMainPackages!= GetPackageFilePathOptions_SearchMainPackages"); - static_assert(static_cast(GetFilePathOptions::SearchFrameworkPackages) == static_cast(GetPackageFilePathOptions_SearchFrameworkPackages), "GetFilePathOptions::SearchFrameworkPackages!= GetPackageFilePathOptions_SearchFrameworkPackages"); - static_assert(static_cast(GetFilePathOptions::SearchOptionalPackages) == static_cast(GetPackageFilePathOptions_SearchOptionalPackages), "GetFilePathOptions::SearchOptionalPackages!= GetPackageFilePathOptions_SearchOptionalPackages"); - static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages"); - static_assert(static_cast(GetFilePathOptions::SearchBundlePackages) == static_cast(GetPackageFilePathOptions_SearchBundlePackages), "GetFilePathOptions::SearchBundlePackages!= GetPackageFilePathOptions_SearchBundlePackages"); - static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies"); + static_assert(static_cast(PackageFeature::PackagePath_Mutable) == static_cast(::PackageFeature_PackagePath_Mutable), "PackageFeature::PackagePath_Mutable != PackageFeature_PackagePath_Mutable"); + static_assert(static_cast(PackageFeature::PackagePath_ExternalLocation) == static_cast(::PackageFeature_PackagePath_ExternalLocation), "PackageFeature::PackagePath_ExternalLocation != PackageFeature_PackagePath_ExternalLocation"); + static_assert(static_cast(GetFilePathOptions::None) == static_cast(::GetPackageFilePathOptions_None), "GetFilePathOptions::None != FindPackageFileOptions_None"); + static_assert(static_cast(GetFilePathOptions::SearchInstallPath) == static_cast(::GetPackageFilePathOptions_SearchInstallPath), "GetFilePathOptions::SearchInstallPath != GetPackageFilePathOptions_SearchInstallPath"); + static_assert(static_cast(GetFilePathOptions::SearchMutablePath) == static_cast(::GetPackageFilePathOptions_SearchMutablePath), "GetFilePathOptions::SearchMutablePath != GetPackageFilePathOptions_SearchMutablePath"); + static_assert(static_cast(GetFilePathOptions::SearchMachineExternalPath) == static_cast(::GetPackageFilePathOptions_SearchMachineExternalPath), "GetFilePathOptions::SearchMachineExternalPath != GetPackageFilePathOptions_SearchMachineExternalPath"); + static_assert(static_cast(GetFilePathOptions::SearchUserExternalPath) == static_cast(::GetPackageFilePathOptions_SearchUserExternalPath), "GetFilePathOptions::SearchUserExternalPath != GetPackageFilePathOptions_SearchUserExternalPath"); + static_assert(static_cast(GetFilePathOptions::SearchMainPackages) == static_cast(::GetPackageFilePathOptions_SearchMainPackages), "GetFilePathOptions::SearchMainPackages!= GetPackageFilePathOptions_SearchMainPackages"); + static_assert(static_cast(GetFilePathOptions::SearchFrameworkPackages) == static_cast(::GetPackageFilePathOptions_SearchFrameworkPackages), "GetFilePathOptions::SearchFrameworkPackages!= GetPackageFilePathOptions_SearchFrameworkPackages"); + static_assert(static_cast(GetFilePathOptions::SearchOptionalPackages) == static_cast(::GetPackageFilePathOptions_SearchOptionalPackages), "GetFilePathOptions::SearchOptionalPackages!= GetPackageFilePathOptions_SearchOptionalPackages"); + static_assert(static_cast(GetFilePathOptions::SearchResourcePackages) == static_cast(::GetPackageFilePathOptions_SearchResourcePackages), "GetFilePathOptions::SearchResourcePackages!= GetPackageFilePathOptions_SearchResourcePackages"); + static_assert(static_cast(GetFilePathOptions::SearchBundlePackages) == static_cast(::GetPackageFilePathOptions_SearchBundlePackages), "GetFilePathOptions::SearchBundlePackages!= GetPackageFilePathOptions_SearchBundlePackages"); + static_assert(static_cast(GetFilePathOptions::SearchHostRuntimeDependencies) == static_cast(::GetPackageFilePathOptions_SearchHostRuntimeDependencies), "GetFilePathOptions::SearchHostRuntimeDependencies!= GetPackageFilePathOptions_SearchHostRuntimeDependencies"); + + bool Package::IsFeatureSupported(winrt::Microsoft::Windows::ApplicationModel::PackageFeature const& feature) + { + return ::IsPackageFeatureSupported(static_cast<::PackageFeature>(feature)); + } hstring Package::GetFilePath(hstring const& filename) { return GetFilePath(filename, winrt::hstring{}); diff --git a/dev/Package/M.W.A.Package.h b/dev/Package/M.W.A.Package.h index 3048b231a7..9fea38fc08 100644 --- a/dev/Package/M.W.A.Package.h +++ b/dev/Package/M.W.A.Package.h @@ -11,6 +11,7 @@ namespace winrt::Microsoft::Windows::ApplicationModel::implementation { Package() = default; + static bool IsFeatureSupported(winrt::Microsoft::Windows::ApplicationModel::PackageFeature const& feature); static hstring GetFilePath(hstring const& filename); static hstring GetFilePath(hstring const& filename, hstring const& packageFullName); static hstring GetFilePath(hstring const& filename, hstring const& packageFullName, winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions const& options); diff --git a/dev/Package/Package.idl b/dev/Package/Package.idl index edecd47b6d..76af5835e3 100644 --- a/dev/Package/Package.idl +++ b/dev/Package/Package.idl @@ -8,6 +8,21 @@ namespace Microsoft.Windows.ApplicationModel [contractversion(1)] apicontract PackageRuntimeContract{}; + /// Features can be queried if currently available/enabled. + /// @see Package.IsPackageFeatureSupported() + [contract(PackageRuntimeContract, 1)] + enum PackageFeature + { + /// Package Mutable path. + /// @see PackagePathType_Mutable + PackagePath_Mutable = 1, + + /// Package ExternalLocation path. + /// @see PackagePathType_MachineExternal + /// @see PackagePathType_UserExternal + PackagePath_ExternalLocation = 2, + }; + /// Options for GetFilePath*() /// @see Package.GetFilePath /// @see PackageGraph.GetFilePath @@ -84,6 +99,9 @@ namespace Microsoft.Windows.ApplicationModel [contract(PackageRuntimeContract, 1)] runtimeclass Package { + /// Return true if feature is supported on the current system. + static Boolean IsFeatureSupported(PackageFeature feature); + /// Return the absolute path to the file in the current process' package. This uses the /// current process' package identity, or fails with HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE) /// if the process lacks package identity. diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index bb27f0b507..5d0ff63174 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -7,6 +7,20 @@ namespace appmodel { +static bool IsPathSupported_Mutable() +{ + // Cache the answer on first query + static bool s_isSupported{ !!::IsPackageFeatureSupported(PackageFeature_PackagePath_Mutable) }; + return s_isSupported; +} + +static bool IsPathSupported_ExternalLocation() +{ + // Cache the answer on first query + static bool s_isSupported{ !!::IsPackageFeatureSupported(PackageFeature_PackagePath_ExternalLocation) }; + return s_isSupported; +} + inline GetPackageFilePathOptions package_properties_to_options( std::uint32_t packageInfoFlags) { @@ -148,26 +162,29 @@ inline std::filesystem::path get_package_file( { // Search External location std::filesystem::path path; - if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchUserExternalPath)) + if (IsPathSupported_ExternalLocation()) { - if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) + if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchUserExternalPath)) { - // EffectiveExternal == UserExternal if package/user has one else MachineExternal - path = get_package_file_for_location(packageFullName, filename, PackagePathType_EffectiveExternal); + if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) + { + // EffectiveExternal == UserExternal if package/user has one else MachineExternal + path = get_package_file_for_location(packageFullName, filename, PackagePathType_EffectiveExternal); + } + else + { + path = get_package_file_for_location(packageFullName, filename, PackagePathType_UserExternal); + } } - else + else if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) { - path = get_package_file_for_location(packageFullName, filename, PackagePathType_UserExternal); + path = get_package_file_for_location(packageFullName, filename, PackagePathType_MachineExternal); } } - else if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMachineExternalPath)) - { - path = get_package_file_for_location(packageFullName, filename, PackagePathType_MachineExternal); - } if (path.empty()) { // Search Mutable location - if (WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMutablePath)) + if (IsPathSupported_Mutable() && WI_IsFlagSet(options, GetPackageFilePathOptions_SearchMutablePath)) { path = get_package_file_for_location(packageFullName, filename, PackagePathType_Mutable); } @@ -205,16 +222,38 @@ inline GetPackageFilePathOptions ToEffectiveOptions( // If options == None then use default behavior (search everything) if (options == GetPackageFilePathOptions_None) { - return GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchMutablePath | - GetPackageFilePathOptions_SearchMachineExternalPath | - GetPackageFilePathOptions_SearchUserExternalPath | - GetPackageFilePathOptions_SearchMainPackages | - GetPackageFilePathOptions_SearchFrameworkPackages | - GetPackageFilePathOptions_SearchOptionalPackages | - GetPackageFilePathOptions_SearchResourcePackages | - GetPackageFilePathOptions_SearchBundlePackages | - GetPackageFilePathOptions_SearchHostRuntimeDependencies; + // 'All' locations supported by the current system is one of... + // * Install + // * Install | Mutable + // * Install | Mutable | ExternalLocation + constexpr auto nonLocationOptions{ + GetPackageFilePathOptions_SearchMainPackages | + GetPackageFilePathOptions_SearchFrameworkPackages | + GetPackageFilePathOptions_SearchOptionalPackages | + GetPackageFilePathOptions_SearchResourcePackages | + GetPackageFilePathOptions_SearchBundlePackages | + GetPackageFilePathOptions_SearchHostRuntimeDependencies + }; + if (IsPathSupported_ExternalLocation()) + { + return GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchMutablePath | + GetPackageFilePathOptions_SearchMachineExternalPath | + GetPackageFilePathOptions_SearchUserExternalPath | + nonLocationOptions; + } + else if (IsPathSupported_Mutable()) + { + return GetPackageFilePathOptions_SearchInstallPath | + GetPackageFilePathOptions_SearchMutablePath | + nonLocationOptions; + } + else + { + return GetPackageFilePathOptions_SearchInstallPath | + nonLocationOptions; + GetPackageFilePathOptions_SearchHostRuntimeDependencies; + } } // If Search*Dependencies are all clear then search them all @@ -238,6 +277,27 @@ inline GetPackageFilePathOptions ToEffectiveOptions( } } +STDAPI_(BOOL) IsPackageFeatureSupported( + PackageFeature feature) noexcept +{ + switch (feature) + { + case PackageFeature_PackagePath_Mutable: + { + // Supported on Windows >= 19H1 + return ::WindowsVersion::IsWindows10_19H1OrGreater() ? TRUE : FALSE; + } + case PackageFeature_PackagePath_ExternalLocation: + { + // Supported on Windows >= VB (20H1) + return ::WindowsVersion::IsWindows10_20H1OrGreater() ? TRUE : FALSE; + } + } + + std::ignore = LOG_HR_MSG(E_INVALIDARG, "PackageFeature:%d", static_cast(feature)); + return FALSE; +} + STDAPI GetPackageFilePath( PCWSTR packageFullName, _In_ PCWSTR filename, diff --git a/dev/Package/package_runtime.h b/dev/Package/package_runtime.h index 633ce37fac..535e2909d6 100644 --- a/dev/Package/package_runtime.h +++ b/dev/Package/package_runtime.h @@ -4,6 +4,24 @@ #if !defined(PACKAGE_RUNTIME_H) #define PACKAGE_RUNTIME_H +/// Features can be queried if currently available/enabled. +/// @see IsPackageFeatureSupported() +typedef enum PackageFeature +{ + /// Package Mutable path. + /// @see PackagePathType_Mutable + PackageFeature_PackagePath_Mutable = 1, + + /// Package External Location path (MachineExternal + UserExternal) + /// @see PackagePathType_MachineExternal + /// @see PackagePathType_UserExternal + PackageFeature_PackagePath_ExternalLocation = 2, +} PackageFeature; + +/// Return TRUE if feature is supported on the current system. +STDAPI_(BOOL) IsPackageFeatureSupported( + PackageFeature feature) noexcept; + /// Options for GetPackageFilePath*() functions typedef enum GetPackageFilePathOptions { diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def index 582b0f5e39..82944a5660 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def @@ -32,3 +32,4 @@ EXPORTS GetPackageFilePath GetPackageFilePathInPackageGraph + IsPackageFeatureSupported diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index 95fa5ae234..65b5886ba2 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -56,6 +56,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/test/Decimal/CS/DecimalTest_CS.csproj b/test/Decimal/CS/DecimalTest_CS.csproj index d67992768a..5f631ad762 100644 --- a/test/Decimal/CS/DecimalTest_CS.csproj +++ b/test/Decimal/CS/DecimalTest_CS.csproj @@ -3,6 +3,7 @@ Exe net6.0-windows10.0.19041.0 + 10.0.19041.0 x86;x64;arm64 disable disable diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index d8ad9369bc..a68f9020d9 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -28,18 +28,42 @@ namespace Test::Package::Tests TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") END_TEST_CLASS() + private: + bool IsMutableLocationSupported() const + { + return !!::IsPackageFeatureSupported(PackageFeature_PackagePath_Mutable); + } + + bool IsExternalLocationSupported() const + { + return !!::IsPackageFeatureSupported(PackageFeature_PackagePath_ExternalLocation); + } + + public: TEST_CLASS_SETUP(ClassSetup) { ::TB::Setup(); - RemovePackage_MachineExternal(); - RemovePackage_UserExternal(); - RemovePackage_Mutable(); - - AddPackage_Mutable(); - AddPackage_UserExternal(); - StagePackage_MachineExternal(); - AddPackage_MachineExternal(); + if (IsExternalLocationSupported()) + { + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + } + if (IsMutableLocationSupported()) + { + RemovePackage_Mutable(); + } + + if (IsMutableLocationSupported()) + { + AddPackage_Mutable(); + } + if (IsExternalLocationSupported()) + { + AddPackage_UserExternal(); + StagePackage_MachineExternal(); + AddPackage_MachineExternal(); + } return true; } @@ -48,9 +72,15 @@ namespace Test::Package::Tests { ::TB::Cleanup(); - RemovePackage_MachineExternal(); - RemovePackage_UserExternal(); - RemovePackage_Mutable(); + if (IsExternalLocationSupported()) + { + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + } + if (IsMutableLocationSupported()) + { + RemovePackage_Mutable(); + } return true; } @@ -108,6 +138,12 @@ namespace Test::Package::Tests TEST_METHOD(GetPackageFilePath_MutablePath) { + if (!IsMutableLocationSupported()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Mutable location is not supported on this system. Skipping test"); + return; + } + PCWSTR packageFullName{ Mutable_PackageFullName }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchMutablePath }; @@ -122,6 +158,12 @@ namespace Test::Package::Tests TEST_METHOD(GetPackageFilePath_MachineExternalPath) { + if (!IsExternalLocationSupported()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ExternalLocation is not supported on this system. Skipping test"); + return; + } + PCWSTR packageFullName{ MachineExternal_PackageFullName }; PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath }; @@ -136,6 +178,12 @@ namespace Test::Package::Tests TEST_METHOD(GetPackageFilePath_UserExternalPath) { + if (!IsExternalLocationSupported()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ExternalLocation is not supported on this system. Skipping test"); + return; + } + PCWSTR packageFullName{ UserExternal_PackageFullName }; PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchUserExternalPath }; diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp index c33e71ad7f..9e6845393b 100644 --- a/test/Package/API/PackageTests_Package_WinRT.cpp +++ b/test/Package/API/PackageTests_Package_WinRT.cpp @@ -28,18 +28,43 @@ namespace Test::Package::Tests TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") END_TEST_CLASS() + private: + bool IsMutableLocationSupported() const + { + return winrt::Microsoft::Windows::ApplicationModel::Package::IsFeatureSupported(winrt::Microsoft::Windows::ApplicationModel::PackageFeature::PackagePath_Mutable); + } + + bool IsExternalLocationSupported() const + { + return winrt::Microsoft::Windows::ApplicationModel::Package::IsFeatureSupported(winrt::Microsoft::Windows::ApplicationModel::PackageFeature::PackagePath_ExternalLocation); + } + + + public: TEST_CLASS_SETUP(ClassSetup) { ::TB::Setup(); - RemovePackage_MachineExternal(); - RemovePackage_UserExternal(); - RemovePackage_Mutable(); + if (IsExternalLocationSupported()) + { + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + } + if (IsMutableLocationSupported()) + { + RemovePackage_Mutable(); + } - AddPackage_Mutable(); - AddPackage_UserExternal(); - StagePackage_MachineExternal(); - AddPackage_MachineExternal(); + if (IsMutableLocationSupported()) + { + AddPackage_Mutable(); + } + if (IsExternalLocationSupported()) + { + AddPackage_UserExternal(); + StagePackage_MachineExternal(); + AddPackage_MachineExternal(); + } return true; } @@ -48,9 +73,15 @@ namespace Test::Package::Tests { ::TB::Cleanup(); - RemovePackage_MachineExternal(); - RemovePackage_UserExternal(); - RemovePackage_Mutable(); + if (IsExternalLocationSupported()) + { + RemovePackage_MachineExternal(); + RemovePackage_UserExternal(); + } + if (IsMutableLocationSupported()) + { + RemovePackage_Mutable(); + } return true; } @@ -143,6 +174,12 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_MutablePath) { + if (!IsMutableLocationSupported()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Mutable location is not supported on this system. Skipping test"); + return; + } + winrt::hstring packageFullName{ Mutable_PackageFullName }; winrt::hstring fileName{ L"AppxManifest.xml" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath }; @@ -156,6 +193,12 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_MachineExternalPath) { + if (!IsExternalLocationSupported()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ExternalLocation is not supported on this system. Skipping test"); + return; + } + winrt::hstring packageFullName{ MachineExternal_PackageFullName }; winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath }; @@ -169,6 +212,12 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_UserExternalPath) { + if (!IsExternalLocationSupported()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ExternalLocation is not supported on this system. Skipping test"); + return; + } + winrt::hstring packageFullName{ UserExternal_PackageFullName }; winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath }; diff --git a/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj b/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj index 2dfd8b9445..1273112adb 100644 --- a/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj +++ b/test/TestApps/AccessControlTestApp/AccessControlTestApp.vcxproj @@ -42,9 +42,9 @@ - $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Security.AccessControl.winmd + $(OutDir)..\WindowsAppRuntime_DLL\Microsoft.Windows.Security.AccessControl.winmd true - $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll + $(OutDir)..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll @@ -126,11 +126,11 @@ Use pch.h - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\test\inc;$(RepoRoot)\dev\common + %(AdditionalIncludeDirectories);$(OutDir)..\WindowsAppRuntime_DLL;$(OutDir)..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\test\inc;$(RepoRoot)\dev\common Console - %(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL + %(AdditionalLibraryDirectories);$(OutDir)..\WindowsAppRuntime_DLL onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies) Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs) @@ -166,6 +166,6 @@ - + From d90ca7d52b494afb4f3674cf6eb9dd45d94f3c2b Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Wed, 18 Mar 2026 10:41:20 -0700 Subject: [PATCH 23/33] Can't use RuntimeBehavior/TrustLevel on old pre-20H1 systems. Switched to classic EntryPoint=windows.fullTrustApplication via UUAP:AppXManifest=PackagedCwaFullTrust --- test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp | 3 +-- test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp index 145cd5df09..4275843b56 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp @@ -22,8 +22,7 @@ namespace Test::Package::Tests BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_CPP) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") TEST_CLASS_PROPERTY(L"RunAs", L"UAP") - TEST_METHOD_PROPERTY(L"UAP:RuntimeBehavior", L"PackagedClassicApp") - TEST_METHOD_PROPERTY(L"UAP:TrustLevel", L"MediumIL") + TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust") END_TEST_CLASS() TEST_CLASS_SETUP(ClassSetup) diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp index 8ba918976a..d3ea76337f 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp @@ -22,8 +22,7 @@ namespace Test::Package::Tests BEGIN_TEST_CLASS(PackageTests_PackageGraph_Packaged_WinRT) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") TEST_CLASS_PROPERTY(L"RunAs", L"UAP") - TEST_METHOD_PROPERTY(L"UAP:RuntimeBehavior", L"PackagedClassicApp") - TEST_METHOD_PROPERTY(L"UAP:TrustLevel", L"MediumIL") + TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"PackagedCwaFullTrust") END_TEST_CLASS() TEST_CLASS_SETUP(ClassSetup) From 6d2de6a2a7311d644f0ce070b0a1625ac1c4caa3 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 21 Mar 2026 02:17:48 -0700 Subject: [PATCH 24/33] Fixed Decimal test --- test/Decimal/CPP/DecimalTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Decimal/CPP/DecimalTests.cpp b/test/Decimal/CPP/DecimalTests.cpp index 780c8e7846..6087a3d71a 100644 --- a/test/Decimal/CPP/DecimalTests.cpp +++ b/test/Decimal/CPP/DecimalTests.cpp @@ -137,7 +137,7 @@ namespace Test::Decimal::Tests TEST_CLASS_SETUP(ClassSetup) { ::TD::DumpExecutionContext(); - ::TB::Setup(TB::Packages::Framework); + ::TB::Setup(); return true; } From 31b010e9c925ea587bf353ca90be16f7aa2a5ea0 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 21 Mar 2026 02:21:38 -0700 Subject: [PATCH 25/33] Fix other decimal test --- test/Decimal/WinRT/DecimalTest_WinRT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Decimal/WinRT/DecimalTest_WinRT.cpp b/test/Decimal/WinRT/DecimalTest_WinRT.cpp index ce3fe4992f..7d63f41c96 100644 --- a/test/Decimal/WinRT/DecimalTest_WinRT.cpp +++ b/test/Decimal/WinRT/DecimalTest_WinRT.cpp @@ -80,7 +80,7 @@ namespace Test::DecimalValue::Tests TEST_CLASS_SETUP(ClassSetup) { ::TD::DumpExecutionContext(); - ::TB::Setup(TB::Packages::Framework); + ::TB::Setup(); return true; } From 4a08b7cd2f014718c75087035f13e92ede650f98 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sat, 21 Mar 2026 12:44:24 -0700 Subject: [PATCH 26/33] Fixed GetPackagePathByFullName2IfSupported to work on RS5 --- dev/Common/AppModel.Package.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/dev/Common/AppModel.Package.h b/dev/Common/AppModel.Package.h index 1570889ba1..aa3571eac9 100644 --- a/dev/Common/AppModel.Package.h +++ b/dev/Common/AppModel.Package.h @@ -143,10 +143,19 @@ namespace details std::uint32_t* pathLength, _Out_writes_opt_(*pathLength) PWSTR path) { - std::call_once(g_onceFlag, initialize); - RETURN_HR_IF_NULL(E_NOTIMPL, g_getPackagePathByFullName2); + // GetPackagePathByFullName2 first appeared in 20H1. Handle older systems + if (packagePathType == PackagePathType_Install) + { + RETURN_IF_FAILED(GetPackagePathByFullName(packageFullName, pathLength, path)); + } + else + { + std::call_once(g_onceFlag, initialize); + RETURN_HR_IF_NULL(E_NOTIMPL, g_getPackagePathByFullName2); - return g_getPackagePathByFullName2(packageFullName, packagePathType, pathLength, path); + RETURN_IF_FAILED(g_getPackagePathByFullName2(packageFullName, packagePathType, pathLength, path)); + } + return S_OK; } } From c302562951b07679558a37e48f444f14586025f8 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 22 Mar 2026 16:22:20 -0700 Subject: [PATCH 27/33] Fix tests --- ...PackageTests_PackageGraph_Packaged_CPP.cpp | 2 +- ...ckageTests_PackageGraph_Packaged_WinRT.cpp | 2 +- test/Package/API/PackageTests_Package_CPP.cpp | 48 +++++++++---------- .../API/PackageTests_Package_WinRT.cpp | 48 +++++++++---------- 4 files changed, 48 insertions(+), 52 deletions(-) diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp index 4275843b56..c6143e9bd7 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp @@ -28,7 +28,7 @@ namespace Test::Package::Tests TEST_CLASS_SETUP(ClassSetup) { // Windows App SDK's Dynamic Dependency API doesn't support packaged processes - // Ue the OS Dynamic Dependency API (if available) + // Use the OS Dynamic Dependency API (if available) if (!::WindowsVersion::IsWindows11_24H2OrGreater()) { WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp index d3ea76337f..c1b68d520e 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp @@ -28,7 +28,7 @@ namespace Test::Package::Tests TEST_CLASS_SETUP(ClassSetup) { // Windows App SDK's Dynamic Dependency API doesn't support packaged processes - // Ue the OS Dynamic Dependency API (if available) + // Use the OS Dynamic Dependency API (if available) if (!::WindowsVersion::IsWindows11_24H2OrGreater()) { WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageGraph tests require >= 24H2. Skipping tests"); diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index a68f9020d9..f19963840a 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -119,7 +119,8 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + const std::filesystem::path actual{ !absoluteFilename ? L"" : absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetPackageFilePath_InstallPath) @@ -138,12 +139,6 @@ namespace Test::Package::Tests TEST_METHOD(GetPackageFilePath_MutablePath) { - if (!IsMutableLocationSupported()) - { - WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Mutable location is not supported on this system. Skipping test"); - return; - } - PCWSTR packageFullName{ Mutable_PackageFullName }; PCWSTR fileName{ L"AppxManifest.xml" }; const auto options{ GetPackageFilePathOptions_SearchMutablePath }; @@ -152,18 +147,17 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + const std::filesystem::path expected; + if (IsMutableLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetPackageFilePath_MachineExternalPath) { - if (!IsExternalLocationSupported()) - { - WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ExternalLocation is not supported on this system. Skipping test"); - return; - } - PCWSTR packageFullName{ MachineExternal_PackageFullName }; PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath }; @@ -172,18 +166,17 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + const std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetPackageFilePath_UserExternalPath) { - if (!IsExternalLocationSupported()) - { - WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ExternalLocation is not supported on this system. Skipping test"); - return; - } - PCWSTR packageFullName{ UserExternal_PackageFullName }; PCWSTR fileName{ L"Shadow.cat" }; const auto options{ GetPackageFilePathOptions_SearchUserExternalPath }; @@ -192,8 +185,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + const std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp index 9e6845393b..42e1a448fc 100644 --- a/test/Package/API/PackageTests_Package_WinRT.cpp +++ b/test/Package/API/PackageTests_Package_WinRT.cpp @@ -156,7 +156,8 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_InstallPath) @@ -174,12 +175,6 @@ namespace Test::Package::Tests TEST_METHOD(GetFilePath_MutablePath) { - if (!IsMutableLocationSupported()) - { - WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Mutable location is not supported on this system. Skipping test"); - return; - } - winrt::hstring packageFullName{ Mutable_PackageFullName }; winrt::hstring fileName{ L"AppxManifest.xml" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath }; @@ -187,18 +182,17 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsMutableLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetFilePath_MachineExternalPath) { - if (!IsExternalLocationSupported()) - { - WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ExternalLocation is not supported on this system. Skipping test"); - return; - } - winrt::hstring packageFullName{ MachineExternal_PackageFullName }; winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath }; @@ -206,18 +200,17 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetFilePath_UserExternalPath) { - if (!IsExternalLocationSupported()) - { - WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"ExternalLocation is not supported on this system. Skipping test"); - return; - } - winrt::hstring packageFullName{ UserExternal_PackageFullName }; winrt::hstring fileName{ L"Shadow.cat" }; const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath }; @@ -225,8 +218,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) From 9d2b65782032ea8b7d2788c73a80e0337f98e570 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 22 Mar 2026 16:57:02 -0700 Subject: [PATCH 28/33] Test fixes --- test/Package/API/PackageTests.Packages.h | 11 ++++++ test/Package/API/PackageTests_CPP.cpp | 34 +++++++++++++----- ...PackageTests_PackageGraph_Packaged_CPP.cpp | 34 +++++++++++++----- ...ckageTests_PackageGraph_Packaged_WinRT.cpp | 34 +++++++++++++----- ...ckageTests_PackageGraph_Unpackaged_CPP.cpp | 34 +++++++++++++----- ...ageTests_PackageGraph_Unpackaged_WinRT.cpp | 34 +++++++++++++----- test/Package/API/PackageTests_Package_CPP.cpp | 35 +++++++----------- .../API/PackageTests_Package_WinRT.cpp | 10 +++--- test/Package/API/PackageTests_WinRT.cpp | 36 +++++++++++++------ test/Package/API/pch.h | 1 + 10 files changed, 187 insertions(+), 76 deletions(-) diff --git a/test/Package/API/PackageTests.Packages.h b/test/Package/API/PackageTests.Packages.h index 5f72cc532d..082c54a073 100644 --- a/test/Package/API/PackageTests.Packages.h +++ b/test/Package/API/PackageTests.Packages.h @@ -48,6 +48,17 @@ namespace Test::Package::Tests { namespace TP = ::Test::Packages; + inline bool IsMutableLocationSupported() + { + return !!::IsPackageFeatureSupported(PackageFeature_PackagePath_Mutable); + } + + inline bool IsExternalLocationSupported() + { + return !!::IsPackageFeatureSupported(PackageFeature_PackagePath_ExternalLocation); + } + + inline bool IsPackageRegistered_Framework() { return TP::IsPackageRegistered(TP::Framework::c_packageFullName); diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp index f3ba0f2c54..71b78cead6 100644 --- a/test/Package/API/PackageTests_CPP.cpp +++ b/test/Package/API/PackageTests_CPP.cpp @@ -93,8 +93,11 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + // GetPackageFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges + // with Mutable or External locations so we'll resolve the Install path + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetPackageFilePath_InstallPath) @@ -121,8 +124,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + const std::filesystem::path expected; + if (IsMutableLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetPackageFilePath_MachineExternalPath) @@ -135,8 +143,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + const std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetPackageFilePath_UserExternalPath) @@ -149,8 +162,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp index c6143e9bd7..1137839abd 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_CPP.cpp @@ -56,8 +56,11 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges + // with Mutable or External locations so we'll resolve the Install path + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_InstallPath) @@ -90,8 +93,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + std::filesystem::path expected; + if (IsMutableLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_MachineExternalPath) @@ -107,8 +115,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_UserExternalPath) @@ -124,8 +137,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp index c1b68d520e..8cf75c2ad0 100644 --- a/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Packaged_WinRT.cpp @@ -80,8 +80,11 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges + // with Mutable or External locations so we'll resolve the Install path + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_InstallPath) @@ -112,8 +115,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsMutableLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_MachineExternalPath) @@ -128,8 +136,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_UserExternalPath) @@ -144,8 +157,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp index 5af7021a92..df13bb7126 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_CPP.cpp @@ -64,8 +64,11 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges + // with Mutable or External locations so we'll resolve the Install path + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_InstallPath) @@ -98,8 +101,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + std::filesystem::path expected; + if (IsMutableLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_MachineExternalPath) @@ -115,8 +123,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_UserExternalPath) @@ -132,8 +145,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), absoluteFilename.get())); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal); + } + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp index 73ce586327..c1e5695b52 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp @@ -77,8 +77,11 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges + // with Mutable or External locations so we'll resolve the Install path + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_InstallPath) @@ -109,8 +112,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsMutableLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_MachineExternalPath) @@ -125,8 +133,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_UserExternalPath) @@ -141,8 +154,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index f19963840a..12bb74ae63 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -28,17 +28,6 @@ namespace Test::Package::Tests TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") END_TEST_CLASS() - private: - bool IsMutableLocationSupported() const - { - return !!::IsPackageFeatureSupported(PackageFeature_PackagePath_Mutable); - } - - bool IsExternalLocationSupported() const - { - return !!::IsPackageFeatureSupported(PackageFeature_PackagePath_ExternalLocation); - } - public: TEST_CLASS_SETUP(ClassSetup) { @@ -118,9 +107,11 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Effective) }; + // GetPackageFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges + // with Mutable or External locations so we'll resolve the Install path + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; const std::filesystem::path actual{ !absoluteFilename ? L"" : absoluteFilename.get() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetPackageFilePath_InstallPath) @@ -147,13 +138,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected; + std::filesystem::path expected; if (IsMutableLocationSupported()) { expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable); } - const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetPackageFilePath_MachineExternalPath) @@ -166,13 +157,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected; + std::filesystem::path expected; if (IsExternalLocationSupported()) { expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal); } - const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetPackageFilePath_UserExternalPath) @@ -185,13 +176,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected; + std::filesystem::path expected; if (IsExternalLocationSupported()) { expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal); } - const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); + const std::filesystem::path actual{ absoluteFilename.get() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp index 42e1a448fc..9e44d0a5eb 100644 --- a/test/Package/API/PackageTests_Package_WinRT.cpp +++ b/test/Package/API/PackageTests_Package_WinRT.cpp @@ -155,7 +155,9 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; + // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges + // with Mutable or External locations so we'll resolve the Install path + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; const std::filesystem::path actual{ absoluteFilename.c_str() }; VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } @@ -188,7 +190,7 @@ namespace Test::Package::Tests expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable); } const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_MachineExternalPath) @@ -206,7 +208,7 @@ namespace Test::Package::Tests expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); } const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_UserExternalPath) @@ -224,7 +226,7 @@ namespace Test::Package::Tests expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal); } const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index 845cc4f775..0a14c5b565 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -30,13 +30,11 @@ namespace Test::Package::Tests { ::TB::Setup(); - //RemovePackage_MachineExternal(); RemovePackage_UserExternal(); RemovePackage_Mutable(); AddPackage_Mutable(); AddPackage_UserExternal(); - //AddPackage_MachineExternal(); return true; } @@ -121,8 +119,11 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Effective) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges + // with Mutable or External locations so we'll resolve the Install path + const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str())); } TEST_METHOD(GetFilePath_InstallPath) @@ -147,8 +148,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + const std::filesystem::path expected; + if (IsMutableLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetFilePath_MachineExternalPath) @@ -160,8 +166,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetFilePath_UserExternalPath) @@ -173,8 +184,13 @@ namespace Test::Package::Tests WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); + std::filesystem::path expected; + if (IsExternalLocationSupported()) + { + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal); + } + const std::filesystem::path actual{ absoluteFilename.c_str() }; + VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); } TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) diff --git a/test/Package/API/pch.h b/test/Package/API/pch.h index fcd644fd66..8c49dacc88 100644 --- a/test/Package/API/pch.h +++ b/test/Package/API/pch.h @@ -10,6 +10,7 @@ #include #include +#include #include #include From 3459eaca3499cc800d796f699f9b90cb2f25a8cd Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Sun, 22 Mar 2026 16:58:13 -0700 Subject: [PATCH 29/33] Fixed typo --- test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp index c1e5695b52..2906fbec3b 100644 --- a/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp +++ b/test/Package/API/PackageTests_PackageGraph_Unpackaged_WinRT.cpp @@ -157,7 +157,7 @@ namespace Test::Package::Tests std::filesystem::path expected; if (IsExternalLocationSupported()) { - expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); + expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal); } const std::filesystem::path actual{ absoluteFilename.c_str() }; VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); From 475784cd970f2bc47a7cdbe32cff2948c5013f30 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 23 Mar 2026 21:14:07 -0700 Subject: [PATCH 30/33] Fix downlevel support --- dev/Common/AppModel.Package.h | 48 ++++++++++++++++++++++++++++----- dev/Package/package_runtime.cpp | 19 ++++++++++--- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/dev/Common/AppModel.Package.h b/dev/Common/AppModel.Package.h index aa3571eac9..b3a3304c88 100644 --- a/dev/Common/AppModel.Package.h +++ b/dev/Common/AppModel.Package.h @@ -11,6 +11,7 @@ #include #include +#include namespace AppModel::Package { @@ -136,6 +137,7 @@ namespace details } /// Get the path for a package, if GetPackagePathByFullName2() is available. + /// Return an empty path if the PackagePathType isn't supported on current platform (*pathLength=0, *path=""). /// @see https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-getpackagepathbyfullname2 inline HRESULT GetPackagePathByFullName2IfSupported( _In_ PCWSTR packageFullName, @@ -143,18 +145,43 @@ namespace details std::uint32_t* pathLength, _Out_writes_opt_(*pathLength) PWSTR path) { - // GetPackagePathByFullName2 first appeared in 20H1. Handle older systems - if (packagePathType == PackagePathType_Install) - { - RETURN_IF_FAILED(GetPackagePathByFullName(packageFullName, pathLength, path)); - } - else + // Availability is a matter of timeline: + // * PackagePathType_Install is available since Win8 + // * PackagePathType_Mutable is available since 19H1 + // * PackagePathType_Effective is available since 19H1 + // * PackagePathType_MachineExternalLocation is available since 20H1 + // * PackagePathType_UserExternalLocation is available since 20H1 + // * PackagePathType_EffectiveExternalLocation is available since 20H1 + // GetPackagePathByFullName() is available since Win8 + // GetPackagePathByFullName2() is available since 19H1 (though not all PackagePathType values were supported that early) + // + // Treat asks for locations not supported by the current system the same as not-found + + if (::WindowsVersion::IsWindows10_20H1OrGreater() || + (::WindowsVersion::IsWindows10_19H1OrGreater() && + ((packagePathType == PackagePathType_Install) || (packagePathType == PackagePathType_Mutable) || (packagePathType == PackagePathType_Effective)))) { std::call_once(g_onceFlag, initialize); RETURN_HR_IF_NULL(E_NOTIMPL, g_getPackagePathByFullName2); RETURN_IF_FAILED(g_getPackagePathByFullName2(packageFullName, packagePathType, pathLength, path)); } + else if ((packagePathType == PackagePathType_Install) || (packagePathType == PackagePathType_Effective)) + { + // Only Install location is supported by the current system + // Effective is thus equivalent to Install + // Either way, rock it old school... + RETURN_IF_FAILED(::GetPackagePathByFullName(packageFullName, pathLength, path)); + } + else + { + // The requested location isn't possible on the current system + if (path && (*pathLength > 0)) + { + *path = L'\0'; + } + *pathLength = 0; + } return S_OK; } } @@ -171,7 +198,14 @@ inline Tstring GetPath(_In_ PCWSTR packageFullName, PackagePathType packagePathT const auto hr{ details::GetPackagePathByFullName2IfSupported(packageFullName, packagePathType, &pathLength, path) }; if (SUCCEEDED(hr)) { - return details::MakeFromPCWSTR(path); + if (pathLength > 0) + { + return details::MakeFromPCWSTR(path); + } + else + { + return Tstring{}; + } } else if ((hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) || (hr == HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_MUTABLE_DIRECTORY)) || diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index 5d0ff63174..3013f86c22 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -140,12 +140,23 @@ inline std::filesystem::path get_package_file_for_location( _In_ PCWSTR filename, PackagePathType packagePathType) { - std::filesystem::path absoluteFilename; - - auto packagePath{ ::AppModel::Package::GetPath(packageFullName, packagePathType) }; + // Availability is a matter of timeline: + // * PackagePathType_Install is available since Win8 + // * PackagePathType_Mutable is available since 19H1 + // * PackagePathType_Effective is available since 19H1 + // * PackagePathType_MachineExternalLocation is available since 20H1 + // * PackagePathType_UserExternalLocation is available since 20H1 + // * PackagePathType_EffectiveExternalLocation is available since 20H1 + // GetPackagePathByFullName() is available since Win8 + // GetPackagePathByFullName2() is available since 19H1 (though not all PackagePathType values were supported that early) + // + // Treat asks for locations not supported by the current system the same as not-found + // + // This is all handled by GetPackagePathByFullName2IfSupported() so just ask it for the path + std::wstring packagePath{ ::AppModel::Package::GetPath(packageFullName, packagePathType) }; if (!packagePath.empty()) { - absoluteFilename = packagePath; + std::filesystem::path absoluteFilename{ packagePath }; absoluteFilename /= filename; if (std::filesystem::exists(absoluteFilename)) { From eefa0634e838cd6f208e0764cdcb0f5f4ce99cc0 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Tue, 24 Mar 2026 12:16:38 -0700 Subject: [PATCH 31/33] Fixed package not found should == file not found --- dev/Package/package_runtime.cpp | 6 ++++++ test/Package/API/PackageTests_Package_CPP.cpp | 11 +++++++++-- test/Package/API/PackageTests_Package_WinRT.cpp | 9 +++++++-- test/Package/API/PackageTests_WinRT.cpp | 9 +++++++-- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/dev/Package/package_runtime.cpp b/dev/Package/package_runtime.cpp index 3013f86c22..75565b863b 100644 --- a/dev/Package/package_runtime.cpp +++ b/dev/Package/package_runtime.cpp @@ -334,6 +334,12 @@ STDAPI GetPackageFilePath( auto rc{ ::OpenPackageInfoByFullName(packageFullName, 0, wil::out_param(packageInfoReference)) }; if (rc != ERROR_SUCCESS) { + const auto hr{ HRESULT_FROM_WIN32(rc) }; + if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) + { + // Package not found == File not found + return S_OK; + } THROW_WIN32_MSG(rc, "OpenPackageInfoByFullName(%ls,...)", packageFullName); } auto path{ appmodel::get_package_file(packageFullName, filename, effectiveOptions, packageInfoReference.get()) }; diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index 12bb74ae63..89eda58901 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -92,9 +92,16 @@ namespace Test::Package::Tests VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), ::GetPackageFilePath(noPackageFullName, fileName, options, wil::out_param(absoluteFilename))); } - TEST_METHOD(GetPackageFilePath_NullPackageFullName_PackagedProcess_InstallPath) + TEST_METHOD(GetPackageFilePath_NoSuchPackage) { - //TODO + PCWSTR packageFullName{ L"Does.Not.Exist_1.2.3.4_neutral__1234567890abc" }; + PCWSTR fileName{ L"AppxManifest.xml" }; + const auto options{ GetPackageFilePathOptions_None }; + wil::unique_process_heap_ptr absoluteFilename; + VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); + VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"Actual:%ls", !actual ? L"" : actual.get())); } TEST_METHOD(GetPackageFilePath) diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp index 9e44d0a5eb..662d97d5d0 100644 --- a/test/Package/API/PackageTests_Package_WinRT.cpp +++ b/test/Package/API/PackageTests_Package_WinRT.cpp @@ -142,9 +142,14 @@ namespace Test::Package::Tests } } - TEST_METHOD(GetFilePath_NullPackageFullName_PackagedProcess_InstallPath) + TEST_METHOD(GetFilePath_NoSuchPackage) { - //TODO + winrt::hstring packageFullName{ L"Does.Not.Exist_1.2.3.4_neutral__1234567890abc" }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_TRUE(absoluteFilename.empty()); } TEST_METHOD(GetFilePath) diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp index 0a14c5b565..61499786ee 100644 --- a/test/Package/API/PackageTests_WinRT.cpp +++ b/test/Package/API/PackageTests_WinRT.cpp @@ -106,9 +106,14 @@ namespace Test::Package::Tests } } - TEST_METHOD(GetFilePath_NullPackageFullName_PackagedProcess_InstallPath) + TEST_METHOD(GetFilePath_NoSuchPackage) { - //TODO + winrt::hstring packageFullName{ L"Does.Not.Exist_1.2.3.4_neutral__1234567890abc" }; + winrt::hstring fileName{ L"AppxManifest.xml" }; + const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); + VERIFY_IS_TRUE(absoluteFilename.empty()); } TEST_METHOD(GetFilePath) From a0363d5b9b9ae9f12ab14db5cd45db6acb5efcc9 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Tue, 24 Mar 2026 13:39:36 -0700 Subject: [PATCH 32/33] Fixed typo --- test/Package/API/PackageTests_Package_CPP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index 89eda58901..616b89f842 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -101,7 +101,7 @@ namespace Test::Package::Tests VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"Actual:%ls", !actual ? L"" : actual.get())); + VERIFY_IS_NULL(absoluteFilename, WEX::Common::String().Format(L"Actual:%ls", !absoluteFilename ? L"" : absoluteFilename.get())); } TEST_METHOD(GetPackageFilePath) From 50e998b93fe050f7ab56e1f7110120fa48bd7aab Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Tue, 24 Mar 2026 22:02:20 -0700 Subject: [PATCH 33/33] Fixed tests. Removed dead code --- test/Package/API/PackageTests_CPP.cpp | 196 ---------------- test/Package/API/PackageTests_Package_CPP.cpp | 18 +- .../API/PackageTests_Package_WinRT.cpp | 18 +- test/Package/API/PackageTests_WinRT.cpp | 221 ------------------ 4 files changed, 30 insertions(+), 423 deletions(-) delete mode 100644 test/Package/API/PackageTests_CPP.cpp delete mode 100644 test/Package/API/PackageTests_WinRT.cpp diff --git a/test/Package/API/PackageTests_CPP.cpp b/test/Package/API/PackageTests_CPP.cpp deleted file mode 100644 index 71b78cead6..0000000000 --- a/test/Package/API/PackageTests_CPP.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) Microsoft Corporation and Contributors. -// Licensed under the MIT License. - -#include "pch.h" - -#include - -#include - -#include "PackageTests.Packages.h" - -namespace TD = ::Test::Diagnostics; -namespace TB = ::Test::Bootstrap; -namespace TP = ::Test::Packages; -namespace TD = ::Test::Diagnostics; - -namespace Test::Package::Tests -{ - const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; - const auto Framework_PackageFullName{ ::TP::Framework::c_packageFullName }; - const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; - const auto UserExternal_PackageFullName{ ::TP::UserExternal::c_packageFullName }; - const auto MachineExternal_PackageFullName{ ::TP::MachineExternal::c_packageFullName }; - - class PackageTests_CPP - { - public: - BEGIN_TEST_CLASS(PackageTests_CPP) - TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") - TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") - END_TEST_CLASS() - - TEST_CLASS_SETUP(ClassSetup) - { - ::TB::Setup(); - - RemovePackage_MachineExternal(); - RemovePackage_UserExternal(); - RemovePackage_Mutable(); - RemovePackage_Framework(); - - AddPackage_Framework(); - AddPackage_Mutable(); - AddPackage_UserExternal(); - StagePackage_MachineExternal(); - AddPackage_MachineExternal(); - - return true; - } - - TEST_CLASS_CLEANUP(ClassCleanup) - { - ::TB::Cleanup(); - - RemovePackage_MachineExternal(); - RemovePackage_UserExternal(); - RemovePackage_Mutable(); - RemovePackage_Framework(); - - return true; - } - - TEST_METHOD(GetPackageFilePath_InvalidParameter) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR noFileName{}; - wil::unique_process_heap_ptr absoluteFilename; - const auto options{ GetPackageFilePathOptions_None }; - VERIFY_ARE_EQUAL(E_INVALIDARG, ::GetPackageFilePath(packageFullName, noFileName, options, wil::out_param(absoluteFilename))); - } - - TEST_METHOD(GetPackageFilePath_NullPackageFullName_UnpackagedProcess_NoPackage) - { - PCWSTR noPackageFullName{}; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_None }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), ::GetPackageFilePath(noPackageFullName, fileName, options, wil::out_param(absoluteFilename))); - } - - TEST_METHOD(GetPackageFilePath_NullPackageFullName_PackagedProcess_InstallPath) - { - //TODO - } - - TEST_METHOD(GetPackageFilePath) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_None }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); - // GetPackageFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges - // with Mutable or External locations so we'll resolve the Install path - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Install) }; - const std::filesystem::path actual{ absoluteFilename.get() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str())); - } - - TEST_METHOD(GetPackageFilePath_InstallPath) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.get()}); - } - - TEST_METHOD(GetPackageFilePath_MutablePath) - { - PCWSTR packageFullName{ Mutable_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchMutablePath }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected; - if (IsMutableLocationSupported()) - { - expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable); - } - const std::filesystem::path actual{ absoluteFilename.get() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); - } - - TEST_METHOD(GetPackageFilePath_MachineExternalPath) - { - PCWSTR packageFullName{ MachineExternal_PackageFullName }; - PCWSTR fileName{ L"Shadow.cat" }; - const auto options{ GetPackageFilePathOptions_SearchMachineExternalPath }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); - const std::filesystem::path expected; - if (IsExternalLocationSupported()) - { - expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal); - } - const std::filesystem::path actual{ absoluteFilename.get() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); - } - - TEST_METHOD(GetPackageFilePath_UserExternalPath) - { - PCWSTR packageFullName{ UserExternal_PackageFullName }; - PCWSTR fileName{ L"Shadow.cat" }; - const auto options{ GetPackageFilePathOptions_SearchUserExternalPath }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); - std::filesystem::path expected; - if (IsExternalLocationSupported()) - { - expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal); - } - const std::filesystem::path actual{ absoluteFilename.get() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); - } - - TEST_METHOD(GetPackageFilePath_FilterPackageType_Main_NoMatch) - { - PCWSTR packageFullName{ Main_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchFrameworkPackages }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - - TEST_METHOD(GetPackageFilePath_FilterPackageType_Framework_NoMatch) - { - PCWSTR packageFullName{ Framework_PackageFullName }; - PCWSTR fileName{ L"AppxManifest.xml" }; - const auto options{ GetPackageFilePathOptions_SearchInstallPath | - GetPackageFilePathOptions_SearchMainPackages }; - wil::unique_process_heap_ptr absoluteFilename; - VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); - VERIFY_IS_NULL(absoluteFilename); - } - }; -} diff --git a/test/Package/API/PackageTests_Package_CPP.cpp b/test/Package/API/PackageTests_Package_CPP.cpp index 616b89f842..bf1b689f3a 100644 --- a/test/Package/API/PackageTests_Package_CPP.cpp +++ b/test/Package/API/PackageTests_Package_CPP.cpp @@ -144,12 +144,16 @@ namespace Test::Package::Tests VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); std::filesystem::path expected; if (IsMutableLocationSupported()) { + VERIFY_IS_NOT_NULL(absoluteFilename); expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_Mutable); } + else + { + VERIFY_IS_NULL(absoluteFilename); + } const std::filesystem::path actual{ absoluteFilename.get() }; VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } @@ -163,12 +167,16 @@ namespace Test::Package::Tests VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); std::filesystem::path expected; if (IsExternalLocationSupported()) { + VERIFY_IS_NOT_NULL(absoluteFilename); expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_MachineExternal); } + else + { + VERIFY_IS_NULL(absoluteFilename); + } const std::filesystem::path actual{ absoluteFilename.get() }; VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } @@ -182,12 +190,16 @@ namespace Test::Package::Tests VERIFY_SUCCEEDED(::GetPackageFilePath(packageFullName, fileName, options, wil::out_param(absoluteFilename))); WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.get())); - VERIFY_IS_NOT_NULL(absoluteFilename); std::filesystem::path expected; if (IsExternalLocationSupported()) { + VERIFY_IS_NOT_NULL(absoluteFilename); expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName, fileName, PackagePathType_UserExternal); } + else + { + VERIFY_IS_NULL(absoluteFilename); + } const std::filesystem::path actual{ absoluteFilename.get() }; VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } diff --git a/test/Package/API/PackageTests_Package_WinRT.cpp b/test/Package/API/PackageTests_Package_WinRT.cpp index 662d97d5d0..ca563a8fbd 100644 --- a/test/Package/API/PackageTests_Package_WinRT.cpp +++ b/test/Package/API/PackageTests_Package_WinRT.cpp @@ -188,12 +188,16 @@ namespace Test::Package::Tests const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); std::filesystem::path expected; if (IsMutableLocationSupported()) { + VERIFY_IS_FALSE(absoluteFilename.empty()); expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable); } + else + { + VERIFY_IS_TRUE(absoluteFilename.empty()); + } const std::filesystem::path actual{ absoluteFilename.c_str() }; VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } @@ -206,12 +210,16 @@ namespace Test::Package::Tests const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); std::filesystem::path expected; if (IsExternalLocationSupported()) { + VERIFY_IS_FALSE(absoluteFilename.empty()); expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); } + else + { + VERIFY_IS_TRUE(absoluteFilename.empty()); + } const std::filesystem::path actual{ absoluteFilename.c_str() }; VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } @@ -224,12 +232,16 @@ namespace Test::Package::Tests const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); std::filesystem::path expected; if (IsExternalLocationSupported()) { + VERIFY_IS_FALSE(absoluteFilename.empty()); expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal); } + else + { + VERIFY_IS_TRUE(absoluteFilename.empty()); + } const std::filesystem::path actual{ absoluteFilename.c_str() }; VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str())); } diff --git a/test/Package/API/PackageTests_WinRT.cpp b/test/Package/API/PackageTests_WinRT.cpp deleted file mode 100644 index 61499786ee..0000000000 --- a/test/Package/API/PackageTests_WinRT.cpp +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) Microsoft Corporation and Contributors. -// Licensed under the MIT License. - -#include "pch.h" - -#include - -namespace TD = ::Test::Diagnostics; -namespace TB = ::Test::Bootstrap; -namespace TP = ::Test::Packages; -namespace TD = ::Test::Diagnostics; - -static const winrt::hstring null_hstring; - -namespace Test::Package::Tests -{ - const auto Main_PackageFullName{ ::TP::WindowsAppRuntimeMain::c_PackageFullName }; - const auto Framework_PackageFullName{ ::TP::WindowsAppRuntimeFramework::c_PackageFullName }; - const auto Mutable_PackageFullName{ ::TP::Mutable::c_packageFullName }; - - class PackageTests_WinRT - { - public: - BEGIN_TEST_CLASS(PackageTests_WinRT) - TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") - TEST_CLASS_PROPERTY(L"RunAs", L"RestrictedUser") - END_TEST_CLASS() - - TEST_CLASS_SETUP(ClassSetup) - { - ::TB::Setup(); - - RemovePackage_UserExternal(); - RemovePackage_Mutable(); - - AddPackage_Mutable(); - AddPackage_UserExternal(); - - return true; - } - - TEST_CLASS_CLEANUP(ClassCleanup) - { - ::TB::Cleanup(); - - RemovePackage_MachineExternal(); - RemovePackage_UserExternal(); - RemovePackage_Mutable(); - - return true; - } - - TEST_METHOD(GetFilePath_InvalidParameter) - { - try - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring noFileName; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noFileName, packageFullName); - VERIFY_FAIL(L"Success is not expected"); - } - catch (winrt::hresult_error& e) - { - VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); - } - - try - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring noFileName; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(noFileName, packageFullName, options); - VERIFY_FAIL(L"Success is not expected"); - } - catch (winrt::hresult_error& e) - { - VERIFY_ARE_EQUAL(E_INVALIDARG, e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); - } - } - - TEST_METHOD(GetFilePath_NullPackageFullName_UnpackagedProcess_NoPackage) - { - try - { - winrt::hstring noPackageFullName; - winrt::hstring fileName{ L"AppxManifest.xml" }; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, noPackageFullName); - VERIFY_FAIL(L"Success is not expected"); - } - catch (winrt::hresult_error& e) - { - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); - } - - try - { - winrt::hstring noPackageFullName; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::None }; - std::ignore = winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, noPackageFullName, options); - VERIFY_FAIL(L"Success is not expected"); - } - catch (winrt::hresult_error& e) - { - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), e.code(), WEX::Common::String().Format(L"0x%X %s", e.code(), e.message().c_str())); - } - } - - TEST_METHOD(GetFilePath_NoSuchPackage) - { - winrt::hstring packageFullName{ L"Does.Not.Exist_1.2.3.4_neutral__1234567890abc" }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) }; - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName) }; - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); - // GetFilePath() w/o specifying Search*Path == SearchEffectivePath but we don't have any matching pacakges - // with Mutable or External locations so we'll resolve the Install path - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; - const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls AbsoluteFilename:%ls", expected.c_str(), actual.c_str())); - } - - TEST_METHOD(GetFilePath_InstallPath) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected{ ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Install) }; - VERIFY_ARE_EQUAL(expected, std::filesystem::path{absoluteFilename.c_str()}); - } - - TEST_METHOD(GetFilePath_MutablePath) - { - winrt::hstring packageFullName{ Mutable_PackageFullName }; - winrt::hstring fileName{ L"AppxManifest.xml" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMutablePath }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); - const std::filesystem::path expected; - if (IsMutableLocationSupported()) - { - expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_Mutable); - } - const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); - } - - TEST_METHOD(GetFilePath_MachineExternalPath) - { - winrt::hstring packageFullName{ MachineExternal_PackageFullName }; - winrt::hstring fileName{ L"Shadow.cat" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMachineExternalPath }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); - std::filesystem::path expected; - if (IsExternalLocationSupported()) - { - expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_MachineExternal); - } - const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); - } - - TEST_METHOD(GetFilePath_UserExternalPath) - { - winrt::hstring packageFullName{ UserExternal_PackageFullName }; - winrt::hstring fileName{ L"Shadow.cat" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchUserExternalPath }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Found: %ls", absoluteFilename.c_str())); - VERIFY_IS_FALSE(absoluteFilename.empty()); - std::filesystem::path expected; - if (IsExternalLocationSupported()) - { - expected = ::AppModel::Package::GetAbsoluteFilename(packageFullName.c_str(), fileName.c_str(), PackagePathType_UserExternal); - } - const std::filesystem::path actual{ absoluteFilename.c_str() }; - VERIFY_ARE_EQUAL(expected, actual, WEX::Common::String().Format(L"Expected:%ls Actual:%ls", expected.c_str(), actual.c_str()))); - } - - TEST_METHOD(GetFilePath_FilterPackageType_Main_NoMatch) - { - winrt::hstring packageFullName{ Main_PackageFullName }; - winrt::hstring fileName{ L"Shadow.cat" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchFrameworkPackages }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - - TEST_METHOD(GetFilePath_FilterPackageType_Framework_NoMatch) - { - winrt::hstring packageFullName{ Framework_PackageFullName }; - winrt::hstring fileName{ L"Shadow.cat" }; - const auto options{ winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchInstallPath | - winrt::Microsoft::Windows::ApplicationModel::GetFilePathOptions::SearchMainPackages }; - const auto absoluteFilename{ winrt::Microsoft::Windows::ApplicationModel::Package::GetFilePath(fileName, packageFullName, options) }; - VERIFY_IS_TRUE(absoluteFilename.empty()); - } - }; -}