From 1fe10dabd8808dffb959774d482c589cfebe0935 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 27 Jun 2024 00:39:33 -0700 Subject: [PATCH 1/2] Reapply "PackageDeploymentManager: IsReadyOrNewerAvailable(), FrameworkUdk update, Implement not-implemented functions, Tests! (#4453)" (#4514) This reverts commit 684fdf17977b121436be94621d15817ad0aacc83. --- WindowsAppRuntime.sln | 94 +- dev/Common/AppModel.Identity.h | 17 + dev/Common/IsWindowsVersion.h | 2 +- dev/Common/Security.User.h | 26 + dev/Deployment/DeploymentManager.cpp | 4 +- .../mrt/Core/unittests/packages.config | 2 +- .../UnpackagedTests/packages.config | 2 +- dev/MRTCore/mrt/mrm/UnitTests/packages.config | 2 +- .../API/M.W.M.D.EnsureReadyOptions.cpp | 8 + .../API/M.W.M.D.EnsureReadyOptions.h | 3 + .../API/M.W.M.D.PackageDeploymentManager.cpp | 2807 ++++++++++++++--- .../API/M.W.M.D.PackageDeploymentManager.h | 228 +- .../API/M.W.M.D.RemovePackageOptions.h | 2 +- .../API/PackageDeploymentResolver.cpp | 9 + .../API/PackageDeploymentResolver.h | 4 + dev/PackageManager/API/PackageManager.idl | 76 +- .../API/PackageManagerTelemetry.h | 12 +- dev/PackageManager/API/pch.h | 6 + dev/WindowsAppRuntime_DLL/packages.config | 1 + dev/WindowsAppRuntime_DLL/pch.h | 3 + docs/Coding-Guidelines/GettingStarted.md | 24 +- eng/Version.Dependencies.xml | 2 +- eng/common/DevCheck.ps1 | 62 +- .../InstallerFunctionalTests/packages.config | 2 +- specs/packagemanager/PackageManagement.md | 60 +- test/AccessControlTests/packages.config | 2 +- test/AppLifecycle/packages.config | 2 +- .../packages.config | 2 +- test/AppNotificationTests/packages.config | 2 +- test/Common/packages.config | 2 +- test/Common/pch.h | 1 + test/Deployment/API/packages.config | 2 +- .../Test_Win32/packages.config | 2 +- .../Test_WinRT/packages.config | 2 +- test/EnvironmentManagerTests/packages.config | 2 +- test/LRPTests/packages.config | 2 +- .../API/PackageDeploymentManagerTests.cpp | 2383 +------------- .../API/PackageDeploymentManagerTests.h | 167 + .../API/PackageDeploymentManagerTests_Add.cpp | 700 ++++ ...mentManagerTests_Deprovision_Framework.cpp | 637 ++++ ...eploymentManagerTests_Deprovision_Main.cpp | 702 +++++ ...kageDeploymentManagerTests_EnsureReady.cpp | 551 ++++ ...agerTests_IsPackageRegistrationPending.cpp | 163 + .../PackageDeploymentManagerTests_IsReady.cpp | 416 +++ ...ntManagerTests_IsReadyOrNewerAvailable.cpp | 834 +++++ ...ackageDeploymentManagerTests_Provision.cpp | 722 +++++ ...PackageDeploymentManagerTests_Register.cpp | 712 +++++ .../PackageDeploymentManagerTests_Remove.cpp | 1336 ++++++++ .../PackageDeploymentManagerTests_Repair.cpp | 625 ++++ .../PackageDeploymentManagerTests_Reset.cpp | 641 ++++ .../PackageDeploymentManagerTests_Stage.cpp | 839 +++++ .../API/PackageManagerTests.Packages.h | 465 ++- .../API/PackageManagerTests.vcxproj | 17 + .../API/PackageManagerTests.vcxproj.filters | 45 + .../API/PackageRuntimeManagerTests.cpp | 2 + test/PackageManager/API/packages.config | 3 +- test/PackageManager/API/pch.h | 23 + .../PackageManager.Test.F.Red.msix/pch.cpp | 8 + .../data/PackageManager.Test.F.Red.msix/pch.h | 23 + .../winmain.cpp | 34 + .../Assets/SplashScreen.png | Bin 0 -> 78102 bytes .../Assets/Square150x150Logo.png | Bin 0 -> 10887 bytes .../Assets/Square44x44Logo.png | Bin 0 -> 2793 bytes .../Assets/Wide310x150Logo.png | Bin 0 -> 11204 bytes .../Assets/logo.png | Bin 0 -> 3138 bytes .../PackageManager.Test.M.Black.msix.vcxproj | 185 ++ ...eManager.Test.M.Black.msix.vcxproj.filters | 38 + ...ackageManager.Test.M.Black.vcxproj.filters | 17 + .../appxmanifest-arm64.xml | 49 + .../appxmanifest-x64.xml | 49 + .../appxmanifest-x86.xml | 49 + .../PackageManager.Test.M.Black.msix/logo.png | Bin 0 -> 5632 bytes .../packages.config | 7 + .../PackageManager.Test.M.Black.msix/pch.cpp | 8 + .../PackageManager.Test.M.Black.msix/pch.h | 23 + .../winmain.cpp | 38 + .../Assets/SplashScreen.png | Bin 0 -> 78102 bytes .../Assets/Square150x150Logo.png | Bin 0 -> 10887 bytes .../Assets/Square44x44Logo.png | Bin 0 -> 2793 bytes .../Assets/Wide310x150Logo.png | Bin 0 -> 11204 bytes .../Assets/logo.png | Bin 0 -> 3138 bytes ...PackageManager.Test.M.Blacker.msix.vcxproj | 185 ++ ...anager.Test.M.Blacker.msix.vcxproj.filters | 38 + ...kageManager.Test.M.Blacker.vcxproj.filters | 17 + .../appxmanifest-arm64.xml | 49 + .../appxmanifest-x64.xml | 49 + .../appxmanifest-x86.xml | 49 + .../logo.png | Bin 0 -> 5632 bytes .../packages.config | 7 + .../pch.cpp | 8 + .../PackageManager.Test.M.Blacker.msix/pch.h | 23 + .../winmain.cpp | 38 + .../Assets/SplashScreen.png | Bin 0 -> 78102 bytes .../Assets/Square150x150Logo.png | Bin 0 -> 10887 bytes .../Assets/Square44x44Logo.png | Bin 0 -> 2793 bytes .../Assets/Wide310x150Logo.png | Bin 0 -> 11204 bytes .../Assets/logo.png | Bin 0 -> 3138 bytes .../PackageManager.Test.M.White.msix.vcxproj | 185 ++ ...eManager.Test.M.White.msix.vcxproj.filters | 38 + ...ackageManager.Test.M.White.vcxproj.filters | 17 + .../appxmanifest-arm64.xml | 49 + .../appxmanifest-x64.xml | 49 + .../appxmanifest-x86.xml | 49 + .../PackageManager.Test.M.White.msix/logo.png | Bin 0 -> 5632 bytes .../packages.config | 7 + .../PackageManager.Test.M.White.msix/pch.cpp | 8 + .../PackageManager.Test.M.White.msix/pch.h | 23 + .../winmain.cpp | 38 + .../Assets/SplashScreen.png | Bin 0 -> 78102 bytes .../Assets/Square150x150Logo.png | Bin 0 -> 10887 bytes .../Assets/Square44x44Logo.png | Bin 0 -> 2793 bytes .../Assets/Wide310x150Logo.png | Bin 0 -> 11204 bytes .../Assets/logo.png | Bin 0 -> 3138 bytes .../PackageManager.Test.M.Whiter.msix.vcxproj | 185 ++ ...Manager.Test.M.Whiter.msix.vcxproj.filters | 38 + ...ckageManager.Test.M.Whiter.vcxproj.filters | 17 + .../appxmanifest-arm64.xml | 49 + .../appxmanifest-x64.xml | 49 + .../appxmanifest-x86.xml | 49 + .../logo.png | Bin 0 -> 5632 bytes .../packages.config | 7 + .../PackageManager.Test.M.Whiter.msix/pch.cpp | 8 + .../PackageManager.Test.M.Whiter.msix/pch.h | 23 + .../winmain.cpp | 38 + test/PowerNotifications/packages.config | 2 +- test/PushNotificationTests/packages.config | 2 +- .../AccessControlTestApp/packages.config | 2 +- .../AppLifecycleTestApp/packages.config | 2 +- test/TestApps/ManualTestApp/packages.config | 2 +- .../PushNotificationsDemoApp/packages.config | 2 +- .../PushNotificationsTestApp/packages.config | 2 +- .../ToastNotificationsDemoApp/packages.config | 2 +- .../ToastNotificationsTestApp/packages.config | 2 +- test/VersionInfo/packages.config | 2 +- test/inc/WindowsAppRuntime.Test.Package.h | 177 +- .../test.cpp.dll.taef/packages.config | 2 +- 136 files changed, 14686 insertions(+), 2892 deletions(-) create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests.h create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Add.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Deprovision_Framework.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Deprovision_Main.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_EnsureReady.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_IsPackageRegistrationPending.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_IsReady.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_IsReadyOrNewerAvailable.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Provision.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Register.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Remove.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Repair.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Reset.cpp create mode 100644 test/PackageManager/API/PackageDeploymentManagerTests_Stage.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.F.Red.msix/pch.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.F.Red.msix/pch.h create mode 100644 test/PackageManager/data/PackageManager.Test.F.Red.msix/winmain.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/SplashScreen.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/Square150x150Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/Square44x44Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/Wide310x150Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.msix.vcxproj create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.msix.vcxproj.filters create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.vcxproj.filters create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-arm64.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-x64.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-x86.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/packages.config create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/pch.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/pch.h create mode 100644 test/PackageManager/data/PackageManager.Test.M.Black.msix/winmain.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/SplashScreen.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/Square150x150Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/Square44x44Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/Wide310x150Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.msix.vcxproj create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.msix.vcxproj.filters create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.vcxproj.filters create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-arm64.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-x64.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-x86.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/packages.config create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/pch.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/pch.h create mode 100644 test/PackageManager/data/PackageManager.Test.M.Blacker.msix/winmain.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/SplashScreen.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/Square150x150Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/Square44x44Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/Wide310x150Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.msix.vcxproj create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.msix.vcxproj.filters create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.vcxproj.filters create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-arm64.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-x64.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-x86.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/packages.config create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/pch.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/pch.h create mode 100644 test/PackageManager/data/PackageManager.Test.M.White.msix/winmain.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/SplashScreen.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/Square150x150Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/Square44x44Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/Wide310x150Logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.msix.vcxproj create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.msix.vcxproj.filters create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.vcxproj.filters create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-arm64.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-x64.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-x86.xml create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/logo.png create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/packages.config create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/pch.cpp create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/pch.h create mode 100644 test/PackageManager/data/PackageManager.Test.M.Whiter.msix/winmain.cpp diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 9dbfdd6b05..1ebd8089b6 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -461,9 +461,13 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageManagerTests", "test\PackageManager\API\PackageManagerTests.vcxproj", "{4A38CB80-3580-4960-9B31-3301058B7AFE}" ProjectSection(ProjectDependencies) = postProject {09DDAE21-397F-4263-8561-7F2FF28127CF} = {09DDAE21-397F-4263-8561-7F2FF28127CF} + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF} = {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF} + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA} = {39277B4C-4FB5-45F6-B0AA-EE8086590CDA} {4626E11F-A7A4-41A2-B22D-5A108BC369AC} = {4626E11F-A7A4-41A2-B22D-5A108BC369AC} {58E95711-A12F-4C0E-A978-C6B4A0842AC8} = {58E95711-A12F-4C0E-A978-C6B4A0842AC8} {66D0D8B1-FAF4-4C6A-8303-07F3BA356FE3} = {66D0D8B1-FAF4-4C6A-8303-07F3BA356FE3} + {AC79B8FF-4C27-4326-AD20-BBC70059FF51} = {AC79B8FF-4C27-4326-AD20-BBC70059FF51} + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D} = {AD7D0A19-44B9-41D6-A68A-9FECAC28078D} {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1} {D0A1DFB8-8CEE-4CFC-B57B-B7C574B411C2} = {D0A1DFB8-8CEE-4CFC-B57B-B7C574B411C2} {F2946790-DAF7-4DFF-A754-BA471A12E494} = {F2946790-DAF7-4DFF-A754-BA471A12E494} @@ -493,6 +497,22 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Windows.Managemen {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1} EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PackageManager.Test.M.Black.msix", "PackageManager.Test.M.Black.msix", "{1AC589D7-FA54-470E-8640-AB2477CA844C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PackageManager.Test.M.Blacker.msix", "PackageManager.Test.M.Blacker.msix", "{4567CD12-A0A7-4E65-8075-B17C09261767}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageManager.Test.M.Black.msix", "test\PackageManager\data\PackageManager.Test.M.Black.msix\PackageManager.Test.M.Black.msix.vcxproj", "{39277B4C-4FB5-45F6-B0AA-EE8086590CDA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageManager.Test.M.Blacker.msix", "test\PackageManager\data\PackageManager.Test.M.Blacker.msix\PackageManager.Test.M.Blacker.msix.vcxproj", "{AD7D0A19-44B9-41D6-A68A-9FECAC28078D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PackageManager.Test.M.White.msix", "PackageManager.Test.M.White.msix", "{6759ECC6-9381-4172-89E6-853F81A03D28}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PackageManager.Test.M.Whiter.msix", "PackageManager.Test.M.Whiter.msix", "{7C240089-0F22-4247-9C91-51255C8DC18B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageManager.Test.M.Whiter.msix", "test\PackageManager\data\PackageManager.Test.M.Whiter.msix\PackageManager.Test.M.Whiter.msix.vcxproj", "{AC79B8FF-4C27-4326-AD20-BBC70059FF51}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PackageManager.Test.M.White.msix", "test\PackageManager\data\PackageManager.Test.M.White.msix\PackageManager.Test.M.White.msix.vcxproj", "{28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1739,6 +1759,70 @@ Global {57E6CCBE-EDEB-4300-8334-98A591D11B3F}.Release|x64.Build.0 = Release|x64 {57E6CCBE-EDEB-4300-8334-98A591D11B3F}.Release|x86.ActiveCfg = Release|x86 {57E6CCBE-EDEB-4300-8334-98A591D11B3F}.Release|x86.Build.0 = Release|x86 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Debug|Any CPU.ActiveCfg = Debug|x64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Debug|Any CPU.Build.0 = Debug|x64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Debug|ARM64.Build.0 = Debug|ARM64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Debug|x64.ActiveCfg = Debug|x64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Debug|x64.Build.0 = Debug|x64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Debug|x86.ActiveCfg = Debug|Win32 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Debug|x86.Build.0 = Debug|Win32 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Release|Any CPU.ActiveCfg = Release|x64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Release|Any CPU.Build.0 = Release|x64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Release|ARM64.ActiveCfg = Release|ARM64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Release|ARM64.Build.0 = Release|ARM64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Release|x64.ActiveCfg = Release|x64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Release|x64.Build.0 = Release|x64 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Release|x86.ActiveCfg = Release|Win32 + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA}.Release|x86.Build.0 = Release|Win32 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Debug|Any CPU.ActiveCfg = Debug|x64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Debug|Any CPU.Build.0 = Debug|x64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Debug|ARM64.Build.0 = Debug|ARM64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Debug|x64.ActiveCfg = Debug|x64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Debug|x64.Build.0 = Debug|x64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Debug|x86.ActiveCfg = Debug|Win32 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Debug|x86.Build.0 = Debug|Win32 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Release|Any CPU.ActiveCfg = Release|x64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Release|Any CPU.Build.0 = Release|x64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Release|ARM64.ActiveCfg = Release|ARM64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Release|ARM64.Build.0 = Release|ARM64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Release|x64.ActiveCfg = Release|x64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Release|x64.Build.0 = Release|x64 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Release|x86.ActiveCfg = Release|Win32 + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D}.Release|x86.Build.0 = Release|Win32 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Debug|Any CPU.ActiveCfg = Debug|x64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Debug|Any CPU.Build.0 = Debug|x64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Debug|ARM64.Build.0 = Debug|ARM64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Debug|x64.ActiveCfg = Debug|x64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Debug|x64.Build.0 = Debug|x64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Debug|x86.ActiveCfg = Debug|Win32 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Debug|x86.Build.0 = Debug|Win32 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Release|Any CPU.ActiveCfg = Release|x64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Release|Any CPU.Build.0 = Release|x64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Release|ARM64.ActiveCfg = Release|ARM64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Release|ARM64.Build.0 = Release|ARM64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Release|x64.ActiveCfg = Release|x64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Release|x64.Build.0 = Release|x64 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Release|x86.ActiveCfg = Release|Win32 + {AC79B8FF-4C27-4326-AD20-BBC70059FF51}.Release|x86.Build.0 = Release|Win32 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Debug|Any CPU.ActiveCfg = Debug|x64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Debug|Any CPU.Build.0 = Debug|x64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Debug|ARM64.Build.0 = Debug|ARM64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Debug|x64.ActiveCfg = Debug|x64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Debug|x64.Build.0 = Debug|x64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Debug|x86.ActiveCfg = Debug|Win32 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Debug|x86.Build.0 = Debug|Win32 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Release|Any CPU.ActiveCfg = Release|x64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Release|Any CPU.Build.0 = Release|x64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Release|ARM64.ActiveCfg = Release|ARM64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Release|ARM64.Build.0 = Release|ARM64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Release|x64.ActiveCfg = Release|x64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Release|x64.Build.0 = Release|x64 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Release|x86.ActiveCfg = Release|Win32 + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1885,9 +1969,17 @@ Global {4626E11F-A7A4-41A2-B22D-5A108BC369AC} = {266AE21F-0D59-4422-A95C-4B3D2BA32A4C} {39A17DBB-F1DB-4D0C-B90E-D5F9BEC2283A} = {6213B1A3-E854-498F-AAFA-4CFC1E71023E} {FBAE1876-C50A-4EFC-A686-3008B6438731} = {39A17DBB-F1DB-4D0C-B90E-D5F9BEC2283A} - {B6B68924-6A0B-457E-AD53-018696EC8889} = {B03C7C69-0A52-4553-B465-04C995161E42} + {B6B68924-6A0B-457E-AD53-018696EC8889} = {6213B1A3-E854-498F-AAFA-4CFC1E71023E} {D0A1DFB8-8CEE-4CFC-B57B-B7C574B411C2} = {B6B68924-6A0B-457E-AD53-018696EC8889} {57E6CCBE-EDEB-4300-8334-98A591D11B3F} = {716C26A0-E6B0-4981-8412-D14A4D410531} + {1AC589D7-FA54-470E-8640-AB2477CA844C} = {6213B1A3-E854-498F-AAFA-4CFC1E71023E} + {4567CD12-A0A7-4E65-8075-B17C09261767} = {6213B1A3-E854-498F-AAFA-4CFC1E71023E} + {39277B4C-4FB5-45F6-B0AA-EE8086590CDA} = {1AC589D7-FA54-470E-8640-AB2477CA844C} + {AD7D0A19-44B9-41D6-A68A-9FECAC28078D} = {4567CD12-A0A7-4E65-8075-B17C09261767} + {6759ECC6-9381-4172-89E6-853F81A03D28} = {6213B1A3-E854-498F-AAFA-4CFC1E71023E} + {7C240089-0F22-4247-9C91-51255C8DC18B} = {6213B1A3-E854-498F-AAFA-4CFC1E71023E} + {AC79B8FF-4C27-4326-AD20-BBC70059FF51} = {7C240089-0F22-4247-9C91-51255C8DC18B} + {28DCF9CE-D9F4-4A7D-8AD1-F2EFC0D3B4DF} = {6759ECC6-9381-4172-89E6-853F81A03D28} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/dev/Common/AppModel.Identity.h b/dev/Common/AppModel.Identity.h index 649099df3a..c1ef91ce6f 100644 --- a/dev/Common/AppModel.Identity.h +++ b/dev/Common/AppModel.Identity.h @@ -372,6 +372,14 @@ class PackageIdentity return m_packageId->publisherId; } + std::wstring PackageFamilyName() const + { + WCHAR packageFamilyName[PACKAGE_FAMILY_NAME_MAX_LENGTH + 1]{}; + UINT32 packageFamilyNameLength{ ARRAYSIZE(packageFamilyName) }; + THROW_IF_WIN32_ERROR_MSG(::PackageFamilyNameFromId(m_packageId, &packageFamilyNameLength, packageFamilyName), "%ls", m_packageFullName.c_str()); + return packageFamilyName; + } + explicit operator bool() const { return m_packageId != nullptr; @@ -384,6 +392,15 @@ class PackageIdentity PACKAGE_RESOURCEID_MAX_LENGTH + 1 + PACKAGE_PUBLISHERID_MAX_LENGTH + 1) * sizeof(WCHAR)]{}; }; + +template +T ToPackageFamilyName(PCWSTR packageFullName) +{ + WCHAR packageFamilyName[PACKAGE_FAMILY_NAME_MAX_LENGTH + 1]{}; + UINT32 packageFamilyNameLength{ ARRAYSIZE(packageFamilyName) }; + THROW_IF_WIN32_ERROR_MSG(::PackageFamilyNameFromFullName(packageFullName, &packageFamilyNameLength, packageFamilyName), "%ls", packageFullName); + return T{ packageFamilyName }; +} } #endif // __APPMODEL_IDENTITY_H diff --git a/dev/Common/IsWindowsVersion.h b/dev/Common/IsWindowsVersion.h index 88ca801918..96b17a5684 100644 --- a/dev/Common/IsWindowsVersion.h +++ b/dev/Common/IsWindowsVersion.h @@ -55,7 +55,7 @@ inline bool IsWindows11_22H2OrGreater() inline bool IsWindows11_23H1OrGreater() { // TryCreatePackageDependency2() added to in NTDDI_WIN10_GE (aka Windows 11 23H1) - return IsExportPresent(L"api-ms-win-appmodel-runtime-l1-1-7.dll", "TryCreatePackageDependency2"); + return IsExportPresent(L"kernelbase.dll", "TryCreatePackageDependency2"); } } diff --git a/dev/Common/Security.User.h b/dev/Common/Security.User.h index 87e7d0d8c2..c37fdafcac 100644 --- a/dev/Common/Security.User.h +++ b/dev/Common/Security.User.h @@ -18,6 +18,32 @@ inline bool IsLocalSystem(HANDLE token = nullptr) return !!EqualSid(userSid, localSystemSid); } + +/// @return sid. Allocated via LocalAlloc; use LocalFree to deallocate +inline PSID StringToSid(PCWSTR sidString) +{ + if (!sidString || (sidString[0] == L'\0')) + { + return nullptr; + } + + PSID sid{}; + THROW_IF_WIN32_BOOL_FALSE(::ConvertStringSidToSidW(sidString, &sid)); + return sid; +} + +/// @return sid as a string. Allocated via LocalAlloc; use LocalFree to deallocate +inline PWSTR SidToString(PSID sid) +{ + if (!sid) + { + return nullptr; + } + + PWSTR sidString{}; + THROW_IF_WIN32_BOOL_FALSE(::ConvertSidToStringSidW(sid, &sidString)); + return sidString; +} } #endif // __SECURITY_USER_H diff --git a/dev/Deployment/DeploymentManager.cpp b/dev/Deployment/DeploymentManager.cpp index fd8fee2b65..a744277b9a 100644 --- a/dev/Deployment/DeploymentManager.cpp +++ b/dev/Deployment/DeploymentManager.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation and Contributors. +// Copyright (c) Microsoft Corporation and Contributors. // Licensed under the MIT License. #include @@ -403,7 +403,7 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem HRESULT deploymentOperationHResult{}; HRESULT deploymentOperationExtendedHResult{}; - if (deploymentOperation.Status() != AsyncStatus::Completed) + if (deploymentOperation.Status() != winrt::Windows::Foundation::AsyncStatus::Completed) { deploymentOperationHResult = static_cast(deploymentOperation.ErrorCode()); deploymentOperationExtendedHResult = deploymentResult.ExtendedErrorCode(); diff --git a/dev/MRTCore/mrt/Core/unittests/packages.config b/dev/MRTCore/mrt/Core/unittests/packages.config index 1861ca894b..9749bd8146 100644 --- a/dev/MRTCore/mrt/Core/unittests/packages.config +++ b/dev/MRTCore/mrt/Core/unittests/packages.config @@ -1,4 +1,4 @@  - + diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/UnpackagedTests/packages.config b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/UnpackagedTests/packages.config index 11a9dacfc8..be237de8a7 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/UnpackagedTests/packages.config +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/UnpackagedTests/packages.config @@ -1,4 +1,4 @@  - + diff --git a/dev/MRTCore/mrt/mrm/UnitTests/packages.config b/dev/MRTCore/mrt/mrm/UnitTests/packages.config index 3a3c1cd7e9..c493267598 100644 --- a/dev/MRTCore/mrt/mrm/UnitTests/packages.config +++ b/dev/MRTCore/mrt/mrm/UnitTests/packages.config @@ -1,5 +1,5 @@  - + diff --git a/dev/PackageManager/API/M.W.M.D.EnsureReadyOptions.cpp b/dev/PackageManager/API/M.W.M.D.EnsureReadyOptions.cpp index c0a3075a4d..8c6a3ba5a0 100644 --- a/dev/PackageManager/API/M.W.M.D.EnsureReadyOptions.cpp +++ b/dev/PackageManager/API/M.W.M.D.EnsureReadyOptions.cpp @@ -14,4 +14,12 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation { return m_addPackageOptions; } + bool EnsureReadyOptions::RegisterNewerIfAvailable() + { + return m_registerNewerIfAvailable; + } + void EnsureReadyOptions::RegisterNewerIfAvailable(bool value) + { + m_registerNewerIfAvailable = value; + } } diff --git a/dev/PackageManager/API/M.W.M.D.EnsureReadyOptions.h b/dev/PackageManager/API/M.W.M.D.EnsureReadyOptions.h index 85d288fcbe..d68d126e7d 100644 --- a/dev/PackageManager/API/M.W.M.D.EnsureReadyOptions.h +++ b/dev/PackageManager/API/M.W.M.D.EnsureReadyOptions.h @@ -12,8 +12,11 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation EnsureReadyOptions() = default; winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions AddPackageOptions(); + bool RegisterNewerIfAvailable(); + void RegisterNewerIfAvailable(bool value); private: winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions m_addPackageOptions{}; + bool m_registerNewerIfAvailable{}; }; } namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp index 149e09b811..9615c01650 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp @@ -11,6 +11,29 @@ #include "PackageManagerTelemetry.h" +#include +#include +#include +#if defined(NTDDI_WIN11_GE) +# define TODO_UpdatedWindowsSDK_with_Windows_Management_Deployment_IRemovePackageOptions +#endif +#if !defined(TODO_UpdatedWindowsSDK_with_Windows_Management_Deployment_IRemovePackageOptions) +// Until we have access to the updated Windows SDK we can't use RemovePackageOptions +// but we need *something* to satisfy PackageManagement_RemovePackageByUriAsync() in the FrameworkUDK +// so we'll make a placeholder definition to satisfy the compiler enough to let us call +// PackageManagement_RemovePackageByUriAsync2(uri, nullptr). Remove this once the updated +// Windows SDK makes this unnecessary. +namespace ABI::Windows::Management::Deployment +{ + typedef void * IRemovePackageOptions; +} +#endif +// +#include +#include + +#include + static_assert(static_cast(winrt::Microsoft::Windows::Management::Deployment::StubPackageOption::Default) == static_cast(winrt::Windows::Management::Deployment::StubPackageOption::Default), "winrt::Microsoft::Windows::Management::Deployment::StubPackageOption::Default != winrt::Windows::Management::Deployment::StubPackageOption::Default"); static_assert(static_cast(winrt::Microsoft::Windows::Management::Deployment::StubPackageOption::InstallFull) == static_cast(winrt::Windows::Management::Deployment::StubPackageOption::InstallFull), @@ -20,12 +43,125 @@ static_assert(static_cast(winrt::Microsoft::Windows::Management::Deployment static_assert(static_cast(winrt::Microsoft::Windows::Management::Deployment::StubPackageOption::UsePreference) == static_cast(winrt::Windows::Management::Deployment::StubPackageOption::UsePreference), "winrt::Microsoft::Windows::Management::Deployment::StubPackageOption::UsePreference != winrt::Windows::Management::Deployment::StubPackageOption::UsePreference"); +static PackageManagement_ArchitectureType ToArchitectureType(const winrt::Windows::System::ProcessorArchitecture architecture) +{ + switch (architecture) + { + case winrt::Windows::System::ProcessorArchitecture::X86: return PackageManagement_ArchitectureType_X86; + case winrt::Windows::System::ProcessorArchitecture::Arm: return PackageManagement_ArchitectureType_Arm; + case winrt::Windows::System::ProcessorArchitecture::X64: return PackageManagement_ArchitectureType_X64; + case winrt::Windows::System::ProcessorArchitecture::Neutral: return PackageManagement_ArchitectureType_Neutral; + case winrt::Windows::System::ProcessorArchitecture::Arm64: return PackageManagement_ArchitectureType_Arm64; + case winrt::Windows::System::ProcessorArchitecture::X86OnArm64: return PackageManagement_ArchitectureType_X86A64; + case winrt::Windows::System::ProcessorArchitecture::Unknown: return PackageManagement_ArchitectureType_Unknown; + default: THROW_HR_MSG(E_UNEXPECTED, "%d", static_cast(architecture)); + } +} + +namespace winrt::Microsoft::Windows::ApplicationModel::DynamicDependency +{ + DEFINE_ENUM_FLAG_OPERATORS(PackageDependencyProcessorArchitectures) +} +static PackageManagement_ArchitectureType ToArchitectureType(const winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures processorArchitectureFilter) +{ + auto architectureType{ PackageManagement_ArchitectureType_None }; + if (WI_IsFlagSet(processorArchitectureFilter, winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::Neutral)) + { + architectureType |= PackageManagement_ArchitectureType_Neutral; + } + if (WI_IsFlagSet(processorArchitectureFilter, winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::X86)) + { + architectureType |= PackageManagement_ArchitectureType_X86; + } + if (WI_IsFlagSet(processorArchitectureFilter, winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::X64)) + { + architectureType |= PackageManagement_ArchitectureType_X64; + } + if (WI_IsFlagSet(processorArchitectureFilter, winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::Arm)) + { + architectureType |= PackageManagement_ArchitectureType_Arm; + } + if (WI_IsFlagSet(processorArchitectureFilter, winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::Arm64)) + { + architectureType |= PackageManagement_ArchitectureType_Arm64; + } + if (WI_IsFlagSet(processorArchitectureFilter, winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::X86OnArm64)) + { + architectureType |= PackageManagement_ArchitectureType_X86A64; + } + return architectureType; +} + +static winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures ToPackageDependencyProcessorArchitectures(const winrt::Windows::System::ProcessorArchitecture architecture) +{ + switch (architecture) + { + case winrt::Windows::System::ProcessorArchitecture::X86: return winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::X86; + case winrt::Windows::System::ProcessorArchitecture::X64: return winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::X64; + case winrt::Windows::System::ProcessorArchitecture::Arm: return winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::Arm; + case winrt::Windows::System::ProcessorArchitecture::Arm64: return winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::Arm64; + case winrt::Windows::System::ProcessorArchitecture::X86OnArm64: return winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::X86OnArm64; + case winrt::Windows::System::ProcessorArchitecture::Neutral: return winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::PackageDependencyProcessorArchitectures::Neutral; + case winrt::Windows::System::ProcessorArchitecture::Unknown: THROW_HR_MSG(E_UNEXPECTED, "Unsupported architecture 0x%X", architecture); + default: THROW_HR_MSG(E_UNEXPECTED, "Unknown architecture 0x%X", architecture); + } +} + namespace winrt::Microsoft::Windows::Management::Deployment::implementation { winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager PackageDeploymentManager::GetDefault() { return winrt::make(); } + bool PackageDeploymentManager::IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature feature) + { + switch (feature) + { + case winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup: + { + //TODO Feature lookup + // Relies on PackageManagement_IsFeatureSupported(L"PackageUriScheme.ms-uup") exist in Microsoft.FrameworkUdk and enabled + return ::WindowsVersion::IsExportPresent(L"appxdeploymentclient.dll", "MsixRemovePackageByUriAsync"); + } + case winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::IsPackageReadyOrNewerAvailable: + { + //TODO Feature lookup + // Relies on PackageManagement_IsFeatureSupported(L"IsPackageReadyOrNewerAvailable") exist in Microsoft.FrameworkUdk and enabled + return false; + } + case winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::RemovePackageByUri: + { + //TODO Awaiting Platform SDK defining RemovePackageOptions + //return ::WindowsVersion::IsExportPresent(L"appxdeploymentclient.dll", "MsixRemovePackageByUriAsync"); + return false; + } + case winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ResetPackage: + { + return ::WindowsVersion::IsExportPresent(L"appxdeploymentclient.dll", "MsixResetPackageAsync"); + } + case winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::RepairPackage: + { + return ::WindowsVersion::IsExportPresent(L"appxdeploymentclient.dll", "MsixRepairPackageAsync"); + } + case winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ProvisionPackage_Framework: + { + //TODO Awaiting ProvisionPackageForAllUsersAsync() support for Framework packages + //return IsPackageDeploymentFeatureSupported(L"ProvisionPackage.Framework"); + return false; + } + default: + { + (void)LOG_HR_MSG(E_UNEXPECTED, "Feature:%d", static_cast(feature)); + return false; + } + } + } + bool PackageDeploymentManager::IsPackageDeploymentFeatureSupported(PCWSTR feature) + { + BOOL isSupported{}; + THROW_IF_FAILED_MSG(PackageManagement_IsFeatureSupported(feature, &isSupported), "%s", feature); + return !!isSupported; + } bool PackageDeploymentManager::IsPackageReady(hstring const& package) { if (VerifyPackageFullName(package.c_str()) == ERROR_SUCCESS) @@ -43,12 +179,32 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation } bool PackageDeploymentManager::IsPackageReadyByUri(winrt::Windows::Foundation::Uri const& packageUri) { - //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() - throw hresult_not_implemented(); + // Currently supported URI schemes: ms-uup + const auto packageFullNames{ GetPackageFullNamesFromUupProductUriIfMsUup(packageUri) }; + if (!packageFullNames) + { + // Currently supported URI schemes: ms-uup + if (!IsUriScheme_MsUup(packageUri)) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup)); + } + + // Ready UUP Products always have 1+ package so no packages found means not ready + return false; + } + + for (PCWSTR packageFullName : packageFullNames) + { + if (!IsReadyByPackageFullName(packageFullName)) + { + return false; + } + } + return true; } bool PackageDeploymentManager::IsPackageSetReady(winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) { - Validate(packageSet); + Validate_PackageUriIsOptional(packageSet); for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSet.Items()) { @@ -69,6 +225,118 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation } return true; } + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus PackageDeploymentManager::IsPackageReadyOrNewerAvailable(hstring const& package) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::IsPackageReadyOrNewerAvailable)); + + if (VerifyPackageFullName(package.c_str()) == ERROR_SUCCESS) + { + return IsReadyOrNewerAvailableByPackageFullName(package.c_str()); + } + + const winrt::Windows::Foundation::Uri packageUri{ package }; + const auto packageAbsoluteUri{ packageUri.AbsoluteUri() }; + if (!packageAbsoluteUri.empty()) + { + return IsPackageReadyOrNewerAvailableByUri(packageUri); + } + THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str()); + } + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus PackageDeploymentManager::IsPackageReadyOrNewerAvailableByUri(winrt::Windows::Foundation::Uri const& packageUri) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::IsPackageReadyOrNewerAvailable)); + + // Currently supported URI schemes: ms-uup + const auto schemeName{ packageUri.SchemeName() }; + const auto uupProductId{ GetUupProductIdIfMsUup(packageUri) }; + if (uupProductId.empty()) + { + // Currently supported URI schemes: ms-uup + if (!IsUriScheme_MsUup(packageUri)) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup)); + } + + // Ready UUP Products always have 1+ package so no packages found means not ready + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady; + } + + wil::unique_cotaskmem_array_ptr packageFullNames; + THROW_IF_FAILED_MSG(Uup_SRFindPackageFullNamesByUupProductId(uupProductId.c_str(), packageFullNames.size_address(), packageFullNames.addressof()), "%s", uupProductId.c_str()); + + bool anyNewerAvailable{}; + const auto packageUriAsString{ packageUri.ToString() }; + for (PCWSTR packageFullName : packageFullNames) + { + const auto packageIdentity{ ::AppModel::Identity::PackageIdentity::FromPackageFullName(packageFullName) }; + const auto packageFamilyName{ packageIdentity.PackageFamilyName() }; + const auto minVersion{ packageIdentity.Version().Version }; + const auto architectureType{ ToArchitectureType(packageIdentity.Architecture()) }; + BOOL isRegistered{}; + BOOL isNewerAvailable{}; + THROW_IF_FAILED_MSG(PackageManagement_IsRegisteredOrNewerAvailable(nullptr, packageFamilyName.c_str(), minVersion, architectureType, &isRegistered, &isNewerAvailable), "%s", packageUriAsString.c_str()); + if (!isRegistered) + { + // At least one package isn't ready so we have our answer + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady; + } + if (!anyNewerAvailable & !!isNewerAvailable) + { + anyNewerAvailable = true; + } + } + if (anyNewerAvailable) + { + // All packages are registered but at least 1 has a newer version available + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable; + } + + // All packages are registered and none have anything newer avaiable + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready; + } + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus PackageDeploymentManager::IsPackageSetReadyOrNewerAvailable(winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::IsPackageReadyOrNewerAvailable)); + + Validate_PackageUriIsOptional(packageSet); + + bool newerAvailable{}; + for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSet.Items()) + { + const auto status{ IsReadyOrNewerAvailable(packageSetItem) }; + if (status == winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady) + { + const ::AppModel::Identity::PackageVersion minVersion{ packageSetItem.MinVersion() }; + TraceLoggingWrite( + PackageManagementTelemetryProvider::Provider(), + "PackageDeployment.Resolver.NotFound", + TraceLoggingWideString(packageSetItem.Id().c_str(), "Criteria.Id"), + TraceLoggingWideString(packageSetItem.PackageFamilyName().c_str(), "Criteria.PackageFamilyName"), + TraceLoggingHexUInt64(minVersion.Version, "Criteria.MinVersion"), + TraceLoggingHexInt32(static_cast(packageSetItem.ProcessorArchitectureFilter()), "Criteria.ArchitectureFilter"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady; + } + if (!newerAvailable && (status == winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable)) + { + const ::AppModel::Identity::PackageVersion minVersion{ packageSetItem.MinVersion() }; + TraceLoggingWrite( + PackageManagementTelemetryProvider::Provider(), + "PackageDeployment.Resolver.NewerAvailable", + TraceLoggingWideString(packageSetItem.Id().c_str(), "Criteria.Id"), + TraceLoggingWideString(packageSetItem.PackageFamilyName().c_str(), "Criteria.PackageFamilyName"), + TraceLoggingHexUInt64(minVersion.Version, "Criteria.MinVersion"), + TraceLoggingHexInt32(static_cast(packageSetItem.ProcessorArchitectureFilter()), "Criteria.ArchitectureFilter"), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); + newerAvailable = true; + } + } + return newerAvailable ? + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable : + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready; + } winrt::Windows::Foundation::IAsyncOperationWithProgress PackageDeploymentManager::EnsurePackageReadyAsync(hstring package, winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options) { @@ -83,8 +351,45 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Windows::Foundation::IAsyncOperationWithProgress PackageDeploymentManager::EnsurePackageReadyByUriAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options) { - //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() - throw hresult_not_implemented(); + // Currently supported URI schemes: ms-uup + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup)); + + // Create a PackageSet for the URI + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + const auto packageFullNames{ GetPackageFullNamesFromUupProductUriIfMsUup(packageUri) }; + if (packageFullNames) + { + packageSet.Id(packageUri.ToString()); + packageSet.PackageUri(packageUri); + auto packageSetItems{ packageSet.Items() }; + for (PCWSTR packageFullName : packageFullNames) + { + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + packageSetItem.Id(packageFullName); + const auto packageIdentity{ ::AppModel::Identity::PackageIdentity::FromPackageFullName(packageFullName) }; + packageSetItem.PackageFamilyName(packageIdentity.PackageFamilyName().c_str()); + const ::AppModel::Identity::PackageVersion minVersion{ packageIdentity.Version() }; + packageSetItem.MinVersion(minVersion.ToWinrtPackageVersion()); + const auto processorArchitectureFilter{ ToPackageDependencyProcessorArchitectures(packageIdentity.Architecture()) }; + packageSetItem.ProcessorArchitectureFilter(processorArchitectureFilter); + packageSetItems.Append(packageSetItem); + } + } + + auto logTelemetry{ PackageManagementTelemetry::EnsurePackageReadyByUriAsync::Start(packageUri.ToString()) }; + + if (packageSet.Id().empty()) + { + // Package URI isn't known to the system so it's an add or bust + co_return co_await AddPackageByUriAsync(packageUri, options.AddPackageOptions()); + } + else + { + // Package URI is known so process the PackageSet + co_return co_await EnsurePackageSetReadyAsync(packageSet, options); + } + + logTelemetry.Stop(packageUri.ToString()); } winrt::Windows::Foundation::IAsyncOperationWithProgress PackageDeploymentManager::EnsurePackageSetReadyAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet, winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options) @@ -108,7 +413,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation progress(packageDeploymentProgress); // Check parameter(s) - Validate(packageSet); + Validate_PackageUriIsRequired(packageSet); // Is there any work to do? packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; @@ -132,10 +437,10 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) { const auto packageFamilyName{ packageSetItem.PackageFamilyName() }; - const auto packageUri{ packageSetItem.PackageUri() }; + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; try { - error = LOG_IF_FAILED_MSG(EnsureReadyAsync(packageSetItem, options, packageDeploymentProgress, progress, extendedError, errorText, activityId), + error = LOG_IF_FAILED_MSG(EnsureReadyAsync(packageUri, packageSetItem, options, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), "Error:0x%08X (0x%08X) PackageFamilyName:%ls PackageUri:%ls : %ls", error, extendedError, packageFamilyName.c_str(), packageUri.ToString().c_str(), errorText.c_str()); } @@ -196,17 +501,15 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageDeploymentProgressStatus::Queued, 0} }; progress(packageDeploymentProgress); - // Check parameter(s) - //TODO Validate(packageSet); - winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; + const double progressMaxPerPackage{ 1.0 }; HRESULT error{}; HRESULT extendedError{}; winrt::hstring errorText; winrt::guid activityId{}; try { - error = LOG_IF_FAILED_MSG(AddPackage(packageUri, addOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId), + error = LOG_IF_FAILED_MSG(AddPackage(packageUri, addOptions, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageUri.ToString().c_str()); } @@ -247,7 +550,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation progress(packageDeploymentProgress); // Check parameter(s) - Validate(packageSet); + Validate_PackageUriIsRequired(packageSet); packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; const double c_progressPercentageStartOfInstalls{ 0.10 }; @@ -261,18 +564,24 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::guid activityId{}; for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) { + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; try { - error = LOG_IF_FAILED_MSG(AddPackage(packageSetItem, options, packageDeploymentProgress, progress, extendedError, errorText, activityId), + const auto progressBeforePackage{ packageDeploymentProgress.Progress }; + error = LOG_IF_FAILED_MSG(AddPackage(packageUri, options, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", - extendedError, packageSetItem.PackageFamilyName().c_str(), packageSetItem.PackageUri().ToString().c_str()); - packageDeploymentProgress.Progress = packageDeploymentProgress.Progress + progressIncrementPerPackageSetItem; - progress(packageDeploymentProgress); + extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str()); + const auto progressAfterPackage{ progressBeforePackage + progressIncrementPerPackageSetItem }; + if (packageDeploymentProgress.Progress < progressAfterPackage) + { + packageDeploymentProgress.Progress = progressAfterPackage; + progress(packageDeploymentProgress); + } } catch (...) { const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; - error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageSetItem.PackageFamilyName().c_str(), packageSetItem.PackageUri().ToString().c_str()); + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str()); } if (FAILED(error)) { @@ -317,17 +626,15 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageDeploymentProgressStatus::Queued, 0} }; progress(packageDeploymentProgress); - // Check parameter(s) - //TODO Validate(packageSet); - winrt::Windows::Management::Deployment::StagePackageOptions stageOptions{ ToOptions(options) }; + const double progressMaxPerPackage{ 1.0 }; HRESULT error{}; HRESULT extendedError{}; winrt::hstring errorText; winrt::guid activityId{}; try { - error = LOG_IF_FAILED_MSG(StagePackage(packageUri, stageOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId), + error = LOG_IF_FAILED_MSG(StagePackage(packageUri, stageOptions, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageUri.ToString().c_str()); } @@ -368,7 +675,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation progress(packageDeploymentProgress); // Check parameter(s) - Validate(packageSet); + Validate_PackageUriIsRequired(packageSet); packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; const double c_progressPercentageStartOfInstalls{ 0.10 }; @@ -382,18 +689,24 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::guid activityId{}; for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) { + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; try { - error = LOG_IF_FAILED_MSG(StagePackage(packageSetItem, options, packageDeploymentProgress, progress, extendedError, errorText, activityId), + const auto progressBeforePackage{ packageDeploymentProgress.Progress }; + error = LOG_IF_FAILED_MSG(StagePackage(packageUri, options, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", - extendedError, packageSetItem.PackageFamilyName().c_str(), packageSetItem.PackageUri().ToString().c_str()); - packageDeploymentProgress.Progress = packageDeploymentProgress.Progress + progressIncrementPerPackageSetItem; - progress(packageDeploymentProgress); + extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str()); + const auto progressAfterPackage{ progressBeforePackage + progressIncrementPerPackageSetItem }; + if (packageDeploymentProgress.Progress < progressAfterPackage) + { + packageDeploymentProgress.Progress = progressAfterPackage; + progress(packageDeploymentProgress); + } } catch (...) { const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; - error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageSetItem.PackageFamilyName().c_str(), packageSetItem.PackageUri().ToString().c_str()); + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str()); } if (FAILED(error)) { @@ -411,11 +724,11 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation { if (VerifyPackageFamilyName(package.c_str()) == ERROR_SUCCESS) { - return RegisterPackageByPackageFullNameAsync(package, options); + return RegisterPackageByPackageFamilyNameAsync(package, options); } else if (VerifyPackageFullName(package.c_str()) == ERROR_SUCCESS) { - return RegisterPackageByPackageFamilyNameAsync(package, options); + return RegisterPackageByPackageFullNameAsync(package, options); } const winrt::Windows::Foundation::Uri packageUri{ package }; @@ -448,17 +761,15 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageDeploymentProgressStatus::Queued, 0} }; progress(packageDeploymentProgress); - // Check parameter(s) - //TODO Validate(packageSet); - winrt::Windows::Management::Deployment::RegisterPackageOptions registerOptions{ ToOptions(options) }; + const double progressMaxPerPackage{ 1.0 }; HRESULT error{}; HRESULT extendedError{}; winrt::hstring errorText; winrt::guid activityId{}; try { - error = LOG_IF_FAILED_MSG(RegisterPackage(packageUri, registerOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId), + error = LOG_IF_FAILED_MSG(RegisterPackage(packageUri, registerOptions, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageUri.ToString().c_str()); } @@ -499,7 +810,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation progress(packageDeploymentProgress); // Check parameter(s) - Validate(packageSet); + Validate_PackageUriIsRequired(packageSet); packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; const double c_progressPercentageStartOfInstalls{ 0.10 }; @@ -513,18 +824,24 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::guid activityId{}; for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) { + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; try { - error = LOG_IF_FAILED_MSG(RegisterPackage(packageSetItem, options, packageDeploymentProgress, progress, extendedError, errorText, activityId), + const auto progressBeforePackage{ packageDeploymentProgress.Progress }; + error = LOG_IF_FAILED_MSG(RegisterPackage(packageUri, options, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", - extendedError, packageSetItem.PackageFamilyName().c_str(), packageSetItem.PackageUri().ToString().c_str()); - packageDeploymentProgress.Progress = packageDeploymentProgress.Progress + progressIncrementPerPackageSetItem; - progress(packageDeploymentProgress); + extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str()); + const auto progressAfterPackage{ progressBeforePackage + progressIncrementPerPackageSetItem }; + if (packageDeploymentProgress.Progress < progressAfterPackage) + { + packageDeploymentProgress.Progress = progressAfterPackage; + progress(packageDeploymentProgress); + } } catch (...) { const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; - error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageSetItem.PackageFamilyName().c_str(), packageSetItem.PackageUri().ToString().c_str()); + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str()); } if (FAILED(error)) { @@ -560,68 +877,656 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Windows::Foundation::IAsyncOperationWithProgress PackageDeploymentManager::RemovePackageByFullNameAsync(hstring packageFullName, winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options) { - //TODO Awaiting FrameworkUdk update with PackageManagement_RemovePackageByUriAsync() - throw hresult_not_implemented(); + auto logTelemetry{ PackageManagementTelemetry::RemovePackageAsync::Start(packageFullName) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + winrt::Windows::Management::Deployment::RemovalOptions removeOptions{ ToOptions(options) }; + const double progressMaxPerPackage{ 1.0 }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + try + { + error = LOG_IF_FAILED_MSG(RemovePackageByFullName(packageFullName, options, removeOptions, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageUri:%ls", + extendedError, packageFullName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFullName.c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageFullName); } winrt::Windows::Foundation::IAsyncOperationWithProgress PackageDeploymentManager::RemovePackageByFamilyNameAsync(hstring packageFamilyName, winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options) { - //TODO Awaiting FrameworkUdk update with PackageManagement_RemovePackageByUriAsync() - throw hresult_not_implemented(); + auto logTelemetry{ PackageManagementTelemetry::RemovePackageAsync::Start(packageFamilyName) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + winrt::hstring packageFullName{ packageFamilyName }; + const double progressMaxPerPackageFamily{ 1.0 }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + try + { + error = LOG_IF_FAILED_MSG(RemovePackageByFamilyName(packageFamilyName, options, packageDeploymentProgress, progress, progressMaxPerPackageFamily, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls", + extendedError, packageFamilyName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls", extendedError, packageFamilyName.c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageFamilyName); } winrt::Windows::Foundation::IAsyncOperationWithProgress PackageDeploymentManager::RemovePackageByUriAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options) { - //TODO Awaiting FrameworkUdk update with PackageManagement_RemovePackageByUriAsync() - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::RemovePackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet, winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options) - { - //TODO Awaiting FrameworkUdk update with PackageManagement_RemovePackageByUriAsync() - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::ResetPackageAsync(hstring package) - { - //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() - throw hresult_not_implemented(); - } + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::RemovePackageByUri)); + + const winrt::hstring packageUriAsString{ packageUri.ToString() }; + auto logTelemetry{ PackageManagementTelemetry::RemovePackageByUriAsync::Start(packageUriAsString) }; + + // Check parameter(s) + if (IsUriScheme_MsUup(packageUri)) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup)); + } + else + { + // Other URI schemes not supported + THROW_HR_MSG(E_INVALIDARG, "%ls", packageUri.ToString().c_str()); + } + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + // Check parameter(s) + if (IsUriScheme_MsUup(packageUri)) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup)); + } + else + { + // Other URI schemes not supported + THROW_HR_MSG(E_INVALIDARG, "%ls", packageUri.ToString().c_str()); + } + + winrt::Windows::Management::Deployment::RemovalOptions removeOptions{ ToOptions(options) }; + const double progressMaxPerPackage{ 1.0 }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + try + { + error = LOG_IF_FAILED_MSG(RemovePackage(packageUri, removeOptions, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageUri:%ls", + extendedError, packageUri.ToString().c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageUri.ToString().c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageUriAsString); + } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::ResetPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri) + PackageDeploymentManager::RemovePackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet, winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options) { - //TODO Awaiting FrameworkUdk update with PackageManagement_ResetPackageAsync() - throw hresult_not_implemented(); + auto logTelemetry{ PackageManagementTelemetry::RemovePackageSetAsync::Start(packageSet.Id()) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + // Allow to register the progress and complete handler + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + // Check parameter(s) + Validate_PackageUriOrFamilyName(packageSet); + + packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; + const double c_progressPercentageStartOfInstalls{ 0.10 }; + packageDeploymentProgress.Progress = c_progressPercentageStartOfInstalls; + progress(packageDeploymentProgress); + auto packageSetItems{ packageSet.Items() }; + const double progressIncrementPerPackageSetItem{ (1.0 - c_progressPercentageStartOfInstalls) / packageSetItems.Size() }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) + { + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; + const auto packageFamilyName{ packageSetItem.PackageFamilyName() }; + try + { + const auto progressBeforePackage{ packageDeploymentProgress.Progress }; + if (packageUri) + { + error = LOG_IF_FAILED_MSG(RemovePackage(packageUri, options, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", + extendedError, packageFamilyName.c_str(), packageUri ? packageUri.ToString().c_str() : L""); + } + else + { + error = LOG_IF_FAILED_MSG(RemovePackageByFamilyName(packageFamilyName, options, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:", + extendedError, packageFamilyName.c_str()); + } + const auto progressAfterPackage{ progressBeforePackage + progressIncrementPerPackageSetItem }; + if (packageDeploymentProgress.Progress < progressAfterPackage) + { + packageDeploymentProgress.Progress = progressAfterPackage; + progress(packageDeploymentProgress); + } + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageFamilyName.c_str(), packageUri ? packageUri.ToString().c_str() : L""); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageSet.Id()); } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::ResetPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet) + PackageDeploymentManager::ResetPackageAsync(hstring package) { - //TODO Awaiting FrameworkUdk update with PackageManagement_ResetPackageAsync() - throw hresult_not_implemented(); + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ResetPackage)); + + if (VerifyPackageFamilyName(package.c_str()) == ERROR_SUCCESS) + { + return ResetPackageByFamilyNameAsync(package); + } + else if (VerifyPackageFullName(package.c_str()) == ERROR_SUCCESS) + { + return ResetPackageByFullNameAsync(package); + } + + const winrt::Windows::Foundation::Uri packageUri{ package }; + const auto packageAbsoluteUri{ packageUri.AbsoluteUri() }; + if (!packageAbsoluteUri.empty()) + { + return ResetPackageByUriAsync(packageUri); + } + THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str()); } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::RepairPackageAsync(hstring package) + PackageDeploymentManager::ResetPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri) { - //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() - throw hresult_not_implemented(); + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ResetPackage)); + + // Currently supported URI schemes: ms-uup + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup)); + + auto logTelemetry{ PackageManagementTelemetry::ResetPackageByUriAsync::Start(packageUri.ToString()) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + // Allow to register the progress and complete handler + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + // Create a PackageSet of (just) package family names for the URI + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + packageSet.Id(packageUri.ToString()); + const auto packageFullNames{ GetPackageFullNamesFromUupProductUriIfMsUup(packageUri) }; + if (packageFullNames.empty()) + { + const auto hr{ HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND) }; + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, GUID{}, hr, HRESULT_FROM_WIN32(ERROR_NOT_FOUND), winrt::impl::message_from_hresult(hr)); + } + + packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; + const double c_progressPercentageStartOfInstalls{ 0.10 }; + packageDeploymentProgress.Progress = c_progressPercentageStartOfInstalls; + progress(packageDeploymentProgress); + const double progressIncrementPerPackageSetItem{ (1.0 - c_progressPercentageStartOfInstalls) / packageFullNames.size() }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + const auto packageUriAsString{ packageUri.ToString() }; + for (PCWSTR packageFullName : packageFullNames) + { + try + { + const auto progressBeforePackage{ packageDeploymentProgress.Progress }; + error = LOG_IF_FAILED_MSG(ResetPackageByFullName(packageFullName, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFullName:%ls PackageUri:%ls", + extendedError, packageFullName, packageUriAsString.c_str()); + const auto progressAfterPackage{ progressBeforePackage + progressIncrementPerPackageSetItem }; + if (packageDeploymentProgress.Progress < progressAfterPackage) + { + packageDeploymentProgress.Progress = progressAfterPackage; + progress(packageDeploymentProgress); + } + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls PackageFamilyName:%ls PackageUri:%ls", + extendedError, packageFullName, packageUriAsString.c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageSet.Id()); } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::RepairPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri) + PackageDeploymentManager::ResetPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet) { - //TODO Awaiting FrameworkUdk update with PackageManagement_RepairPackageAsync() - throw hresult_not_implemented(); + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ResetPackage)); + + auto logTelemetry{ PackageManagementTelemetry::ResetPackageSetAsync::Start(packageSet.Id()) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + // Allow to register the progress and complete handler + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + // Check parameter(s) + Validate_PackageUriIsOptional(packageSet); + + packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; + const double c_progressPercentageStartOfInstalls{ 0.10 }; + packageDeploymentProgress.Progress = c_progressPercentageStartOfInstalls; + progress(packageDeploymentProgress); + auto packageSetItems{ packageSet.Items() }; + const double progressIncrementPerPackageSetItem{ (1.0 - c_progressPercentageStartOfInstalls) / packageSetItems.Size() }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) + { + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; + const auto packageFamilyName{ packageSetItem.PackageFamilyName() }; + try + { + const auto progressBeforePackage{ packageDeploymentProgress.Progress }; + error = LOG_IF_FAILED_MSG(ResetPackageByFamilyName(packageFamilyName, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:", + extendedError, packageFamilyName.c_str()); + const auto progressAfterPackage{ progressBeforePackage + progressIncrementPerPackageSetItem }; + if (packageDeploymentProgress.Progress < progressAfterPackage) + { + packageDeploymentProgress.Progress = progressAfterPackage; + progress(packageDeploymentProgress); + } + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageFamilyName.c_str(), packageUri ? packageUri.ToString().c_str() : L""); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageSet.Id()); } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::RepairPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet) + PackageDeploymentManager::RepairPackageAsync(hstring package) { - //TODO Awaiting FrameworkUdk update with PackageManagement_RepairPackageAsync() - throw hresult_not_implemented(); + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::RepairPackage)); + + if (VerifyPackageFamilyName(package.c_str()) == ERROR_SUCCESS) + { + return RepairPackageByFamilyNameAsync(package); + } + else if (VerifyPackageFullName(package.c_str()) == ERROR_SUCCESS) + { + return RepairPackageByFullNameAsync(package); + } + + const winrt::Windows::Foundation::Uri packageUri{ package }; + const auto packageAbsoluteUri{ packageUri.AbsoluteUri() }; + if (!packageAbsoluteUri.empty()) + { + return RepairPackageByUriAsync(packageUri); + } + THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str()); + } + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::RepairPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::RepairPackage)); + + // Currently supported URI schemes: ms-uup + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup)); + + auto logTelemetry{ PackageManagementTelemetry::RepairPackageByUriAsync::Start(packageUri.ToString()) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + // Allow to register the progress and complete handler + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + // Create a PackageSet of (just) package family names for the URI + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + packageSet.Id(packageUri.ToString()); + const auto packageFullNames{ GetPackageFullNamesFromUupProductUriIfMsUup(packageUri) }; + if (packageFullNames.empty()) + { + const auto hr{ HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND) }; + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, GUID{}, hr, HRESULT_FROM_WIN32(ERROR_NOT_FOUND), winrt::impl::message_from_hresult(hr)); + } + + packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; + const double c_progressPercentageStartOfInstalls{ 0.10 }; + packageDeploymentProgress.Progress = c_progressPercentageStartOfInstalls; + progress(packageDeploymentProgress); + const double progressIncrementPerPackageSetItem{ (1.0 - c_progressPercentageStartOfInstalls) / packageFullNames.size() }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + const auto packageUriAsString{ packageUri.ToString() }; + for (PCWSTR packageFullName : packageFullNames) + { + try + { + const auto progressBeforePackage{ packageDeploymentProgress.Progress }; + error = LOG_IF_FAILED_MSG(RepairPackageByFullName(packageFullName, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFullName:%ls PackageUri:%ls", + extendedError, packageFullName, packageUriAsString.c_str()); + const auto progressAfterPackage{ progressBeforePackage + progressIncrementPerPackageSetItem }; + if (packageDeploymentProgress.Progress < progressAfterPackage) + { + packageDeploymentProgress.Progress = progressAfterPackage; + progress(packageDeploymentProgress); + } + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls PackageFamilyName:%ls PackageUri:%ls", + extendedError, packageFullName, packageUriAsString.c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageSet.Id()); + } + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::RepairPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::RepairPackage)); + + auto logTelemetry{ PackageManagementTelemetry::RepairPackageSetAsync::Start(packageSet.Id()) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + // Allow to register the progress and complete handler + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + // Check parameter(s) + Validate_PackageUriIsOptional(packageSet); + + packageDeploymentProgress.Status = PackageDeploymentProgressStatus::InProgress; + const double c_progressPercentageStartOfInstalls{ 0.10 }; + packageDeploymentProgress.Progress = c_progressPercentageStartOfInstalls; + progress(packageDeploymentProgress); + auto packageSetItems{ packageSet.Items() }; + const double progressIncrementPerPackageSetItem{ (1.0 - c_progressPercentageStartOfInstalls) / packageSetItems.Size() }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) + { + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; + const auto packageFamilyName{ packageSetItem.PackageFamilyName() }; + try + { + const auto progressBeforePackage{ packageDeploymentProgress.Progress }; + error = LOG_IF_FAILED_MSG(RepairPackageByFamilyName(packageFamilyName, packageDeploymentProgress, progress, progressIncrementPerPackageSetItem, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:", + extendedError, packageFamilyName.c_str()); + const auto progressAfterPackage{ progressBeforePackage + progressIncrementPerPackageSetItem }; + if (packageDeploymentProgress.Progress < progressAfterPackage) + { + packageDeploymentProgress.Progress = progressAfterPackage; + progress(packageDeploymentProgress); + } + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls", extendedError, packageFamilyName.c_str(), packageUri ? packageUri.ToString().c_str() : L""); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageSet.Id()); + } + bool PackageDeploymentManager::IsPackageProvisioned(hstring const& package) + { + if (VerifyPackageFamilyName(package.c_str()) == ERROR_SUCCESS) + { + return IsProvisionedByPackageFamilyName(package); + } + + const winrt::Windows::Foundation::Uri packageUri{ package }; + const auto packageAbsoluteUri{ packageUri.AbsoluteUri() }; + if (!packageAbsoluteUri.empty()) + { + return IsPackageProvisionedByUri(packageUri); + } + THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str()); + } + bool PackageDeploymentManager::IsPackageProvisionedByUri(winrt::Windows::Foundation::Uri const& packageUri) + { + const auto packageFullNames{ GetPackageFullNamesFromUupProductUriIfMsUup(packageUri) }; + if (!packageFullNames) + { + // Currently supported URI schemes: ms-uup + if (!IsUriScheme_MsUup(packageUri)) + { + THROW_HR_IF(E_NOTIMPL, !IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup)); + } + + // Provisioned UUP Products always have 1+ package so no packages found means not provisioned + return false; + } + + for (PCWSTR packageFullName : packageFullNames) + { + // Provisioning is based on package family but we only know package full names for the URI + // Use the package's family name for the actual provisioning check + const auto packageFamilyName{ ::AppModel::Identity::ToPackageFamilyName(packageFullName) }; + if (!IsProvisionedByPackageFamilyName(packageFamilyName)) + { + return false; + } + } + return true; + } + bool PackageDeploymentManager::IsPackageSetProvisioned(winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) + { + Validate_PackageUriIsOptional(packageSet); + + const auto provisionedPackages{ m_packageManager.FindProvisionedPackages() }; + for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSet.Items()) + { + if (!IsProvisioned(provisionedPackages, packageSetItem)) + { + return false; + } + } + return true; } winrt::Windows::Foundation::IAsyncOperationWithProgress PackageDeploymentManager::ProvisionPackageAsync(hstring package, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options) { - //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() - throw hresult_not_implemented(); + if (VerifyPackageFamilyName(package.c_str()) == ERROR_SUCCESS) + { + return ProvisionPackageByFamilyNameAsync(package, options); + } + + const winrt::Windows::Foundation::Uri packageUri{ package }; + const auto packageAbsoluteUri{ packageUri.AbsoluteUri() }; + if (!packageAbsoluteUri.empty()) + { + return ProvisionPackageByUriAsync(packageUri, options); + } + 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) @@ -635,52 +1540,1011 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() throw hresult_not_implemented(); } - winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::DeprovisionPackageAsync(hstring package) + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::DeprovisionPackageAsync(hstring package) + { + if (VerifyPackageFamilyName(package.c_str()) == ERROR_SUCCESS) + { + return DeprovisionPackageByFamilyNameAsync(package); + } + + const winrt::Windows::Foundation::Uri packageUri{ package }; + const auto packageAbsoluteUri{ packageUri.AbsoluteUri() }; + if (!packageAbsoluteUri.empty()) + { + return DeprovisionPackageByUriAsync(packageUri); + } + THROW_HR_MSG(E_INVALIDARG, "%ls", package.c_str()); + } + winrt::Windows::Foundation::IAsyncOperationWithProgress + 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) + { + //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() + throw hresult_not_implemented(); + } + bool PackageDeploymentManager::IsPackageRegistrationPending(hstring const& packageFullName) + { + return IsPackageRegistrationPendingForUser(nullptr, packageFullName.c_str()); + } + bool PackageDeploymentManager::IsPackageRegistrationPendingForUser(hstring const& userSecurityId, hstring const& packageFullName) + { + wil::unique_any_psid userSid{ ::Security::User::StringToSid(userSecurityId.c_str()) }; + return IsPackageRegistrationPendingForUser(userSid.get(), packageFullName.c_str()); + } + + bool PackageDeploymentManager::IsPackageRegistrationPendingForUser(PSID userSid, PCWSTR packageFullName) + { + BOOL isPending{}; + THROW_IF_FAILED(::PackageManagement_IsPackageRegistrationPending(userSid, packageFullName, &isPending)); + return !!isPending; + } + + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::AddPackageByAppInstallerFileAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options) + { + //TODO add via AddPackageByAppInstallerFileAsync() + throw hresult_not_implemented(); + } + + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::RegisterPackageByPackageFamilyNameAsync(winrt::hstring const& packageFamilyName, winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options) + { + auto logTelemetry{ PackageManagementTelemetry::RegisterPackageByPackageFamilyNameAsync::Start(packageFamilyName) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + // Allow to register the progress and complete handler + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + try + { + error = LOG_IF_FAILED_MSG(RegisterPackageByPackageFamilyName(packageFamilyName, options, packageDeploymentProgress, progress, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls", + extendedError, packageFamilyName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls", extendedError, packageFamilyName.c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageFamilyName); + } + + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::RegisterPackageByPackageFullNameAsync(winrt::hstring const& packageFullName, winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options) + { + auto logTelemetry{ PackageManagementTelemetry::RegisterPackageByPackageFullNameAsync::Start(packageFullName) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + // Allow to register the progress and complete handler + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + winrt::Windows::Management::Deployment::RegisterPackageOptions registerOptions{ ToOptions(options) }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + try + { + error = LOG_IF_FAILED_MSG(RegisterPackageByPackageFullName(packageFullName, registerOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFullName:%ls", + extendedError, packageFullName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFullName:%ls", extendedError, packageFullName.c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageFullName); + } + + winrt::hstring PackageDeploymentManager::GetUupProductIdIfMsUup(winrt::Windows::Foundation::Uri const& uri) const + { + if (IsUriScheme_MsUup(uri)) + { + // Support legacy behavior (for now) + // + // ms-uup://Product/id + const auto uriAsString{ uri.ToString() }; + const std::wstring_view legacyPrefix{ L"ms-uup://Product/" }; + if ((uriAsString.size() > legacyPrefix.length()) && + StringEqualsNoCase(uriAsString.c_str(), legacyPrefix.length(), legacyPrefix.data(), legacyPrefix.length())) + { + return uriAsString.begin() + legacyPrefix.length(); + } + + // ms-uup:///Product/id + if (uri.Host().empty()) + { + const auto path{ uri.Path() }; + const std::wstring_view c_product{ L"/Product/" }; + if ((path.size() > c_product.length()) && + StringEqualsNoCase(path.c_str(), c_product.length(), c_product.data(), c_product.length())) + { + return path.begin() + c_product.length(); + } + } + } + return winrt::hstring{}; + } + + wil::unique_cotaskmem_array_ptr PackageDeploymentManager::GetPackageFullNamesFromUupProductUriIfMsUup(winrt::Windows::Foundation::Uri const& uri) const + { + wil::unique_cotaskmem_array_ptr packageFullNames; + + const auto schemeName{ uri.SchemeName() }; + const auto uupProductId{ GetUupProductIdIfMsUup(uri) }; + if (!uupProductId.empty()) + { + THROW_IF_FAILED_MSG(Uup_SRFindPackageFullNamesByUupProductId(uupProductId.c_str(), packageFullNames.size_address(), packageFullNames.addressof()), "%s", uupProductId.c_str()); + } + return packageFullNames; + } + + bool PackageDeploymentManager::IsReadyByPackageFullName(hstring const& packageFullName) + { + const auto packageIdentity{ ::AppModel::Identity::PackageIdentity::FromPackageFullName(packageFullName.c_str()) }; + const winrt::hstring packageFamilyName{ packageIdentity.PackageFamilyName().c_str()}; + const AppModel::Identity::PackageVersion minVersion{ packageIdentity.Version() }; + const auto processorArchitectureFilter{ ToPackageDependencyProcessorArchitectures(packageIdentity.Architecture()) }; + return ::Microsoft::Windows::ApplicationModel::PackageDeploymentResolver::FindAny(m_packageManager, packageFamilyName, minVersion, processorArchitectureFilter); + } + + bool PackageDeploymentManager::IsReady(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) + { + const AppModel::Identity::PackageVersion minVersion{ packageSetItem.MinVersion() }; + const auto processorArchitectureFilter{ packageSetItem.ProcessorArchitectureFilter() }; + return ::Microsoft::Windows::ApplicationModel::PackageDeploymentResolver::FindAny(m_packageManager, packageSetItem.PackageFamilyName(), minVersion, processorArchitectureFilter); + } + + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus PackageDeploymentManager::IsReadyOrNewerAvailableByPackageFullName(hstring const& packageFullName) + { + const auto packageIdentity{ ::AppModel::Identity::PackageIdentity::FromPackageFullName(packageFullName.c_str()) }; + const auto packageFamilyName{ packageIdentity.PackageFamilyName() }; + const auto minVersion{ packageIdentity.Version().Version }; + const auto architectureType{ ToArchitectureType(packageIdentity.Architecture()) }; + BOOL isRegistered{}; + BOOL isNewerAvailable{}; + THROW_IF_FAILED_MSG(PackageManagement_IsRegisteredOrNewerAvailable(nullptr, packageFamilyName.c_str(), minVersion, architectureType, &isRegistered, &isNewerAvailable), "%s", packageFullName.c_str()); + if (!isRegistered) + { + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady; + } + else if (!isNewerAvailable) + { + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready; + } + else + { + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable; + } + } + + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus PackageDeploymentManager::IsReadyOrNewerAvailable(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) + { + const auto packageFamilyName{ packageSetItem.PackageFamilyName().c_str() }; + const AppModel::Identity::PackageVersion minVersion{ packageSetItem.MinVersion() }; + const auto architectureType{ ToArchitectureType(packageSetItem.ProcessorArchitectureFilter()) }; + BOOL isRegistered{}; + BOOL isNewerAvailable{}; + THROW_IF_FAILED_MSG(PackageManagement_IsRegisteredOrNewerAvailable(nullptr, packageFamilyName, minVersion.Version, architectureType, &isRegistered, &isNewerAvailable), "%ls", packageFamilyName); + if (!isRegistered) + { + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady; + } + else if (!isNewerAvailable) + { + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready; + } + else + { + return winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable; + } + } + + void PackageDeploymentManager::Validate_PackageUriIsRequired( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) const + { + return _Validate(packageSet, true); + } + + void PackageDeploymentManager::Validate_PackageUriIsOptional( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) const + { + return _Validate(packageSet, false); + } + + void PackageDeploymentManager::_Validate( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet, + const bool packageUriIsRequired) const + { + THROW_HR_IF(E_INVALIDARG, packageSet.Id().empty()); + const auto& packageSetItems{ packageSet.Items() }; + THROW_HR_IF(E_INVALIDARG, packageSetItems.Size() == 0); + for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) + { + _Validate(packageSet, packageSetItem, packageUriIsRequired); + } + } + + void PackageDeploymentManager::_Validate( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, + const bool packageUriIsRequired) const + { + const auto packageFamilyName{ packageSetItem.PackageFamilyName() }; + THROW_IF_WIN32_ERROR_MSG(VerifyPackageFamilyName(packageFamilyName.c_str()), "PackageFamilyName:%ls", packageFamilyName.c_str()); + + if (packageUriIsRequired) + { + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; + THROW_HR_IF_NULL_MSG(E_INVALIDARG, packageUri, "PackageUri:"); + } + } + + void PackageDeploymentManager::Validate_PackageUriOrFamilyName( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) const + { + THROW_HR_IF(E_INVALIDARG, packageSet.Id().empty()); + const auto& packageSetItems{ packageSet.Items() }; + THROW_HR_IF(E_INVALIDARG, packageSetItems.Size() == 0); + for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) + { + Validate_PackageUriOrFamilyName(packageSet, packageSetItem); + } + } + + void PackageDeploymentManager::Validate_PackageUriOrFamilyName( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) const + { + const auto packageUri{ GetEffectivePackageUri(packageSet, packageSetItem) }; + if (packageUri) + { + return; + } + + const auto packageFamilyName{ packageSetItem.PackageFamilyName() }; + THROW_IF_WIN32_ERROR_MSG(VerifyPackageFamilyName(packageFamilyName.c_str()), "PackageUri: PackageFamilyName:%ls", packageFamilyName.c_str()); + } + + HRESULT PackageDeploymentManager::EnsureReadyAsync( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageSetItem, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + if (IsReady(packageSetItem)) + { + return S_OK; + } + + winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; + const auto progressBefore{ packageDeploymentProgress.Progress }; + auto deploymentOperation{ m_packageManager.AddPackageByUriAsync(packageUri, addOptions) }; + deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< + winrt::Windows::Management::Deployment::DeploymentResult, + winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, + winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) + { + const auto progressAfter{ progressBefore + PercentageToProgress(progressInfo.percentage, progressMaxPerPackageSetItem) }; + if (packageDeploymentProgress.Progress < progressAfter) + { + packageDeploymentProgress.Progress = progressAfter; + progress(packageDeploymentProgress); + } + }); + deploymentOperation.get(); + try + { + const auto deploymentResult{ deploymentOperation.GetResults() }; + const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; + extendedError = deploymentResult.ExtendedErrorCode(); + errorText = deploymentResult.ErrorText(); + activityId = deploymentResult.ActivityId(); + const auto status{ deploymentOperation.Status() }; + if (status == winrt::Windows::Foundation::AsyncStatus::Error) + { + RETURN_IF_FAILED_MSG(error, + "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls : %ls", + extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str(), errorText.c_str()); + + // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. + FAIL_FAST_HR_MSG(E_UNEXPECTED, + "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls : %ls", + extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str(), errorText.c_str()); + } + else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) + { + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageUri.ToString().c_str()); + } + FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, + "Status:%d %ls", static_cast(status), packageUri.ToString().c_str()); + } + catch (...) + { + auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + THROW_HR_MSG(exception.code(), + "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls : %ls", + extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str(), errorText.c_str()); + } + return S_OK; + } + + HRESULT PackageDeploymentManager::AddPackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageSetItem, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; + RETURN_IF_FAILED(AddPackage(packageUri, addOptions, packageDeploymentProgress, progress, progressMaxPerPackageSetItem, extendedError, errorText, activityId)); + return S_OK; + } + + HRESULT PackageDeploymentManager::AddPackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Windows::Management::Deployment::AddPackageOptions const& addOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackage, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + const auto progressBefore{ packageDeploymentProgress.Progress }; + auto deploymentOperation{ m_packageManager.AddPackageByUriAsync(packageUri, addOptions) }; + deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< + winrt::Windows::Management::Deployment::DeploymentResult, + winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, + winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) + { + const auto progressAfter{ progressBefore + PercentageToProgress(progressInfo.percentage, progressMaxPerPackage) }; + if (packageDeploymentProgress.Progress < progressAfter) + { + packageDeploymentProgress.Progress = progressAfter; + progress(packageDeploymentProgress); + } + }); + deploymentOperation.get(); + try + { + const auto deploymentResult{ deploymentOperation.GetResults() }; + const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; + extendedError = deploymentResult.ExtendedErrorCode(); + errorText = deploymentResult.ErrorText(); + activityId = deploymentResult.ActivityId(); + const auto status{ deploymentOperation.Status() }; + if (status == winrt::Windows::Foundation::AsyncStatus::Error) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) + { + // Newer version already installed. Success! + (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + extendedError = error; + errorText.clear(); + return S_OK; + } + RETURN_IF_FAILED_MSG(error, + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + + // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. + FAIL_FAST_HR_MSG(E_UNEXPECTED, + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + } + else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) + { + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageUri.ToString().c_str()); + } + FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, + "Status:%d PackageUri:%ls : %ls", static_cast(status), packageUri.ToString().c_str(), errorText.c_str()); + } + catch (...) + { + auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + THROW_HR_MSG(exception.code(), + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + } + return S_OK; + } + + HRESULT PackageDeploymentManager::StagePackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageSetItem, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + winrt::Windows::Management::Deployment::StagePackageOptions stageOptions{ ToOptions(options) }; + RETURN_IF_FAILED(StagePackage(packageUri, stageOptions, packageDeploymentProgress, progress, progressMaxPerPackageSetItem, extendedError, errorText, activityId)); + return S_OK; + } + + HRESULT PackageDeploymentManager::StagePackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Windows::Management::Deployment::StagePackageOptions const& stageOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackage, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + const auto progressBefore{ packageDeploymentProgress.Progress }; + auto deploymentOperation{ m_packageManager.StagePackageByUriAsync(packageUri, stageOptions) }; + deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< + winrt::Windows::Management::Deployment::DeploymentResult, + winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, + winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) + { + const auto progressAfter{ progressBefore + PercentageToProgress(progressInfo.percentage, progressMaxPerPackage) }; + if (packageDeploymentProgress.Progress < progressAfter) + { + packageDeploymentProgress.Progress = progressAfter; + progress(packageDeploymentProgress); + } + }); + deploymentOperation.get(); + try + { + const auto deploymentResult{ deploymentOperation.GetResults() }; + const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; + extendedError = deploymentResult.ExtendedErrorCode(); + errorText = deploymentResult.ErrorText(); + activityId = deploymentResult.ActivityId(); + const auto status{ deploymentOperation.Status() }; + if (status == winrt::Windows::Foundation::AsyncStatus::Error) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) + { + // Newer version already installed. Success! + (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + extendedError = error; + errorText.clear(); + return S_OK; + } + RETURN_IF_FAILED_MSG(error, + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + + // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. + FAIL_FAST_HR_MSG(E_UNEXPECTED, + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + } + else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) + { + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageUri.ToString().c_str()); + } + FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, + "Status:%d PackageUri:%ls : %ls", static_cast(status), packageUri.ToString().c_str(), errorText.c_str()); + } + catch (...) + { + auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + THROW_HR_MSG(exception.code(), + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + } + return S_OK; + } + + HRESULT PackageDeploymentManager::RegisterPackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageSetItem, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + winrt::Windows::Management::Deployment::RegisterPackageOptions registerOptions{ ToOptions(options) }; + RETURN_IF_FAILED(RegisterPackage(packageUri, registerOptions, packageDeploymentProgress, progress, progressMaxPerPackageSetItem, extendedError, errorText, activityId)); + return S_OK; + } + + HRESULT PackageDeploymentManager::RegisterPackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Windows::Management::Deployment::RegisterPackageOptions const& registerOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackage, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + const auto progressBefore{ packageDeploymentProgress.Progress }; + auto deploymentOperation{ m_packageManager.RegisterPackageByUriAsync(packageUri, registerOptions) }; + deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< + winrt::Windows::Management::Deployment::DeploymentResult, + winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, + winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) + { + const auto progressAfter{ progressBefore + PercentageToProgress(progressInfo.percentage, progressMaxPerPackage) }; + if (packageDeploymentProgress.Progress < progressAfter) + { + packageDeploymentProgress.Progress = progressAfter; + progress(packageDeploymentProgress); + } + }); + deploymentOperation.get(); + try + { + const auto deploymentResult{ deploymentOperation.GetResults() }; + const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; + extendedError = deploymentResult.ExtendedErrorCode(); + errorText = deploymentResult.ErrorText(); + activityId = deploymentResult.ActivityId(); + const auto status{ deploymentOperation.Status() }; + if (status == winrt::Windows::Foundation::AsyncStatus::Error) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) + { + // Newer version already installed. Success! + (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + extendedError = error; + errorText.clear(); + return S_OK; + } + RETURN_IF_FAILED_MSG(error, + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + + // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. + FAIL_FAST_HR_MSG(E_UNEXPECTED, + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + } + else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) + { + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageUri.ToString().c_str()); + } + FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, + "Status:%d PackageUri:%ls : %ls", static_cast(status), packageUri.ToString().c_str(), errorText.c_str()); + } + catch (...) + { + auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + THROW_HR_MSG(exception.code(), + "ExtendedError:0x%08X PackageUri:%ls : %ls", + extendedError, packageUri.ToString().c_str(), errorText.c_str()); + } + return S_OK; + } + + HRESULT PackageDeploymentManager::RegisterPackageByPackageFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions const& registerOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + const auto deploymentOptions{ ToDeploymentOptions(registerOptions) }; + auto deploymentOperation{ m_packageManager.RegisterPackageByFamilyNameAsync(packageFamilyName, + registerOptions.DependencyPackageFamilyNames(), deploymentOptions, + ToPackageVolume(registerOptions.AppDataVolume()), registerOptions.OptionalPackageFamilyNames()) }; + deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< + winrt::Windows::Management::Deployment::DeploymentResult, + winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, + winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) + { + const double progressMaxPerPackageFamily{ 1.0 }; + packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage, progressMaxPerPackageFamily); + progress(packageDeploymentProgress); + }); + deploymentOperation.get(); + try + { + const auto deploymentResult{ deploymentOperation.GetResults() }; + const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; + extendedError = deploymentResult.ExtendedErrorCode(); + errorText = deploymentResult.ErrorText(); + activityId = deploymentResult.ActivityId(); + const auto status{ deploymentOperation.Status() }; + if (status == winrt::Windows::Foundation::AsyncStatus::Error) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) + { + // Newer version already installed. Success! + (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), + "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", + extendedError, packageFamilyName.c_str(), errorText.c_str()); + extendedError = error; + errorText.clear(); + return S_OK; + } + RETURN_IF_FAILED_MSG(error, + "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", + extendedError, packageFamilyName.c_str(), errorText.c_str()); + + // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. + FAIL_FAST_HR_MSG(E_UNEXPECTED, + "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", + extendedError, packageFamilyName.c_str(), errorText.c_str()); + } + else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) + { + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageFamilyName.c_str()); + } + FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, + "Status:%d PackageFamilyName:%ls : %ls", static_cast(status), packageFamilyName.c_str(), errorText.c_str()); + } + catch (...) + { + auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + THROW_HR_MSG(exception.code(), + "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", + extendedError, packageFamilyName.c_str(), errorText.c_str()); + } + return S_OK; + } + + HRESULT PackageDeploymentManager::RegisterPackageByPackageFullName( + winrt::hstring const& packageFullName, + winrt::Windows::Management::Deployment::RegisterPackageOptions const& registerOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) { - //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() - throw hresult_not_implemented(); + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + winrt::Windows::Foundation::Collections::IVector packageFullNames{ winrt::single_threaded_vector() }; + packageFullNames.Append(packageFullName); + auto deploymentOperation{ m_packageManager.RegisterPackagesByFullNameAsync(packageFullNames, registerOptions) }; + deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< + winrt::Windows::Management::Deployment::DeploymentResult, + winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, + winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) + { + const double progressMaxPerPackage{ 1.0 }; + packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage, progressMaxPerPackage); + progress(packageDeploymentProgress); + }); + deploymentOperation.get(); + try + { + const auto deploymentResult{ deploymentOperation.GetResults() }; + const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; + extendedError = deploymentResult.ExtendedErrorCode(); + errorText = deploymentResult.ErrorText(); + activityId = deploymentResult.ActivityId(); + const auto status{ deploymentOperation.Status() }; + if (status == winrt::Windows::Foundation::AsyncStatus::Error) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) + { + // Newer version already installed. Success! + (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); + extendedError = error; + errorText.clear(); + return S_OK; + } + RETURN_IF_FAILED_MSG(error, + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); + + // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. + FAIL_FAST_HR_MSG(E_UNEXPECTED, + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); + } + else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) + { + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageFullName.c_str()); + } + FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, + "Status:%d PackageFullName:%ls : %ls", static_cast(status), packageFullName.c_str(), errorText.c_str()); + } + catch (...) + { + auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + THROW_HR_MSG(exception.code(), + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); + } + return S_OK; } - winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::DeprovisionPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri) + + HRESULT PackageDeploymentManager::RemovePackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageSetItem, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) { - //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() - throw hresult_not_implemented(); + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + winrt::Windows::Management::Deployment::RemovalOptions removeOptions{ ToOptions(options) }; + RETURN_IF_FAILED(RemovePackage(packageUri, removeOptions, packageDeploymentProgress, progress, progressMaxPerPackageSetItem, extendedError, errorText, activityId)); + return S_OK; } - winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::DeprovisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet) + + HRESULT PackageDeploymentManager::RemovePackage( + winrt::Windows::Foundation::Uri const& /*packageUri*/, + winrt::Windows::Management::Deployment::RemovalOptions const& /*removeOptions*/, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& /*packageDeploymentProgress*/, + wistd::function /*progress*/, + const double /*progressMaxPerPackage*/, + HRESULT& /*extendedError*/, + winrt::hstring& /*errorText*/, + winrt::guid& /*activityId*/) { - //TODO Awaiting FrameworkUdk update with Uup_SRFindPackageFullNamesByUupProductId() - throw hresult_not_implemented(); + //TODO Awaiting Platform SDK defining RemovePackageOptions + RETURN_HR(E_NOTIMPL); } - bool PackageDeploymentManager::IsPackageRegistrationPending(hstring const& packageFamilyName) + + HRESULT PackageDeploymentManager::RemovePackageByFullName( + winrt::hstring const& packageFullName, + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options, + winrt::Windows::Management::Deployment::RemovalOptions const& removeOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackage, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) { - return IsPackageRegistrationPendingForUser(hstring{}, packageFamilyName); + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + auto deploymentOperation{ m_packageManager.RemovePackageAsync(packageFullName, removeOptions) }; + deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< + winrt::Windows::Management::Deployment::DeploymentResult, + winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, + winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) + { + packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage, progressMaxPerPackage); + progress(packageDeploymentProgress); + }); + deploymentOperation.get(); + try + { + const auto deploymentResult{ deploymentOperation.GetResults() }; + const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; + extendedError = deploymentResult.ExtendedErrorCode(); + errorText = deploymentResult.ErrorText(); + activityId = deploymentResult.ActivityId(); + const auto status{ deploymentOperation.Status() }; + if (status == winrt::Windows::Foundation::AsyncStatus::Error) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)) + { + if (!options.FailIfNotFound()) + { + // Package not installed. Success! + (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); + extendedError = error; + errorText.clear(); + return S_OK; + } + } + RETURN_IF_FAILED_MSG(error, + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); + + // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. + FAIL_FAST_HR_MSG(E_UNEXPECTED, + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); + } + else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) + { + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageFullName.c_str()); + } + FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, + "Status:%d PackageFullName:%ls : %ls", static_cast(status), packageFullName.c_str(), errorText.c_str()); + } + catch (...) + { + auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + THROW_HR_MSG(exception.code(), + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); + } + return S_OK; } - bool PackageDeploymentManager::IsPackageRegistrationPendingForUser(hstring const& userSecurityId, hstring const& packageFamilyName) + + HRESULT PackageDeploymentManager::RemovePackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageFamily, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) { - //TODO Awaiting FrameworkUdk update with PackageManagement_IsPackageRegistrationPending() - throw hresult_not_implemented(); + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + winrt::Windows::Management::Deployment::RemovalOptions removeOptions{ ToOptions(options) }; + RETURN_IF_FAILED(RemovePackageByFamilyName(packageFamilyName, options, removeOptions, packageDeploymentProgress, progress, progressMaxPerPackageFamily, extendedError, errorText, activityId)); + return S_OK; } - winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::AddPackageByAppInstallerFileAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options) + HRESULT PackageDeploymentManager::RemovePackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options, + winrt::Windows::Management::Deployment::RemovalOptions const& removeOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageFamily, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) { - //TODO add via AddPackageByAppInstallerFileAsync() - throw hresult_not_implemented(); + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + // Resource packages are automagically removed when their associated Main|Optional package is removed + // Bundle packages are automagically removed when their associated Main|Optional package is removed + const auto packageTypes{ winrt::Windows::Management::Deployment::PackageTypes::Framework | + winrt::Windows::Management::Deployment::PackageTypes::Main | + winrt::Windows::Management::Deployment::PackageTypes::Optional }; + auto packages{ + ::Security::IntegrityLevel::IsElevated() ? + m_packageManager.FindPackagesWithPackageTypes(packageFamilyName, packageTypes) : + m_packageManager.FindPackagesForUserWithPackageTypes(winrt::hstring(), packageFamilyName, packageTypes) }; + const size_t packagesCount{ packages ? Count(packages) : 0 }; + if (packagesCount > 0) + { + const auto progressMaxPerPackage{ progressMaxPerPackageFamily / packagesCount }; + for (const winrt::Windows::ApplicationModel::Package& package : packages) + { + const auto packageFullName{ package.Id().FullName() }; + try + { + RETURN_IF_FAILED_MSG(RemovePackageByFullName(packageFullName, options, removeOptions, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls PackageFullName:%ls", + extendedError, packageFamilyName.c_str(), packageFullName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + RETURN_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageFullName:%ls", extendedError, packageFamilyName.c_str(), packageFullName.c_str()); + } + } + } + else if (options.FailIfNotFound()) + { + extendedError = HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND); + errorText = winrt::impl::message_from_hresult(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); + RETURN_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), "PackageFamilyName:%ls", packageFamilyName.c_str()); + } + return S_OK; } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::RegisterPackageByPackageFamilyNameAsync(winrt::hstring const& packageFamilyName, winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options) + PackageDeploymentManager::ResetPackageByFamilyNameAsync(hstring packageFamilyName) { - auto logTelemetry{ PackageManagementTelemetry::RegisterPackageByPackageFamilyNameAsync::Start(packageFamilyName) }; + auto logTelemetry{ PackageManagementTelemetry::ResetPackageAsync::Start(packageFamilyName) }; auto strong{ get_strong() }; auto cancellation{ co_await winrt::get_cancellation_token() }; cancellation.enable_propagation(true); - // Allow to register the progress and complete handler logTelemetry.IgnoreCurrentThread(); co_await resume_background(); // Allow to register the progress and complete handler auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; @@ -691,46 +2555,108 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageDeploymentProgressStatus::Queued, 0} }; progress(packageDeploymentProgress); - // Check parameter(s) - //TODO Validate(packageSet); - + const double progressMaxPerPackageFamily{ 1.0 }; HRESULT error{}; HRESULT extendedError{}; winrt::hstring errorText; winrt::guid activityId{}; try { - error = LOG_IF_FAILED_MSG(RegisterPackageByPackageFamilyName(packageFamilyName, options, packageDeploymentProgress, progress, extendedError, errorText, activityId), - "ExtendedError:0x%08X PackageFamilyName:%ls", + error = LOG_IF_FAILED_MSG(ResetPackageByFamilyName(packageFamilyName, packageDeploymentProgress, progress, progressMaxPerPackageFamily, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFamilyName.c_str()); } catch (...) { const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; - error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls", extendedError, packageFamilyName.c_str()); + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFamilyName.c_str()); } if (FAILED(error)) { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED) && (extendedError == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))) + { + error = HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND); + } co_return winrt::make( PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); } - - co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); - - logTelemetry.Stop(packageFamilyName); + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageFamilyName); + } + + HRESULT PackageDeploymentManager::ResetPackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageFamily, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId) + { + extendedError = S_OK; + errorText.clear(); + activityId = winrt::guid{}; + + // Resource packages are automagically reseted when their associated Main|Optional package is reseted + // Bundle packages are automagically reseted when their associated Main|Optional package is reseted + const auto packageTypes{ winrt::Windows::Management::Deployment::PackageTypes::Framework | + winrt::Windows::Management::Deployment::PackageTypes::Main | + winrt::Windows::Management::Deployment::PackageTypes::Optional }; +#if defined(TODO_Reset_DoesElevatedMatter) + auto packages{ + ::Security::IntegrityLevel::IsElevated() ? + m_packageManager.FindPackagesWithPackageTypes(packageFamilyName, packageTypes) : + m_packageManager.FindPackagesForUserWithPackageTypes(winrt::hstring(), packageFamilyName, packageTypes) }; +#else + auto packages{ m_packageManager.FindPackagesForUserWithPackageTypes(winrt::hstring(), packageFamilyName, packageTypes) }; +#endif + const size_t packagesCount{ packages ? Count(packages) : 0 }; + if (packagesCount == 0) + { + extendedError = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + errorText = winrt::impl::message_from_hresult(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); + RETURN_HR(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); + } + const auto progressMaxPerPackage{ progressMaxPerPackageFamily / packagesCount }; + for (const winrt::Windows::ApplicationModel::Package& package : packages) + { + const auto packageFullName{ package.Id().FullName() }; + HRESULT error{}; + try + { + error = LOG_IF_FAILED_MSG(ResetPackageByFullName(packageFullName, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls PackageFullName:%ls", + extendedError, packageFamilyName.c_str(), packageFullName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageFullName:%ls", extendedError, packageFamilyName.c_str(), packageFullName.c_str()); + } + if (FAILED(error)) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED) && (extendedError == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))) + { + error = HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND); + } + RETURN_HR(error); + } + } + return S_OK; } winrt::Windows::Foundation::IAsyncOperationWithProgress - PackageDeploymentManager::RegisterPackageByPackageFullNameAsync(winrt::hstring const& packageFullName, winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options) + PackageDeploymentManager::ResetPackageByFullNameAsync(hstring packageFullName) { - auto logTelemetry{ PackageManagementTelemetry::RegisterPackageByPackageFullNameAsync::Start(packageFullName) }; + auto logTelemetry{ PackageManagementTelemetry::ResetPackageAsync::Start(packageFullName) }; auto strong{ get_strong() }; auto cancellation{ co_await winrt::get_cancellation_token() }; cancellation.enable_propagation(true); - // Allow to register the progress and complete handler logTelemetry.IgnoreCurrentThread(); co_await resume_background(); // Allow to register the progress and complete handler auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; @@ -741,27 +2667,28 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageDeploymentProgressStatus::Queued, 0} }; progress(packageDeploymentProgress); - // Check parameter(s) - //TODO Validate(packageSet); - - winrt::Windows::Management::Deployment::RegisterPackageOptions registerOptions{ ToOptions(options) }; + const double progressMaxPerPackage{ 1.0 }; HRESULT error{}; HRESULT extendedError{}; winrt::hstring errorText; winrt::guid activityId{}; try { - error = LOG_IF_FAILED_MSG(RegisterPackageByPackageFullName(packageFullName, registerOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId), - "ExtendedError:0x%08X PackageFullName:%ls", + error = LOG_IF_FAILED_MSG(ResetPackageByFullName(packageFullName, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFullName.c_str()); } catch (...) { const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; - error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFullName:%ls", extendedError, packageFullName.c_str()); + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFullName.c_str()); } if (FAILED(error)) { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED) && (extendedError == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))) + { + error = HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND); + } co_return winrt::make( PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); } @@ -771,43 +2698,11 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation logTelemetry.Stop(packageFullName); } - bool PackageDeploymentManager::IsReadyByPackageFullName(hstring const& packageFullName) - { - return ::Microsoft::Windows::ApplicationModel::PackageDeploymentResolver::FindAny(m_packageManager, packageFullName); - } - - bool PackageDeploymentManager::IsReady(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) - { - const AppModel::Identity::PackageVersion minVersion{ packageSetItem.MinVersion() }; - const auto processorArchitectureFilter{ packageSetItem.ProcessorArchitectureFilter() }; - return ::Microsoft::Windows::ApplicationModel::PackageDeploymentResolver::FindAny(m_packageManager, packageSetItem.PackageFamilyName(), minVersion, processorArchitectureFilter); - } - - void PackageDeploymentManager::Validate(winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) const - { - THROW_HR_IF(E_INVALIDARG, packageSet.Id().empty()); - const auto& packageSetItems{ packageSet.Items() }; - THROW_HR_IF(E_INVALIDARG, packageSetItems.Size() == 0); - for (const winrt::Microsoft::Windows::Management::Deployment::PackageSetItem& packageSetItem : packageSetItems) - { - Validate(packageSetItem); - } - } - - void PackageDeploymentManager::Validate(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) const - { - const auto packageFamilyName{ packageSetItem.PackageFamilyName() }; - THROW_IF_WIN32_ERROR_MSG(VerifyPackageFamilyName(packageFamilyName.c_str()), "PackageFamilyName:%ls", packageFamilyName.c_str()); - - const auto packageUri{ packageSetItem.PackageUri() }; - THROW_HR_IF_NULL_MSG(E_INVALIDARG, packageUri, "PackageUri:"); - } - - HRESULT PackageDeploymentManager::EnsureReadyAsync( - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions const& options, + HRESULT PackageDeploymentManager::ResetPackageByFullName( + winrt::hstring const& packageFullName, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackage, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId) @@ -816,20 +2711,27 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation errorText.clear(); activityId = winrt::guid{}; - if (IsReady(packageSetItem)) + // Reset only works on packages if they're registered to the caller. + // But PackageManagement_ResetPackageAsync2() = Remove + StageUserData + Register + // which succeeds if the package isn't initially registered for the caller. + // Ensure we're only working on packages if they're registered to the caller + if (!::Microsoft::Windows::ApplicationModel::PackageDeploymentResolver::IsRegistered(m_packageManager, packageFullName)) { - return S_OK; + extendedError = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + errorText = winrt::impl::message_from_hresult(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); + RETURN_HR(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); } - auto packageUri{ packageSetItem.PackageUri() }; - winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; - auto deploymentOperation{ m_packageManager.AddPackageByUriAsync(packageUri, addOptions) }; + ::ABI::Windows::Foundation::IAsyncOperationWithProgress<::ABI::Windows::Management::Deployment::DeploymentResult*, ::ABI::Windows::Management::Deployment::DeploymentProgress>* abiDeploymentOperation{}; + RETURN_IF_FAILED(PackageManagement_ResetPackageAsync2(packageFullName.c_str(), &abiDeploymentOperation)); + winrt::Windows::Foundation::IAsyncOperationWithProgress deploymentOperation; + winrt::copy_from_abi(deploymentOperation, abiDeploymentOperation); deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< winrt::Windows::Management::Deployment::DeploymentResult, winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) { - packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage); + packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage, progressMaxPerPackage); progress(packageDeploymentProgress); }); deploymentOperation.get(); @@ -844,142 +2746,87 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation if (status == winrt::Windows::Foundation::AsyncStatus::Error) { RETURN_IF_FAILED_MSG(error, - "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls : %ls", - extendedError, packageSetItem.PackageFamilyName().c_str(), packageSetItem.PackageUri().ToString().c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. FAIL_FAST_HR_MSG(E_UNEXPECTED, - "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls : %ls", - extendedError, packageSetItem.PackageFamilyName().c_str(), packageUri.ToString().c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); } else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) { - RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageUri.ToString().c_str()); + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageFullName.c_str()); } FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, - "Status:%d %ls", static_cast(status), packageUri.ToString().c_str()); + "Status:%d PackageFullName:%ls : %ls", static_cast(status), packageFullName.c_str(), errorText.c_str()); } catch (...) { auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; THROW_HR_MSG(exception.code(), - "ExtendedError:0x%08X PackageFamilyName:%ls PackageUri:%ls : %ls", - extendedError, packageSetItem.PackageFamilyName().c_str(), packageSetItem.PackageUri().ToString().c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); } return S_OK; } - HRESULT PackageDeploymentManager::AddPackage( - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions const& options, - winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, - wistd::function progress, - HRESULT& extendedError, - winrt::hstring& errorText, - winrt::guid& activityId) + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::RepairPackageByFamilyNameAsync(hstring packageFamilyName) { - extendedError = S_OK; - errorText.clear(); - activityId = winrt::guid{}; + auto logTelemetry{ PackageManagementTelemetry::RepairPackageAsync::Start(packageFamilyName) }; - auto packageUri{ packageSetItem.PackageUri() }; - winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; - RETURN_IF_FAILED(AddPackage(packageUri, addOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId)); - return S_OK; - } + auto strong{ get_strong() }; - HRESULT PackageDeploymentManager::AddPackage( - winrt::Windows::Foundation::Uri const& packageUri, - winrt::Windows::Management::Deployment::AddPackageOptions const& addOptions, - winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, - wistd::function progress, - HRESULT& extendedError, - winrt::hstring& errorText, - winrt::guid& activityId) - { - extendedError = S_OK; - errorText.clear(); - activityId = winrt::guid{}; + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); - auto deploymentOperation{ m_packageManager.AddPackageByUriAsync(packageUri, addOptions) }; - deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< - winrt::Windows::Management::Deployment::DeploymentResult, - winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, - winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) - { - packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage); - progress(packageDeploymentProgress); - }); - deploymentOperation.get(); + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + const double progressMaxPerPackageFamily{ 1.0 }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; try { - const auto deploymentResult{ deploymentOperation.GetResults() }; - const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; - extendedError = deploymentResult.ExtendedErrorCode(); - errorText = deploymentResult.ErrorText(); - activityId = deploymentResult.ActivityId(); - const auto status{ deploymentOperation.Status() }; - if (status == winrt::Windows::Foundation::AsyncStatus::Error) - { - if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) - { - // Newer version already installed. Success! - (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); - extendedError = error; - errorText.clear(); - return S_OK; - } - RETURN_IF_FAILED_MSG(error, - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); - - // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. - FAIL_FAST_HR_MSG(E_UNEXPECTED, - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); - } - else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) - { - RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageUri.ToString().c_str()); - } - FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, - "Status:%d PackageUri:%ls : %ls", static_cast(status), packageUri.ToString().c_str(), errorText.c_str()); + error = LOG_IF_FAILED_MSG(RepairPackageByFamilyName(packageFamilyName, packageDeploymentProgress, progress, progressMaxPerPackageFamily, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageUri:%ls", + extendedError, packageFamilyName.c_str()); } catch (...) { - auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; - THROW_HR_MSG(exception.code(), - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFamilyName.c_str()); + } + if (FAILED(error)) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED) && (extendedError == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))) + { + error = HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND); + } + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); } - return S_OK; - } - HRESULT PackageDeploymentManager::StagePackage(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions const& options, - winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, - wistd::function progress, - HRESULT& extendedError, - winrt::hstring& errorText, - winrt::guid& activityId) - { - extendedError = S_OK; - errorText.clear(); - activityId = winrt::guid{}; + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); - auto packageUri{ packageSetItem.PackageUri() }; - winrt::Windows::Management::Deployment::StagePackageOptions stageOptions{ ToOptions(options) }; - RETURN_IF_FAILED(StagePackage(packageUri, stageOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId)); - return S_OK; + logTelemetry.Stop(packageFamilyName); } - HRESULT PackageDeploymentManager::StagePackage( - winrt::Windows::Foundation::Uri const& packageUri, - winrt::Windows::Management::Deployment::StagePackageOptions const& stageOptions, + HRESULT PackageDeploymentManager::RepairPackageByFamilyName( + winrt::hstring const& packageFamilyName, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackageFamily, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId) @@ -988,86 +2835,110 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation errorText.clear(); activityId = winrt::guid{}; - auto deploymentOperation{ m_packageManager.StagePackageByUriAsync(packageUri, stageOptions) }; - deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< - winrt::Windows::Management::Deployment::DeploymentResult, - winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, - winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) + // Resource packages are automagically repaired when their associated Main|Optional package is repaired + // Bundle packages are automagically repaired when their associated Main|Optional package is repaired + const auto packageTypes{ winrt::Windows::Management::Deployment::PackageTypes::Framework | + winrt::Windows::Management::Deployment::PackageTypes::Main | + winrt::Windows::Management::Deployment::PackageTypes::Optional }; +#if defined(TODO_Reset_DoesElevatedMatter) + auto packages{ + ::Security::IntegrityLevel::IsElevated() ? + m_packageManager.FindPackagesWithPackageTypes(packageFamilyName, packageTypes) : + m_packageManager.FindPackagesForUserWithPackageTypes(winrt::hstring(), packageFamilyName, packageTypes) }; +#else + auto packages{ m_packageManager.FindPackagesForUserWithPackageTypes(winrt::hstring(), packageFamilyName, packageTypes) }; +#endif + const size_t packagesCount{ packages ? Count(packages) : 0 }; + if (packagesCount == 0) { - packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage); - progress(packageDeploymentProgress); - }); - deploymentOperation.get(); - try + extendedError = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + errorText = winrt::impl::message_from_hresult(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); + RETURN_HR(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); + } + const auto progressMaxPerPackage{ progressMaxPerPackageFamily / packagesCount }; + for (const winrt::Windows::ApplicationModel::Package& package : packages) { - const auto deploymentResult{ deploymentOperation.GetResults() }; - const HRESULT error{ static_cast(deploymentOperation.ErrorCode()) }; - extendedError = deploymentResult.ExtendedErrorCode(); - errorText = deploymentResult.ErrorText(); - activityId = deploymentResult.ActivityId(); - const auto status{ deploymentOperation.Status() }; - if (status == winrt::Windows::Foundation::AsyncStatus::Error) + const auto packageFullName{ package.Id().FullName() }; + HRESULT error{}; + try { - if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) + error = LOG_IF_FAILED_MSG(RepairPackageByFullName(packageFullName, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageFamilyName:%ls PackageFullName:%ls", + extendedError, packageFamilyName.c_str(), packageFullName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageFamilyName:%ls PackageFullName:%ls", extendedError, packageFamilyName.c_str(), packageFullName.c_str()); + } + if (FAILED(error)) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED) && (extendedError == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))) { - // Newer version already installed. Success! - (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); - extendedError = error; - errorText.clear(); - return S_OK; + error = HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND); } - RETURN_IF_FAILED_MSG(error, - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); + RETURN_HR(error); + } + } + return S_OK; + } + + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::RepairPackageByFullNameAsync(hstring packageFullName) + { + auto logTelemetry{ PackageManagementTelemetry::RepairPackageAsync::Start(packageFullName) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); - // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. - FAIL_FAST_HR_MSG(E_UNEXPECTED, - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); - } - else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) - { - RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageUri.ToString().c_str()); - } - FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, - "Status:%d PackageUri:%ls : %ls", static_cast(status), packageUri.ToString().c_str(), errorText.c_str()); + const double progressMaxPerPackage{ 1.0 }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + try + { + error = LOG_IF_FAILED_MSG(RepairPackageByFullName(packageFullName, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageUri:%ls", + extendedError, packageFullName.c_str()); } catch (...) { - auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; - THROW_HR_MSG(exception.code(), - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFullName.c_str()); + } + if (FAILED(error)) + { + if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED) && (extendedError == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))) + { + error = HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND); + } + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); } - return S_OK; - } - HRESULT PackageDeploymentManager::RegisterPackage( - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, - winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions const& options, - winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, - wistd::function progress, - HRESULT& extendedError, - winrt::hstring& errorText, - winrt::guid& activityId) - { - extendedError = S_OK; - errorText.clear(); - activityId = winrt::guid{}; + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); - auto packageUri{ packageSetItem.PackageUri() }; - winrt::Windows::Management::Deployment::RegisterPackageOptions registerOptions{ ToOptions(options) }; - RETURN_IF_FAILED(RegisterPackage(packageUri, registerOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId)); - return S_OK; + logTelemetry.Stop(packageFullName); } - HRESULT PackageDeploymentManager::RegisterPackage( - winrt::Windows::Foundation::Uri const& packageUri, - winrt::Windows::Management::Deployment::RegisterPackageOptions const& registerOptions, + HRESULT PackageDeploymentManager::RepairPackageByFullName( + winrt::hstring const& packageFullName, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackage, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId) @@ -1076,13 +2947,27 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation errorText.clear(); activityId = winrt::guid{}; - auto deploymentOperation{ m_packageManager.RegisterPackageByUriAsync(packageUri, registerOptions) }; + // Repair only works on packages if they're registered to the caller. + // But PackageManagement_RepairPackageAsync2() = Register + // which succeeds if the package isn't initially registered for the caller. + // Ensure we're only working on packages if they're registered to the caller + if (!::Microsoft::Windows::ApplicationModel::PackageDeploymentResolver::IsRegistered(m_packageManager, packageFullName)) + { + extendedError = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + errorText = winrt::impl::message_from_hresult(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); + RETURN_HR(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND)); + } + + ::ABI::Windows::Foundation::IAsyncOperationWithProgress<::ABI::Windows::Management::Deployment::DeploymentResult*, ::ABI::Windows::Management::Deployment::DeploymentProgress>* abiDeploymentOperation{}; + RETURN_IF_FAILED(PackageManagement_RepairPackageAsync2(packageFullName.c_str(), &abiDeploymentOperation)); + winrt::Windows::Foundation::IAsyncOperationWithProgress deploymentOperation; + winrt::copy_from_abi(deploymentOperation, abiDeploymentOperation); deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< winrt::Windows::Management::Deployment::DeploymentResult, winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) { - packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage); + packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage, progressMaxPerPackage); progress(packageDeploymentProgress); }); deploymentOperation.get(); @@ -1096,45 +2981,111 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation const auto status{ deploymentOperation.Status() }; if (status == winrt::Windows::Foundation::AsyncStatus::Error) { - if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) - { - // Newer version already installed. Success! - (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); - extendedError = error; - errorText.clear(); - return S_OK; - } RETURN_IF_FAILED_MSG(error, - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. FAIL_FAST_HR_MSG(E_UNEXPECTED, - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); } else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) { - RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageUri.ToString().c_str()); + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageFullName.c_str()); } FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, - "Status:%d PackageUri:%ls : %ls", static_cast(status), packageUri.ToString().c_str(), errorText.c_str()); + "Status:%d PackageFullName:%ls : %ls", static_cast(status), packageFullName.c_str(), errorText.c_str()); } catch (...) { auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; THROW_HR_MSG(exception.code(), - "ExtendedError:0x%08X PackageUri:%ls : %ls", - extendedError, packageUri.ToString().c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFullName:%ls : %ls", + extendedError, packageFullName.c_str(), errorText.c_str()); } return S_OK; } - HRESULT PackageDeploymentManager::RegisterPackageByPackageFamilyName( + bool PackageDeploymentManager::IsProvisionedByPackageFamilyName(hstring const& packageFamilyName) + { + const auto provisionedPackages{ m_packageManager.FindProvisionedPackages() }; + return IsProvisionedByPackageFamilyName(provisionedPackages, packageFamilyName); + } + + bool PackageDeploymentManager::IsProvisionedByPackageFamilyName( + winrt::Windows::Foundation::Collections::IVector const& provisionedPackages, + hstring const& packageFamilyName) + { + for (const winrt::Windows::ApplicationModel::Package& provisionedPackage: provisionedPackages) + { + if (StringEqualsNoCase(packageFamilyName, provisionedPackage.Id().FamilyName())) + { + return true; + } + } + return false; + } + + bool PackageDeploymentManager::IsProvisioned( + winrt::Windows::Foundation::Collections::IVector const& provisionedPackages, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) + { + return IsProvisionedByPackageFamilyName(provisionedPackages, packageSetItem.PackageFamilyName()); + } + + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::ProvisionPackageByFamilyNameAsync( + hstring packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions const& options) + { + auto logTelemetry{ PackageManagementTelemetry::ProvisionPackageAsync::Start(packageFamilyName) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + winrt::Windows::Management::Deployment::PackageAllUserProvisioningOptions provisionOptions{ ToOptions(options) }; + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + try + { + error = LOG_IF_FAILED_MSG(ProvisionPackageByFamilyName(packageFamilyName, provisionOptions, packageDeploymentProgress, progress, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageUri:%ls", + extendedError, packageFamilyName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFamilyName.c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageFamilyName); + } + + HRESULT PackageDeploymentManager::ProvisionPackageByFamilyName( winrt::hstring const& packageFamilyName, - winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions const& registerOptions, + winrt::Windows::Management::Deployment::PackageAllUserProvisioningOptions const& options, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, HRESULT& extendedError, @@ -1145,16 +3096,23 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation errorText.clear(); activityId = winrt::guid{}; - const auto deploymentOptions{ ToDeploymentOptions(registerOptions) }; - auto deploymentOperation{ m_packageManager.RegisterPackageByFamilyNameAsync(packageFamilyName, - registerOptions.DependencyPackageFamilyNames(), deploymentOptions, - ToPackageVolume(registerOptions.AppDataVolume()), registerOptions.OptionalPackageFamilyNames()) }; + // PackageManager.ProvisionPackageForAllUsersAsync(String, PackageAllUserProvisioningOptions) requires Windows >= 10.0.22000.0 (aka Win11 21H2) + winrt::Windows::Foundation::IAsyncOperationWithProgress deploymentOperation; + if (WindowsVersion::IsWindows11_21H2OrGreater()) + { + deploymentOperation = m_packageManager.ProvisionPackageForAllUsersAsync(packageFamilyName, options); + } + else + { + deploymentOperation = m_packageManager.ProvisionPackageForAllUsersAsync(packageFamilyName); + } deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< winrt::Windows::Management::Deployment::DeploymentResult, winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) { - packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage); + const double progressMaxPerPackage{ 1.0 }; + packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage, progressMaxPerPackage); progress(packageDeploymentProgress); }); deploymentOperation.get(); @@ -1168,16 +3126,6 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation const auto status{ deploymentOperation.Status() }; if (status == winrt::Windows::Foundation::AsyncStatus::Error) { - if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) - { - // Newer version already installed. Success! - (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), - "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", - extendedError, packageFamilyName.c_str(), errorText.c_str()); - extendedError = error; - errorText.clear(); - return S_OK; - } RETURN_IF_FAILED_MSG(error, "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", extendedError, packageFamilyName.c_str(), errorText.c_str()); @@ -1204,9 +3152,54 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation return S_OK; } - HRESULT PackageDeploymentManager::RegisterPackageByPackageFullName( - winrt::hstring const& packageFullName, - winrt::Windows::Management::Deployment::RegisterPackageOptions const& registerOptions, + winrt::Windows::Foundation::IAsyncOperationWithProgress + PackageDeploymentManager::DeprovisionPackageByFamilyNameAsync(hstring packageFamilyName) + { + auto logTelemetry{ PackageManagementTelemetry::DeprovisionPackageAsync::Start(packageFamilyName) }; + + auto strong{ get_strong() }; + + auto cancellation{ co_await winrt::get_cancellation_token() }; + cancellation.enable_propagation(true); + + logTelemetry.IgnoreCurrentThread(); + co_await resume_background(); // Allow to register the progress and complete handler + auto logTelemetryContinuation{ logTelemetry.ContinueOnCurrentThread() }; + + auto progress{ co_await winrt::get_progress_token() }; + auto packageDeploymentProgress{ + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress{ + PackageDeploymentProgressStatus::Queued, 0} }; + progress(packageDeploymentProgress); + + HRESULT error{}; + HRESULT extendedError{}; + winrt::hstring errorText; + winrt::guid activityId{}; + try + { + error = LOG_IF_FAILED_MSG(DeprovisionPackageByFamilyName(packageFamilyName, packageDeploymentProgress, progress, extendedError, errorText, activityId), + "ExtendedError:0x%08X PackageUri:%ls", + extendedError, packageFamilyName.c_str()); + } + catch (...) + { + const auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; + error = LOG_HR_MSG(exception.code(), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageFamilyName.c_str()); + } + if (FAILED(error)) + { + co_return winrt::make( + PackageDeploymentStatus::CompletedFailure, activityId, error, extendedError, errorText); + } + + co_return winrt::make(PackageDeploymentStatus::CompletedSuccess, activityId); + + logTelemetry.Stop(packageFamilyName); + } + + HRESULT PackageDeploymentManager::DeprovisionPackageByFamilyName( + winrt::hstring const& packageFamilyName, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, HRESULT& extendedError, @@ -1217,15 +3210,14 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation errorText.clear(); activityId = winrt::guid{}; - winrt::Windows::Foundation::Collections::IVector packageFullNames{ winrt::single_threaded_vector() }; - packageFullNames.Append(packageFullName); - auto deploymentOperation{ m_packageManager.RegisterPackagesByFullNameAsync(packageFullNames, registerOptions) }; + auto deploymentOperation{ m_packageManager.DeprovisionPackageForAllUsersAsync(packageFamilyName) }; deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< winrt::Windows::Management::Deployment::DeploymentResult, winrt::Windows::Management::Deployment::DeploymentProgress> const& /*sender*/, winrt::Windows::Management::Deployment::DeploymentProgress const& progressInfo) { - packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage); + const double progressMaxPerPackage{ 1.0 }; + packageDeploymentProgress.Progress = PercentageToProgress(progressInfo.percentage, progressMaxPerPackage); progress(packageDeploymentProgress); }); deploymentOperation.get(); @@ -1239,38 +3231,28 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation const auto status{ deploymentOperation.Status() }; if (status == winrt::Windows::Foundation::AsyncStatus::Error) { - if (error == HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE)) - { - // Newer version already installed. Success! - (void)LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), - "ExtendedError:0x%08X PackageFullName:%ls : %ls", - extendedError, packageFullName.c_str(), errorText.c_str()); - extendedError = error; - errorText.clear(); - return S_OK; - } RETURN_IF_FAILED_MSG(error, - "ExtendedError:0x%08X PackageFullName:%ls : %ls", - extendedError, packageFullName.c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", + extendedError, packageFamilyName.c_str(), errorText.c_str()); // Status=Error but SUCCEEDED(error) == This.Should.Never.Happen. FAIL_FAST_HR_MSG(E_UNEXPECTED, - "ExtendedError:0x%08X PackageFullName:%ls : %ls", - extendedError, packageFullName.c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", + extendedError, packageFamilyName.c_str(), errorText.c_str()); } else if (status == winrt::Windows::Foundation::AsyncStatus::Canceled) { - RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageFullName.c_str()); + RETURN_WIN32_MSG(ERROR_CANCELLED, "%ls", packageFamilyName.c_str()); } FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, status != winrt::Windows::Foundation::AsyncStatus::Completed, - "Status:%d PackageFullName:%ls : %ls", static_cast(status), packageFullName.c_str(), errorText.c_str()); + "Status:%d PackageFamilyName:%ls : %ls", static_cast(status), packageFamilyName.c_str(), errorText.c_str()); } catch (...) { auto exception{ hresult_error(to_hresult(), take_ownership_from_abi) }; THROW_HR_MSG(exception.code(), - "ExtendedError:0x%08X PackageFullName:%ls : %ls", - extendedError, packageFullName.c_str(), errorText.c_str()); + "ExtendedError:0x%08X PackageFamilyName:%ls : %ls", + extendedError, packageFamilyName.c_str(), errorText.c_str()); } return S_OK; } @@ -1501,9 +3483,29 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation return deploymentOptions; } - double PackageDeploymentManager::PercentageToProgress(uint32_t percentage) + winrt::Windows::Management::Deployment::PackageAllUserProvisioningOptions PackageDeploymentManager::ToOptions(winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions const& options) const + { + auto optionalPackageFamilyNames{ options.OptionalPackageFamilyNames() }; + THROW_HR_IF(E_NOTIMPL, (optionalPackageFamilyNames.Size() >0) && !options.IsOptionalPackageFamilyNamesSupported()); + + auto projectionOrderPackageFamilyNames{ options.ProjectionOrderPackageFamilyNames() }; + THROW_HR_IF(E_NOTIMPL, (projectionOrderPackageFamilyNames.Size() >0) && !options.IsProjectionOrderPackageFamilyNamesSupported()); + + winrt::Windows::Management::Deployment::PackageAllUserProvisioningOptions toOptions; + for (const auto optionalPackageFamilyName : optionalPackageFamilyNames) + { + toOptions.OptionalPackageFamilyNames().Append(optionalPackageFamilyName); + } + for (const auto projectionOrderPackageFamilyName : projectionOrderPackageFamilyNames) + { + toOptions.ProjectionOrderPackageFamilyNames().Append(projectionOrderPackageFamilyName); + } + return toOptions; + } + + double PackageDeploymentManager::PercentageToProgress(uint32_t percentage, const double progressMaxPerItem) { - return static_cast(percentage) / 100.0; + return (static_cast(percentage) / 100.0) * progressMaxPerItem; } bool PackageDeploymentManager::IsUriEndsWith(winrt::Windows::Foundation::Uri const& packageUri, PCWSTR target) @@ -1524,4 +3526,25 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PCWSTR pathToCompare{ path.c_str() + (path.size() - targetLength) }; return CompareStringOrdinal(pathToCompare, -1, target, -1, TRUE) == CSTR_EQUAL; } + + winrt::Windows::Foundation::Uri PackageDeploymentManager::GetEffectivePackageUri( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) + { + auto packageUri{ packageSetItem.PackageUri() }; + if (packageUri) + { + return packageUri; + } + else + { + return packageSet.PackageUri(); + } + } + + bool PackageDeploymentManager::IsUriScheme_MsUup(winrt::Windows::Foundation::Uri const& packageUri) + { + const auto schemeName{ packageUri.SchemeName() }; + return CompareStringOrdinal(schemeName.c_str(), -1, L"ms-uup", -1, TRUE) == CSTR_EQUAL; + } } diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h index 9c1e753406..d31f46f8e5 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h +++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h @@ -10,9 +10,16 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation struct PackageDeploymentManager : PackageDeploymentManagerT { static winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager GetDefault(); + static bool IsPackageDeploymentFeatureSupported(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature feature); + private: + static bool IsPackageDeploymentFeatureSupported(PCWSTR feature); + public: bool IsPackageReady(hstring const& package); bool IsPackageReadyByUri(winrt::Windows::Foundation::Uri const& packageUri); bool IsPackageSetReady(winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet); + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus IsPackageReadyOrNewerAvailable(hstring const& package); + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus IsPackageReadyOrNewerAvailableByUri(winrt::Windows::Foundation::Uri const& packageUri); + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus IsPackageSetReadyOrNewerAvailable(winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet); winrt::Windows::Foundation::IAsyncOperationWithProgress EnsurePackageReadyAsync(hstring package, winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options); winrt::Windows::Foundation::IAsyncOperationWithProgress EnsurePackageReadyByUriAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options); winrt::Windows::Foundation::IAsyncOperationWithProgress EnsurePackageSetReadyAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet, winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options); @@ -36,14 +43,20 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Windows::Foundation::IAsyncOperationWithProgress RepairPackageAsync(hstring package); winrt::Windows::Foundation::IAsyncOperationWithProgress RepairPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri); winrt::Windows::Foundation::IAsyncOperationWithProgress RepairPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet); + bool IsPackageProvisioned(hstring const& package); + bool IsPackageProvisionedByUri(winrt::Windows::Foundation::Uri const& packageUri); + bool IsPackageSetProvisioned(winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet); winrt::Windows::Foundation::IAsyncOperationWithProgress ProvisionPackageAsync(hstring package, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options); winrt::Windows::Foundation::IAsyncOperationWithProgress ProvisionPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options); winrt::Windows::Foundation::IAsyncOperationWithProgress ProvisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet, winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options); winrt::Windows::Foundation::IAsyncOperationWithProgress DeprovisionPackageAsync(hstring package); winrt::Windows::Foundation::IAsyncOperationWithProgress DeprovisionPackageByUriAsync(winrt::Windows::Foundation::Uri packageUri); winrt::Windows::Foundation::IAsyncOperationWithProgress DeprovisionPackageSetAsync(winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet); - bool IsPackageRegistrationPending(hstring const& packageFamilyName); - bool IsPackageRegistrationPendingForUser(hstring const& userSecurityId, hstring const& packageFamilyName); + bool IsPackageRegistrationPending(hstring const& packageFullName); + bool IsPackageRegistrationPendingForUser(hstring const& userSecurityId, hstring const& packageFullName); + + private: + bool IsPackageRegistrationPendingForUser(PSID userSid, PCWSTR packageFullName); private: winrt::Windows::Foundation::IAsyncOperationWithProgress AddPackageByAppInstallerFileAsync(winrt::Windows::Foundation::Uri packageUri, winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options); @@ -51,23 +64,44 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Windows::Foundation::IAsyncOperationWithProgress RegisterPackageByPackageFullNameAsync(winrt::hstring const& packageFullName, winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options); private: + winrt::hstring GetUupProductIdIfMsUup(winrt::Windows::Foundation::Uri const& uri) const; + wil::unique_cotaskmem_array_ptr GetPackageFullNamesFromUupProductUriIfMsUup(winrt::Windows::Foundation::Uri const& uri) const; bool IsReadyByPackageFullName(hstring const& packageFullName); - bool IsReady(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSet); - void Validate(winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) const; - void Validate(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) const; + bool IsReady(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem); + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus IsReadyOrNewerAvailableByPackageFullName(hstring const& packageFullName); + winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus IsReadyOrNewerAvailable(winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem); + void Validate_PackageUriIsRequired( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) const; + void Validate_PackageUriIsOptional( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) const; + void _Validate( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet, + const bool packageUriIsRequired) const; + void _Validate( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, + const bool packageUriIsRequired) const; + void Validate_PackageUriOrFamilyName( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet) const; + void Validate_PackageUriOrFamilyName( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem) const; HRESULT EnsureReadyAsync( + winrt::Windows::Foundation::Uri const& packageUri, winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions const& options, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackageSetItem, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); HRESULT AddPackage( - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, + winrt::Windows::Foundation::Uri const& packageUri, winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions const& options, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackageSetItem, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); @@ -76,14 +110,16 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Windows::Management::Deployment::AddPackageOptions const& addOptions, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackage, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); HRESULT StagePackage( - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, + winrt::Windows::Foundation::Uri const& packageUri, winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions const& options, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackageSetItem, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); @@ -92,14 +128,16 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Windows::Management::Deployment::StagePackageOptions const& stageOptions, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackage, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); HRESULT RegisterPackage( - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem, + winrt::Windows::Foundation::Uri const& packageUri, winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions const& options, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackageSetItem, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); @@ -108,6 +146,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Windows::Management::Deployment::RegisterPackageOptions const& registerOptions, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, + const double progressMaxPerPackage, HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); @@ -127,6 +166,121 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); + HRESULT RemovePackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageSetItem, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + HRESULT RemovePackage( + winrt::Windows::Foundation::Uri const& packageUri, + winrt::Windows::Management::Deployment::RemovalOptions const& removeOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackage, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + HRESULT RemovePackageByFullName( + winrt::hstring const& packageFullName, + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options, + winrt::Windows::Management::Deployment::RemovalOptions const& removeOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackage, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + HRESULT RemovePackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageFamily, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + HRESULT RemovePackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options, + winrt::Windows::Management::Deployment::RemovalOptions const& removeOptions, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageFamily, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + winrt::Windows::Foundation::IAsyncOperationWithProgress ResetPackageByFamilyNameAsync( + hstring packageFamilyName); + HRESULT ResetPackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageFamily, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + winrt::Windows::Foundation::IAsyncOperationWithProgress ResetPackageByFullNameAsync( + hstring packageFullName); + HRESULT ResetPackageByFullName( + winrt::hstring const& packageFullName, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackage, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + winrt::Windows::Foundation::IAsyncOperationWithProgress RepairPackageByFamilyNameAsync( + hstring packageFamilyName); + HRESULT RepairPackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackageFamily, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + winrt::Windows::Foundation::IAsyncOperationWithProgress RepairPackageByFullNameAsync( + hstring packageFullName); + HRESULT RepairPackageByFullName( + winrt::hstring const& packageFullName, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + const double progressMaxPerPackage, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + bool IsProvisionedByPackageFamilyName( + hstring const& packageFamilyName); + bool IsProvisionedByPackageFamilyName( + winrt::Windows::Foundation::Collections::IVector const& provisionedPackages, + hstring const& packageFamilyName); + bool IsProvisioned( + winrt::Windows::Foundation::Collections::IVector const& provisionedPackages, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem); + winrt::Windows::Foundation::IAsyncOperationWithProgress ProvisionPackageByFamilyNameAsync( + hstring packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions const& options); + HRESULT ProvisionPackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Windows::Management::Deployment::PackageAllUserProvisioningOptions const& options, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); + winrt::Windows::Foundation::IAsyncOperationWithProgress DeprovisionPackageByFamilyNameAsync( + hstring packageFamilyName); + HRESULT DeprovisionPackageByFamilyName( + winrt::hstring const& packageFamilyName, + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, + wistd::function progress, + HRESULT& extendedError, + winrt::hstring& errorText, + winrt::guid& activityId); winrt::Windows::Management::Deployment::PackageVolume ToPackageVolume(winrt::Microsoft::Windows::Management::Deployment::PackageVolume const& packageVolume) const; winrt::Windows::Management::Deployment::AddPackageOptions ToOptions(winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions const& options) const; winrt::Windows::Management::Deployment::StagePackageOptions ToOptions(winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions const& options) const; @@ -134,8 +288,64 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Windows::Management::Deployment::RemovalOptions ToOptions(winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions const& options) const; winrt::Windows::Management::Deployment::AddPackageOptions ToOptions(winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions const& options) const; winrt::Windows::Management::Deployment::DeploymentOptions ToDeploymentOptions(winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions const& options) const; - static double PercentageToProgress(uint32_t percentage); + winrt::Windows::Management::Deployment::PackageAllUserProvisioningOptions ToOptions(winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions const& options) const; + static double PercentageToProgress(uint32_t percentage, const double progressMaxPerItem); static bool IsUriEndsWith(winrt::Windows::Foundation::Uri const& packageUri, PCWSTR target); + static winrt::Windows::Foundation::Uri GetEffectivePackageUri( + winrt::Microsoft::Windows::Management::Deployment::PackageSet const& packageSet, + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem); + static bool IsUriScheme_MsUup(winrt::Windows::Foundation::Uri const& packageUri); + + private: + static size_t Count(winrt::Windows::Foundation::Collections::IIterable packages) + { + size_t count{}; + if (packages) + { + const auto iterator{ packages.First() }; + if (iterator.HasCurrent()) + { + ++count; + while (iterator.MoveNext()) + { + ++count; + } + } + } + return count; + } + private: + static bool Any(winrt::Windows::Foundation::Collections::IIterable packages) + { + return packages ? packages.First().HasCurrent() : false; + } + + private: + static int StringCompareNoCase(PCWSTR left, PCWSTR right) + { + return CompareStringOrdinal(left, -1, right, -1, TRUE) - CSTR_EQUAL; + } + static bool StringEqualsNoCase(PCWSTR left, PCWSTR right) + { + return StringCompareNoCase(left, right) == 0; + } + static int StringCompareNoCase(PCWSTR left, const size_t leftLength, PCWSTR right, const size_t rightLength) + { + return CompareStringOrdinal(left, static_cast(leftLength), right, static_cast(rightLength), TRUE) - CSTR_EQUAL; + } + static int StringEqualsNoCase(PCWSTR left, const size_t leftLength, PCWSTR right, const size_t rightLength) + { + return StringCompareNoCase(left, leftLength, right, rightLength) == 0; + } + private: + static int StringCompareNoCase(const winrt::hstring& left, const winrt::hstring& right) + { + return StringCompareNoCase(left.c_str(), right.c_str()); + } + static bool StringEqualsNoCase(const winrt::hstring& left, const winrt::hstring& right) + { + return StringEqualsNoCase(left.c_str(), right.c_str()); + } private: winrt::Windows::Management::Deployment::PackageManager m_packageManager; diff --git a/dev/PackageManager/API/M.W.M.D.RemovePackageOptions.h b/dev/PackageManager/API/M.W.M.D.RemovePackageOptions.h index 1faf7871ae..ce0bdfd003 100644 --- a/dev/PackageManager/API/M.W.M.D.RemovePackageOptions.h +++ b/dev/PackageManager/API/M.W.M.D.RemovePackageOptions.h @@ -21,7 +21,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation void RemoveForAllUsers(bool value); private: - bool m_failIfNotFound{ true }; + bool m_failIfNotFound{}; bool m_preserveApplicationData{}; bool m_preserveRoamableApplicationData{}; bool m_removeForAllUsers{}; diff --git a/dev/PackageManager/API/PackageDeploymentResolver.cpp b/dev/PackageManager/API/PackageDeploymentResolver.cpp index 143ac694b2..63d7cd12fb 100644 --- a/dev/PackageManager/API/PackageDeploymentResolver.cpp +++ b/dev/PackageManager/API/PackageDeploymentResolver.cpp @@ -330,3 +330,12 @@ winrt::hstring Microsoft::Windows::ApplicationModel::PackageDeploymentResolver:: } return bestFitPackageFullName; } + +bool Microsoft::Windows::ApplicationModel::PackageDeploymentResolver::IsRegistered( + const winrt::Windows::Management::Deployment::PackageManager& packageManager, + const winrt::hstring& packageFullName) +{ + // Find the match + auto package{ packageManager.FindPackageForUser(winrt::hstring(), packageFullName) }; + return !!package; +} diff --git a/dev/PackageManager/API/PackageDeploymentResolver.h b/dev/PackageManager/API/PackageDeploymentResolver.h index 5188585f63..11dc1c65d2 100644 --- a/dev/PackageManager/API/PackageDeploymentResolver.h +++ b/dev/PackageManager/API/PackageDeploymentResolver.h @@ -24,6 +24,10 @@ namespace Microsoft::Windows::ApplicationModel::PackageDeploymentResolver bool FindAny( const winrt::Windows::Management::Deployment::PackageManager& packageManager, const winrt::hstring& packageFullName); + + bool IsRegistered( + const winrt::Windows::Management::Deployment::PackageManager& packageManager, + const winrt::hstring& packageFullName); } #endif // PACKAGERESOLVER_H diff --git a/dev/PackageManager/API/PackageManager.idl b/dev/PackageManager/API/PackageManager.idl index 0f2eece2d5..a5b88396ac 100644 --- a/dev/PackageManager/API/PackageManager.idl +++ b/dev/PackageManager/API/PackageManager.idl @@ -7,9 +7,22 @@ import "M.AM.DynamicDependency.idl"; namespace Microsoft.Windows.Management.Deployment { - [contractversion(1)] + [contractversion(2)] apicontract PackageDeploymentContract{}; + /// Features can be queried if currently available/enabled. + /// @see PackageDeploymentManager.IsPackageDeploymentFeatureSupported() + [contract(PackageDeploymentContract, 2)] + enum PackageDeploymentFeature + { + PackageUriScheme_ms_uup = 1, + IsPackageReadyOrNewerAvailable = 2, + RemovePackageByUri = 3, + ResetPackage = 4, + RepairPackage = 5, + ProvisionPackage_Framework = 6, + }; + /// Represents a package storage volume. /// @note A volume 'name' is the volume's media ID (you can treat 'Volume Name' == 'Volume Media ID'). /// @see https://learn.microsoft.com/uwp/api/windows.management.deployment.packagevolume @@ -71,6 +84,15 @@ namespace Microsoft.Windows.Management.Deployment UsePreference, }; + /// Defines the stub behavior for an app package that is being added or staged. + [contract(PackageDeploymentContract, 2)] + enum PackageReadyOrNewerAvailableStatus + { + NotReady = 0, + Ready = 1, + NewerAvailable = 2, + }; + /// The progress status of the deployment request. /// @see https://learn.microsoft.com/uwp/api/windows.management.deployment.deploymentprogress.state [contract(PackageDeploymentContract, 1)] @@ -258,6 +280,9 @@ namespace Microsoft.Windows.Management.Deployment EnsureReadyOptions(); AddPackageOptions AddPackageOptions { get; }; + + [contract(PackageDeploymentContract, 2)] + Boolean RegisterNewerIfAvailable; } [contract(PackageDeploymentContract, 1)] @@ -266,6 +291,11 @@ namespace Microsoft.Windows.Management.Deployment // Get an instance of the manager static PackageDeploymentManager GetDefault(); + //------------------------------------------------------------- + // IsPackageDeploymentFeatureSupported + + static Boolean IsPackageDeploymentFeatureSupported(PackageDeploymentFeature feature); + //------------------------------------------------------------- // IsReady @@ -275,8 +305,24 @@ namespace Microsoft.Windows.Management.Deployment Boolean IsPackageReadyByUri(Windows.Foundation.Uri packageUri); + /// @note packageSet[Item].PackageUri is optional Boolean IsPackageSetReady(PackageSet packageSet); + //------------------------------------------------------------- + // IsReadyOrNewerAvailable + + // Return true if the package(s) are present and available for use + + [contract(PackageDeploymentContract, 2)] + PackageReadyOrNewerAvailableStatus IsPackageReadyOrNewerAvailable(String package); + + [contract(PackageDeploymentContract, 2)] + PackageReadyOrNewerAvailableStatus IsPackageReadyOrNewerAvailableByUri(Windows.Foundation.Uri packageUri); + + /// @note packageSet[Item].PackageUri is optional + [contract(PackageDeploymentContract, 2)] + PackageReadyOrNewerAvailableStatus IsPackageSetReadyOrNewerAvailable(PackageSet packageSet); + //------------------------------------------------------------- // EnsureReady @@ -292,6 +338,7 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress EnsurePackageReadyByUriAsync(Windows.Foundation.Uri packageUri, EnsureReadyOptions options); + /// @note packageSet[Item].PackageUri is required Windows.Foundation.IAsyncOperationWithProgress EnsurePackageSetReadyAsync(PackageSet packageSet, EnsureReadyOptions options); @@ -304,6 +351,7 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress AddPackageByUriAsync(Windows.Foundation.Uri packageUri, AddPackageOptions options); + /// @note packageSet[Item].PackageUri is required Windows.Foundation.IAsyncOperationWithProgress AddPackageSetAsync(PackageSet packageSet, AddPackageOptions options); @@ -316,6 +364,7 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress StagePackageByUriAsync(Windows.Foundation.Uri packageUri, StagePackageOptions options); + /// @note packageSet[Item].PackageUri is required Windows.Foundation.IAsyncOperationWithProgress StagePackageSetAsync(PackageSet packageSet, StagePackageOptions options); @@ -328,6 +377,7 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress RegisterPackageByUriAsync(Windows.Foundation.Uri packageUri, RegisterPackageOptions options); + /// @note packageSet[Item].PackageUri is optional Windows.Foundation.IAsyncOperationWithProgress RegisterPackageSetAsync(PackageSet packageSet, RegisterPackageOptions options); @@ -346,6 +396,7 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress RemovePackageByUriAsync(Windows.Foundation.Uri packageUri, RemovePackageOptions options); + /// @note packageSet[Item].PackageUri is optional Windows.Foundation.IAsyncOperationWithProgress RemovePackageSetAsync(PackageSet packageSet, RemovePackageOptions options); @@ -358,6 +409,7 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress ResetPackageByUriAsync(Windows.Foundation.Uri packageUri); + /// @note packageSet[Item].PackageUri is optional Windows.Foundation.IAsyncOperationWithProgress ResetPackageSetAsync(PackageSet packageSet); @@ -370,9 +422,25 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress RepairPackageByUriAsync(Windows.Foundation.Uri packageUri); + /// @note packageSet[Item].PackageUri is optional Windows.Foundation.IAsyncOperationWithProgress RepairPackageSetAsync(PackageSet packageSet); + //------------------------------------------------------------- + // IsProvisioned + + // Return true if the package(s) are provisioned + + [contract(PackageDeploymentContract, 2)] + Boolean IsPackageProvisioned(String package); + + [contract(PackageDeploymentContract, 2)] + Boolean IsPackageProvisionedByUri(Windows.Foundation.Uri packageUri); + + /// @note packageSet[Item].PackageUri is optional + [contract(PackageDeploymentContract, 2)] + Boolean IsPackageSetProvisioned(PackageSet packageSet); + //------------------------------------------------------------- // Provision packages @@ -382,6 +450,7 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress ProvisionPackageByUriAsync(Windows.Foundation.Uri packageUri, ProvisionPackageOptions options); + /// @note packageSet[Item].PackageUri is optional Windows.Foundation.IAsyncOperationWithProgress ProvisionPackageSetAsync(PackageSet packageSet, ProvisionPackageOptions options); @@ -394,15 +463,16 @@ namespace Microsoft.Windows.Management.Deployment Windows.Foundation.IAsyncOperationWithProgress DeprovisionPackageByUriAsync(Windows.Foundation.Uri packageUri); + /// @note packageSet[Item].PackageUri is optional Windows.Foundation.IAsyncOperationWithProgress DeprovisionPackageSetAsync(PackageSet packageSet); //------------------------------------------------------------- // IsRegistrationPending - Boolean IsPackageRegistrationPending(String packageFamilyName); + Boolean IsPackageRegistrationPending(String packageFullName); - Boolean IsPackageRegistrationPendingForUser(String userSecurityId, String packageFamilyName); + Boolean IsPackageRegistrationPendingForUser(String userSecurityId, String packageFullName); } [contract(PackageDeploymentContract, 1)] diff --git a/dev/PackageManager/API/PackageManagerTelemetry.h b/dev/PackageManager/API/PackageManagerTelemetry.h index 013747307f..3f9a71b7f4 100644 --- a/dev/PackageManager/API/PackageManagerTelemetry.h +++ b/dev/PackageManager/API/PackageManagerTelemetry.h @@ -126,11 +126,11 @@ class PackageManagementTelemetry : public wil::TraceLoggingProvider CATCH_LOG() END_ACTIVITY_CLASS(); - BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(EnsurePackageAsync, PDT_ProductAndServicePerformance); + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(EnsurePackageReadyAsync, PDT_ProductAndServicePerformance); DEFINE_ACTIVITY_START(winrt::hstring const& package) noexcept try { TraceLoggingClassWriteStart( - EnsurePackageAsync, + EnsurePackageReadyAsync, _GENERIC_PARTB_FIELDS_ENABLED, TraceLoggingWideString(package.c_str(), "Package")); } @@ -138,17 +138,17 @@ class PackageManagementTelemetry : public wil::TraceLoggingProvider DEFINE_ACTIVITY_STOP(winrt::hstring const& package) noexcept try { TraceLoggingClassWriteStop( - EnsurePackageAsync, + EnsurePackageReadyAsync, _GENERIC_PARTB_FIELDS_ENABLED, TraceLoggingWideString(package.c_str(), "Package")); } CATCH_LOG() END_ACTIVITY_CLASS(); - BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(EnsurePackageByUriAsync, PDT_ProductAndServicePerformance); + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(EnsurePackageReadyByUriAsync, PDT_ProductAndServicePerformance); DEFINE_ACTIVITY_START(winrt::hstring const& packageUri) noexcept try { TraceLoggingClassWriteStart( - EnsurePackageByUriAsync, + EnsurePackageReadyByUriAsync, _GENERIC_PARTB_FIELDS_ENABLED, TraceLoggingWideString(packageUri.c_str(), "PackageUri")); } @@ -156,7 +156,7 @@ class PackageManagementTelemetry : public wil::TraceLoggingProvider DEFINE_ACTIVITY_STOP(winrt::hstring const& packageUri) noexcept try { TraceLoggingClassWriteStop( - EnsurePackageByUriAsync, + EnsurePackageReadyByUriAsync, _GENERIC_PARTB_FIELDS_ENABLED, TraceLoggingWideString(packageUri.c_str(), "PackageUri")); } diff --git a/dev/PackageManager/API/pch.h b/dev/PackageManager/API/pch.h index 3dcd1b1b1a..22be15110b 100644 --- a/dev/PackageManager/API/pch.h +++ b/dev/PackageManager/API/pch.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include #include @@ -28,5 +30,9 @@ #include #include +#include #include "MsixPackageManager.h" + +#include +#include diff --git a/dev/WindowsAppRuntime_DLL/packages.config b/dev/WindowsAppRuntime_DLL/packages.config index cd05427e9c..647f7eaa06 100644 --- a/dev/WindowsAppRuntime_DLL/packages.config +++ b/dev/WindowsAppRuntime_DLL/packages.config @@ -5,4 +5,5 @@ + diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index ec070ce0f0..37ab34eedf 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include #include @@ -53,6 +55,7 @@ #include #include #include +#include #include #include diff --git a/docs/Coding-Guidelines/GettingStarted.md b/docs/Coding-Guidelines/GettingStarted.md index db39f94802..b5b5aa15cf 100644 --- a/docs/Coding-Guidelines/GettingStarted.md +++ b/docs/Coding-Guidelines/GettingStarted.md @@ -18,7 +18,14 @@ or via the browser: **NOTE:** Visual Studio 2022 doesn't include this SDK but will use it if installed on the machine. -2. Visual Studio 2022 with... +2. Windows 11 SDK 10.0.26100.0 (24H2) + a. Browse to https://go.microsoft.com/fwlink/?linkid=2272610 + b. Save the offered download `winsdksetup.exe` + c. Run winsdksetup.exe + +**NOTE:** Visual Studio 2022 doesn't include this SDK but will use it if installed on the machine. + +3. Visual Studio 2022 with... * Workloads * .NET desktop development * Desktop development with C++ @@ -51,7 +58,7 @@ or via the browser: **NOTE:** You can tell the Visual Studio Installer to do the heavy lifting for you via `More` / `Import configuration` and select `docs\Coding-Guidelines\VisualStudio2022.vsconfig`. -3. Run NuGet Restore +4. Run NuGet Restore * Download nuget.exe version >= 6.2.1 from https://www.nuget.org/downloads e.g. https://dist.nuget.org/win-x86-commandline/v6.2.1/nuget.exe * Open a command prompt @@ -88,7 +95,7 @@ Some tips: ## MSBuild Tips -Build everything from the command line via msbuild e.g. +### Build everything from the command line via msbuild e.g. | Goal | Command Line | |---|---| @@ -103,6 +110,17 @@ See MSBuild documentation for more details. Troubleshoot build problems by enabling binary logging (e.g. `msbuild...-bl`) and use [MSBuild Binary and Structured Log Viewer](https://msbuildlog.com/) to review the log. +### Common Build Errors + +PROBLEM 001: Expired Test Certificate +SYMPTOMS: + VS ErrorList: + MSB3073 The command "signtool.exe sign ..." exited with code 1...\MakeMsix.targets... + Build Output: + Build Output: EXEC : SignTool error : No certificates were found that met all the given criteria. + ...\MakeMsix.targets...error MSB3073: The command "signtool.exe sign ..." exited with code 1. +SOLUTION: Run DevCheck.cmd (from an admin prompt). This detects the expired certificate and prompts to create a new one. + ## Testing Tips * Use Test Explorer to view and run tests via the View menu's `Test Explorer` diff --git a/eng/Version.Dependencies.xml b/eng/Version.Dependencies.xml index fba4803c9f..28fe3c0430 100644 --- a/eng/Version.Dependencies.xml +++ b/eng/Version.Dependencies.xml @@ -29,7 +29,7 @@ - + diff --git a/eng/common/DevCheck.ps1 b/eng/common/DevCheck.ps1 index 7aebb317c1..ff1eb8c1c9 100644 --- a/eng/common/DevCheck.ps1 +++ b/eng/common/DevCheck.ps1 @@ -43,6 +43,9 @@ .PARAMETER NoInteractive Run in non-interactive mode (fail if any need for user input) +.PARAMETER InstallWindowsSDK + Download and install Windows Platform SDKs (if necessary). + .PARAMETER Offline Do not access the network @@ -100,6 +103,8 @@ Param( [Switch]$Clean=$false, + [Switch]$InstallWindowsSDK=$false, + [Switch]$NoInteractive=$false, [Switch]$Offline=$false, @@ -307,7 +312,6 @@ function Get-VSWhereOnline Write-Host "Downloading $global:vswhere from $global:vswhere_url..." Write-Verbose "Executing: curl.exe --output $path -L -# $global:vswhere_url" $null = Start-Process curl.exe -ArgumentList "--output $path -L -# $global:vswhere_url" -Wait -NoNewWindow -PassThru - } if (-not(Test-Path -Path $path -PathType Leaf)) { @@ -456,17 +460,61 @@ function Test-VisualStudio2022Install return $ok } +function Install-WindowsSDK +{ + param( + [String]$version, + [uri]$url + ) + + $path = Join-Path $env:TEMP "winsdksetup-$($version).exe" + if ($Clean -eq $true -And (Test-Path -Path $path -PathType Leaf)) + { + Write-Verbose "Found $path. Deleting per -Clean..." + Remove-Item -Path $path -Force + } + + $log = Join-Path $env:TEMP "winsdksetup-$($version).log" + if ($Clean -eq $true -And (Test-Path -Path $log -PathType Leaf)) + { + Write-Verbose "Found $log. Deleting per -Clean..." + Remove-Item -Path $log -Force + } + + if (-not(Test-Path -Path $path -PathType Leaf)) + { + Write-Host "Downloading Windows SDK $version from $url..." + Write-Verbose "Executing: curl.exe --output $path -L -# $url" + $null = Start-Process curl.exe -ArgumentList "--output $path -L -# $url" -Wait -NoNewWindow -PassThru + } + $p = Start-Process $path -ArgumentList "/features + /q /log $log" -Wait -NoNewWindow -PassThru + if ($p.ExitCode -ne 0) + { + Write-Host "...ERROR: Windows SDK $($version) install failed. See $log" -ForegroundColor Red -BackgroundColor Black + $global:issues++ + return $false + } + Write-Host "Install Windows SDK $($version)...OK" + return $true +} + function Test-WindowsSDKInstall { param( - [String]$version + [String]$version, + [uri]$url ) $regkey = "HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\$version" $found = Test-Path $regkey -PathType Container if ($found) { - Write-Verbose "Windows SDK $($version) = OK" + Write-Host "Windows SDK $($version) = OK" + } + elseif ($InstallWindowsSDK -eq $true) + { + Write-Warning "WARNING: Windows SDK $($version) not found. Installing..." + $null = Install-WindowsSDK $version $url } else { @@ -1279,8 +1327,8 @@ function Get-DeveloperMode $regkey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock' if (Test-Path -Path $regkey -PathType Container) { - $value = Get-ItemProperty -Path $regkey -Name AllowDevelopmentWithoutDevLicense - return $value.AllowDevelopmentWithoutDevLicense -eq 1 + $value = $(Get-Item -Path $regkey).GetValue('AllowDevelopmentWithoutDevLicense') + return $value -eq 1 } return $false @@ -1297,7 +1345,6 @@ function Test-DeveloperMode { Write-Host "ERROR: Developer mode is not enabled. Enable it via Settings" -ForegroundColor Red -BackgroundColor Black $global:issues++ - $fatal_errors++ } } @@ -1354,7 +1401,8 @@ if (($CheckAll -ne $false) -Or ($CheckVisualStudio -ne $false)) { $null = Test-VisualStudioComponents } - $null = Test-WindowsSDKInstall '10.0.17763.0' + $null = Test-WindowsSDKInstall '10.0.17763.0' [uri]'https://go.microsoft.com/fwlink/p/?LinkID=2033908' + #TODO Uncomment to require new SDK: $null = Test-WindowsSDKInstall '10.0.26100.0' [uri]'https://go.microsoft.com/fwlink/?linkid=2272610' } if (($CheckAll -ne $false) -Or ($CheckTestPfx -ne $false)) diff --git a/installer/test/InstallerFunctionalTests/packages.config b/installer/test/InstallerFunctionalTests/packages.config index 1117ac430f..dc444ff576 100644 --- a/installer/test/InstallerFunctionalTests/packages.config +++ b/installer/test/InstallerFunctionalTests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/specs/packagemanager/PackageManagement.md b/specs/packagemanager/PackageManagement.md index e84b679b46..aa2c5355b7 100644 --- a/specs/packagemanager/PackageManagement.md +++ b/specs/packagemanager/PackageManagement.md @@ -17,10 +17,12 @@ but with additional functionality, improved developer experience and performance - [3.6. Reset](#36-reset) - [3.7. IsPackageRegistrationPending](#37-ispackageregistrationpending) - [3.8. PackageSet](#38-packageset) + - [3.8.1. PackageSet Properties](#381-packageset-properties) + - [3.8.2. PackageSetItem Properties](#382-packagesetitem-properties) - [3.9. PackageRuntimeManager](#39-packageruntimemanager) - [3.10. PackageVolume Repair](#310-packagevolume-repair) - [3.11. Usability](#311-usability) - - [3.12 Is\*Provisioned()](#312-isprovisioned) + - [3.12. Is\*Provisioned()](#312-312-isprovisioned) - [4. Examples](#4-examples) - [4.1. AddPackageAsync()](#41-addpackageasync) - [4.2. AddPackageByUriAsync()](#42-addpackagebyuriasync) @@ -133,10 +135,10 @@ The following table shows the supported permutations of verbs and targets: Legend: -* OS = Supported by Windows (OS) APIs in the Windows.Management.Deployment.PackageManager namespace. -* WAS = Supported by Windows App SDK APIs in the +* **OS** = Supported by Windows (OS) APIs in the Windows.Management.Deployment.PackageManager namespace. +* **WAS** = Supported by Windows App SDK APIs in the Microsoft.Windows.Management.Deployment.PackageDeploymentManager namespace. -* X = Not supported +* **X** = Not supported ## 3.2. Is\*Ready() @@ -286,6 +288,50 @@ foreach (PackageSetItem psi in ps.Items) return new PackageDeploymentResult(PackageDeploymentStatus.CompletedSuccess); ``` +### 3.8.1. PackageSet Properties + +`Id` is optional. This is used primarily for logging and troubleshooting. + +`Items` is required to contain 1+ item. + +`PackageUri` is optional. This is used if a `PackageUri` is needed for a `PackageSetItem` but the +`PackageSetItem.PackageUri` is not specified. + +### 3.8.2. PackageSetItem Properties + +`Id` is required and used primarily for logging and troubleshooting. + +`MinVersion` is optional. If not set the default value is 0.0.0.0. Some verbs use this property (see below). + +`PackageFamilyName` is optional. Some verbs require this property (see below). + +`PackageUri` is optional. If a `PackageUri` is needed and this is not set the `PackageSet`'s `PackageUri` property is used. Some verbs require this property (see below). + +`ProcessorArchitectureFilter` is optional. If not set the default value is `Microsoft.Windows.ApplicationModel.DynamicDependency.PackageDependencyProcessorArchitectures.None`. Only some verbs use this property (see below). + +|Verb | MinVersion | PackageFamilyName | PackageUri | ProcessorArchitectureFilter | +|------------------------|:----------:|:-------------------------:|:----------:|:---------------------------:| +|IsReady | Used | Required | N/A | Optional | +|IsReadyOrNewerAvailable | Used | Required | N/A | Optional | +|EnsureReady | Used | Required | Used | Optional | +|Add | N/A | N/A | Used | N/A | +|Stage | N/A | N/A | USed | N/A | +|Register | N/A | N/A | Used | N/A | +|Remove | N/A | Used-if-no-PackageUri | Optional | N/A | +|Repair | N/A | Used-if-no-PackageUri | Optional | N/A | +|Reset | N/A | Used-if-no-PackageUri | Optional | N/A | +|IsProvisioned | N/A | Used | Optional | N/A | +|Provision | N/A | Used-if-no-PackageUri | Optional | N/A | +|Deprovision | N/A | Used-if-no-PackageUri | Optional | N/A | + +**Legend:** + +* **N/A** = Not applicable. This property is not used. +* **Optional** = This property is used, if specified. +* **Required** = This property is required. +* **Used** = This property is used; if not specified, the default value is used. + + ## 3.9. PackageRuntimeManager The `PackageRuntimeManager` API provides Dynamic Dependency support for PackageSet operations, @@ -347,7 +393,7 @@ package management APIs in Windows (e.g. Windows.Management.Deployment.PackageMa not PackageFamilyName. `PackageDeploymentManager` provides a richer API accepting additional identifiers. -## 3.12 Is*Provisioned() +## 3.12. Is*Provisioned() Is\*Provisioned\*() methods determine if the target is provisioned. @@ -1173,9 +1219,9 @@ namespace Microsoft.Windows.Management.Deployment //------------------------------------------------------------- // IsRegistrationPending - Boolean IsPackageRegistrationPending(String packageFamilyName); + Boolean IsPackageRegistrationPending(String packageFullName); - Boolean IsPackageRegistrationPendingForUser(String userSecurityId, String packageFamilyName); + Boolean IsPackageRegistrationPendingForUser(String userSecurityId, String packageFullName); } [contract(PackageDeploymentContract, 1)] diff --git a/test/AccessControlTests/packages.config b/test/AccessControlTests/packages.config index 3313efc9ef..e0f09cb394 100644 --- a/test/AccessControlTests/packages.config +++ b/test/AccessControlTests/packages.config @@ -1,5 +1,5 @@  - + diff --git a/test/AppLifecycle/packages.config b/test/AppLifecycle/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/AppLifecycle/packages.config +++ b/test/AppLifecycle/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/AppNotificationBuilderTests/packages.config b/test/AppNotificationBuilderTests/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/AppNotificationBuilderTests/packages.config +++ b/test/AppNotificationBuilderTests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/AppNotificationTests/packages.config b/test/AppNotificationTests/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/AppNotificationTests/packages.config +++ b/test/AppNotificationTests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/Common/packages.config b/test/Common/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/Common/packages.config +++ b/test/Common/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/Common/pch.h b/test/Common/pch.h index 332b96ac0d..1991ea6489 100644 --- a/test/Common/pch.h +++ b/test/Common/pch.h @@ -11,6 +11,7 @@ #define PCH_H #include +#include #include #include diff --git a/test/Deployment/API/packages.config b/test/Deployment/API/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/Deployment/API/packages.config +++ b/test/Deployment/API/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/DynamicDependency/Test_Win32/packages.config b/test/DynamicDependency/Test_Win32/packages.config index 1861ca894b..9749bd8146 100644 --- a/test/DynamicDependency/Test_Win32/packages.config +++ b/test/DynamicDependency/Test_Win32/packages.config @@ -1,4 +1,4 @@  - + diff --git a/test/DynamicDependency/Test_WinRT/packages.config b/test/DynamicDependency/Test_WinRT/packages.config index 1861ca894b..9749bd8146 100644 --- a/test/DynamicDependency/Test_WinRT/packages.config +++ b/test/DynamicDependency/Test_WinRT/packages.config @@ -1,4 +1,4 @@  - + diff --git a/test/EnvironmentManagerTests/packages.config b/test/EnvironmentManagerTests/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/EnvironmentManagerTests/packages.config +++ b/test/EnvironmentManagerTests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/LRPTests/packages.config b/test/LRPTests/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/LRPTests/packages.config +++ b/test/LRPTests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/PackageManager/API/PackageDeploymentManagerTests.cpp b/test/PackageManager/API/PackageDeploymentManagerTests.cpp index b4ed6f593b..62b6ebf490 100644 --- a/test/PackageManager/API/PackageDeploymentManagerTests.cpp +++ b/test/PackageManager/API/PackageDeploymentManagerTests.cpp @@ -3,48 +3,19 @@ #include "pch.h" +#include "PackageDeploymentManagerTests.h" + #include namespace TD = ::Test::Diagnostics; namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; namespace TPMT = ::Test::PackageManager::Tests; namespace Test::PackageManager::Tests { - class PackageDeploymentManagerTests_Base - { - protected: - winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus(PCWSTR packageFullName) - { - return TPMT::GetPackageStatus(m_packageManager, packageFullName); - } - - void SetPackageStatus(PCWSTR packageFullName, winrt::Windows::Management::Deployment::PackageStatus status) - { - TPMT::SetPackageStatus(m_packageManager, packageFullName, status); - } - - void SetPackageStatusByPackageFamilyName(PCWSTR packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus status) - { - TPMT::SetPackageStatusByPackageFamilyName(m_packageManager, packageFamilyName, status); - } - - void ClearPackageStatus(PCWSTR packageFullName, winrt::Windows::Management::Deployment::PackageStatus status) - { - TPMT::ClearPackageStatus(m_packageManager, packageFullName, status); - } - - void ClearPackageStatusByPackageFamilyName(PCWSTR packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus status) - { - TPMT::ClearPackageStatusByPackageFamilyName(m_packageManager, packageFamilyName, status); - } - - protected: - winrt::Windows::Management::Deployment::PackageManager m_packageManager; - }; - class PackageDeploymentManagerTests : PackageDeploymentManagerTests_Base { public: @@ -59,2340 +30,42 @@ namespace Test::PackageManager::Tests WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); return true; } - RemovePackage_Blue(); - RemovePackage_Green(); - RemovePackage_Redder(); - RemovePackage_Red(); + ::TB::Setup(); return true; } TEST_CLASS_CLEANUP(ClassCleanup) { - RemovePackage_Blue(); - RemovePackage_Green(); - RemovePackage_Redder(); - RemovePackage_Red(); ::TB::Cleanup(); return true; } - TEST_METHOD(IsPackageSetReady_InvalidParameter) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - try - { - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - packageDeploymentManager.IsPackageSetReady(packageSet); - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - - packageDeploymentManager.IsPackageSetReady(packageSet); - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - packageSet.Items().Append(packageSetItem); - - packageDeploymentManager.IsPackageSetReady(packageSet); - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Not a valid Package Family Name" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - packageSet.Items().Append(packageSetItem); - - packageDeploymentManager.IsPackageSetReady(packageSet); - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - packageSet.Items().Append(packageSetItem); - - packageDeploymentManager.IsPackageSetReady(packageSet); - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageUriAsString{ L"https://doesnotexist.com/assemble.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - packageSetItem.PackageUri(packageUri); - packageSet.Items().Append(packageSetItem); - - packageDeploymentManager.IsPackageSetReady(packageSet); - 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(IsPackageSetReady_1_NoSuchPackage_No) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - packageSetItem.PackageUri(packageUri); - packageSet.Items().Append(packageSetItem); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(IsPackageSetReady_1_NotInstalled_No) - { - RemovePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(IsPackageSetReady_1_Registered_Yes) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(IsPackageSetReady_1_OlderRegistered_No) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; - packageSet.Items().Append(redder); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(IsPackageSetReady_1_NewerRegistered_Yes) - { - AddPackage_Redder(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(IsPackageSetReady_N_NotInstalled_No) - { - RemovePackage_Red(); - RemovePackage_Green(); - RemovePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(IsPackageSetReady_N_Registered_Yes) - { - AddPackage_Red(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(IsPackageSetReady_N_OlderRegistered_No) - { - AddPackage_Red(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; - packageSet.Items().Append(redder); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(IsPackageSetReady_N_NewerRegistered_Yes) - { - AddPackage_Redder(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(IsPackageSetReady_N_RegisteredAndNotInstalled_No) - { - AddPackage_Red(); - RemovePackage_Green(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(IsPackageSetReady_N_No_NotAllPackageStatusOK) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - AddPackage_Red(); - AddPackage_Green(); - SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); - - ClearPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_InvalidParameter) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - try - { - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - packageSet.Items().Append(packageSetItem); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Not a valid Package Family Name" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - packageSet.Items().Append(packageSetItem); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - packageSet.Items().Append(packageSetItem); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageUriAsString{ L"file://c:/assemble.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - packageSetItem.PackageUri(packageUri); - packageSet.Items().Append(packageSetItem); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - 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(EnsurePackageSetReadyAsync_1_NoSuchPackage_Fail) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - packageSetItem.PackageUri(packageUri); - packageSet.Items().Append(packageSetItem); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_1_NotInstalled_Success) - { - RemovePackageFamily_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_1_Staged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_1_Registered_Success) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_1_OlderRegistered_Success) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; - packageSet.Items().Append(redder); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_1_NewerRegistered_Success) - { - AddPackage_Redder(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_N_NotInstalled_Success) - { - RemovePackageFamily_Red(); - RemovePackage_Green(); - RemovePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_N_Registered_Success) - { - AddPackage_Red(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_N_NewerRegistered_Success) - { - AddPackage_Redder(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_N_OlderRegistered_Success) - { - AddPackage_Red(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; - packageSet.Items().Append(redder); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_N_RegisteredAndNotInstalled_Success) - { - AddPackage_Red(); - RemovePackage_Green(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_N_RegisteredAndNotInstalledAndStaged_Success) + TEST_METHOD(IsPackageDeploymentFeatureSupported_InvalidParameter) { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - AddPackage_Red(); - RemovePackage_Green(); - StagePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + const auto feature{ static_cast(0) }; + VERIFY_IS_FALSE(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::IsPackageDeploymentFeatureSupported(feature)); } + }; +} - TEST_METHOD(AddPackageAsync_NoSuchPackage_Fail) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - PCWSTR package{ L"c:\\does\\not\\exist.msix" }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - } - - TEST_METHOD(AddPackageAsync_NotInstalled_Success) - { - RemovePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - } - - TEST_METHOD(AddPackageAsync_Staged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - } - - TEST_METHOD(AddPackageAsync_Registered_Success) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - } - - TEST_METHOD(AddPackageAsync_OlderRegistered_Success) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - - RemovePackage_Redder(); - } - - TEST_METHOD(AddPackageAsync_NewerRegistered_Success) - { - AddPackage_Redder(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Redder()); - - RemovePackage_Redder(); - } - - TEST_METHOD(AddPackageByUriAsync_NoSuchPackage_Fail) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - } - - TEST_METHOD(AddPackageByUriAsync_NotInstalled_Success) - { - RemovePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - } - - TEST_METHOD(AddPackageByUriAsync_Staged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - } - - TEST_METHOD(AddPackageByUriAsync_Registered_Success) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - } - - TEST_METHOD(AddPackageByUriAsync_OlderRegistered_Success) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - - RemovePackage_Redder(); - } - - TEST_METHOD(AddPackageByUriAsync_NewerRegistered_Success) - { - AddPackage_Redder(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Redder()); - - RemovePackage_Redder(); - } - - TEST_METHOD(AddPackageSetAsync_1_NoSuchPackage_Fail) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - packageSetItem.PackageUri(packageUri); - packageSet.Items().Append(packageSetItem); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(AddPackageSetAsync_1_NotInstalled_Success) - { - RemovePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(AddPackageSetAsync_1_Staged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(AddPackageSetAsync_1_Registered_Success) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(AddPackageSetAsync_1_OlderRegistered_Success) - { - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; - packageSet.Items().Append(redder); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(AddPackageSetAsync_1_NewerRegistered_Success) - { - AddPackage_Redder(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(AddPackageSetAsync_N_NotInstalled_Success) - { - RemovePackage_Red(); - RemovePackage_Green(); - RemovePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(AddPackageSetAsync_N_Registered_Success) - { - AddPackage_Red(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(AddPackageSetAsync_N_NewerRegistered_Success) - { - AddPackage_Redder(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(AddPackageSetAsync_N_OlderRegistered_Success) - { - AddPackage_Red(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; - packageSet.Items().Append(redder); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackage_Redder(); - } - - TEST_METHOD(AddPackageSetAsync_N_RegisteredAndNotInstalled_Success) - { - AddPackage_Red(); - RemovePackage_Green(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(AddPackageSetAsync_N_RegisteredAndNotInstalledAndStaged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - AddPackage_Red(); - RemovePackage_Green(); - StagePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageAsync_NoSuchPackage_Fail) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - PCWSTR package{ L"c:\\does\\not\\exist.msix" }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - // - // NOTE: ExtendedError() should be HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) but on some platforms may be S_OK (and also ErrorText() may be empty) - VERIFY_IS_TRUE((deploymentResult.ExtendedError() == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) || (deploymentResult.ExtendedError() == S_OK), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - if (FAILED(deploymentResult.ExtendedError())) - { - VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - } - } - - TEST_METHOD(StagePackageAsync_NotInstalled_Success) - { - RemovePackageFamily_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - VERIFY_IS_TRUE(IsPackageStaged_Red()); - } - - TEST_METHOD(StagePackageAsync_Staged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - RemovePackageFamily_Red(); - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - } - - TEST_METHOD(StagePackageAsync_Registered_Success) - { - RemovePackageFamily_Red(); - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - } - - TEST_METHOD(StagePackageAsync_OlderStaged_Success) - { - RemovePackageFamily_Red(); - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_FALSE(IsPackageStaged_Redder()); - - RemovePackage_Redder(); - } - - TEST_METHOD(StagePackageAsync_NewerStaged_Success) - { - RemovePackageFamily_Redder(); - StagePackage_Redder(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Redder()); - - RemovePackageFamily_Redder(); - } - - TEST_METHOD(StagePackageByUriAsync_NoSuchPackage_Fail) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - // - // NOTE: ExtendedError() should be HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) but on some platforms may be S_OK (and also ErrorText() may be empty) - VERIFY_IS_TRUE((deploymentResult.ExtendedError() == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) || (deploymentResult.ExtendedError() == S_OK), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - if (FAILED(deploymentResult.ExtendedError())) - { - VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - } - } - - TEST_METHOD(StagePackageByUriAsync_NotInstalled_Success) - { - RemovePackageFamily_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - } - - TEST_METHOD(StagePackageByUriAsync_Staged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - RemovePackageFamily_Red(); - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - } - - TEST_METHOD(StagePackageByUriAsync_Registered_Success) - { - RemovePackageFamily_Red(); - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - } - - TEST_METHOD(StagePackageByUriAsync_OlderStaged_Success) - { - RemovePackageFamily_Red(); - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_FALSE(IsPackageStaged_Redder()); - - RemovePackageFamily_Redder(); - } - - TEST_METHOD(StagePackageByUriAsync_NewerStaged_Success) - { - RemovePackageFamily_Redder(); - StagePackage_Redder(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Redder()); - - RemovePackageFamily_Redder(); - } - - TEST_METHOD(StagePackageSetAsync_1_NoSuchPackage_Fail) - { - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - packageSetItem.PackageUri(packageUri); - packageSet.Items().Append(packageSetItem); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - // - // NOTE: ExtendedError() should be HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) but on some platforms may be S_OK (and also ErrorText() may be empty) - VERIFY_IS_TRUE((deploymentResult.ExtendedError() == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) || (deploymentResult.ExtendedError() == S_OK), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - if (FAILED(deploymentResult.ExtendedError())) - { - VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - } - - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_1_NotInstalled_Success) - { - RemovePackageFamily_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_1_Staged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - RemovePackageFamily_Red(); - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_1_Registered_Success) - { - RemovePackageFamily_Red(); - AddPackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_1_OlderStaged_Success) - { - RemovePackageFamily_Red(); - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; - packageSet.Items().Append(redder); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_FALSE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Redder()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - RemovePackageFamily_Red(); - } - - TEST_METHOD(StagePackageSetAsync_1_NewerStaged_Success) - { - RemovePackageFamily_Red(); - StagePackage_Redder(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_FALSE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Redder()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_NoSuchPackage_Fail) - { - RemovePackageFamily_Red(); - RemovePackage_Blue(); - StagePackage_Red(); - StagePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"Does.Not.Exist" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; - PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; - packageSetItem.PackageFamilyName(c_packageFamilyName); - PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; - winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; - packageSetItem.PackageUri(packageUri); - packageSet.Items().Append(packageSetItem); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); - VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - // - // NOTE: ExtendedError() should be HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) but on some platforms may be S_OK (and also ErrorText() may be empty) - VERIFY_IS_TRUE((deploymentResult.ExtendedError() == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) || (deploymentResult.ExtendedError() == S_OK), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - if (FAILED(deploymentResult.ExtendedError())) - { - VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - } - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Blue()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_NotInstalled_Success) - { - RemovePackageFamily_Red(); - RemovePackage_Green(); - RemovePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Green()); - VERIFY_IS_TRUE(IsPackageStaged_Blue()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_Staged_Success) - { - RemovePackageFamily_Red(); - RemovePackage_Green(); - RemovePackage_Blue(); - StagePackage_Red(); - StagePackage_Green(); - StagePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Green()); - VERIFY_IS_TRUE(IsPackageStaged_Blue()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_Registered_Success) - { - RemovePackageFamily_Red(); - RemovePackage_Green(); - RemovePackage_Blue(); - AddPackage_Red(); - AddPackage_Green(); - AddPackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Green()); - VERIFY_IS_TRUE(IsPackageStaged_Blue()); - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_OlderStaged_Success) - { - RemovePackageFamily_Red(); - RemovePackage_Green(); - RemovePackage_Blue(); - StagePackage_Red(); - StagePackage_Green(); - StagePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; - packageSet.Items().Append(redder); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Redder()); - VERIFY_IS_TRUE(IsPackageStaged_Green()); - VERIFY_IS_TRUE(IsPackageStaged_Blue()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_NewerStaged_Success) - { - RemovePackageFamily_Redder(); - RemovePackage_Green(); - RemovePackage_Blue(); - StagePackage_Redder(); - StagePackage_Green(); - StagePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Redder()); - VERIFY_IS_TRUE(IsPackageStaged_Green()); - VERIFY_IS_TRUE(IsPackageStaged_Blue()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_StagedAndNotInstalled_Success) - { - RemovePackageFamily_Red(); - RemovePackage_Green(); - StagePackage_Red(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Green()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_StagedAndNotInstalledAndStaged_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - RemovePackageFamily_Red(); - RemovePackage_Green(); - RemovePackage_Blue(); - StagePackage_Red(); - StagePackage_Blue(); - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(blue); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Green()); - VERIFY_IS_TRUE(IsPackageStaged_Blue()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - }; - - class PackageDeploymentManagerTests_Elevated : PackageDeploymentManagerTests_Base - { - public: - BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Elevated) - TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") - TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") - END_TEST_CLASS() - - TEST_CLASS_SETUP(ClassSetup) - { - if (!::WindowsVersion::IsWindows10_20H1OrGreater()) - { - WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); - return true; - } - - TD::DumpExecutionContext(); - - RemovePackage_Blue(); - RemovePackage_Green(); - RemovePackage_Redder(); - RemovePackage_Red(); - AddPackage_Red(); - ::TB::Setup(); - return true; - } - - TEST_CLASS_CLEANUP(ClassCleanup) - { - TD::DumpExecutionContext(); - - RemovePackage_Blue(); - RemovePackage_Green(); - RemovePackage_Redder(); - RemovePackage_Red(); - ::TB::Cleanup(); - return true; - } - - TEST_METHOD(IsPackageSetReady_1_RegisteredPackageStatusBad_No) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - AddPackage_Red(); - SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - - ClearPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_1_RegisteredPackageStatusBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - AddPackage_Red(); - SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(EnsurePackageSetReadyAsync_N_RegisteredPackageStatusOkAndBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - AddPackage_Red(); - AddPackage_Green(); - SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - - winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; - auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(AddPackageAsync_RegisteredPackageStatusBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - AddPackage_Red(); - SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - } - - TEST_METHOD(AddPackageByUriAsync_RegisteredPackageStatusBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - AddPackage_Red(); - SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageRegistered_Red()); - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - } - - TEST_METHOD(AddPackageSetAsync_1_RegisteredPackageStatusBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - AddPackage_Red(); - SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - } - - TEST_METHOD(AddPackageSetAsync_N_RegisteredPackageStatusOkAndBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - AddPackage_Red(); - AddPackage_Green(); - SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - - winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; - auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); - VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); - } - - TEST_METHOD(StagePackageAsync_StagedPackageStatusBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - RemovePackageFamily_Red(); - StagePackage_Red(); - SetPackageStatus(::TPF::Red::GetPackageFullName(), winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(IsPackageRegistered_Red()); - - const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; - const winrt::hstring package{ packagePath.c_str() }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageAsync(package, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - } - - TEST_METHOD(StagePackageByUriAsync_StagedPackageStatusBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - RemovePackageFamily_Red(); - StagePackage_Red(); - SetPackageStatusByPackageFamilyName(::TPF::Red::GetPackageFullName(), winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - - winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - } - - TEST_METHOD(StagePackageSetAsync_1_StagedPackageStatusBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - RemovePackageFamily_Red(); - StagePackage_Red(); - SetPackageStatusByPackageFamilyName(::TPF::Red::GetPackageFullName(), winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); - } - - TEST_METHOD(StagePackageSetAsync_N_StagedPackageStatusOkAndBad_Success) - { - BEGIN_TEST_METHOD_PROPERTIES() - TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") - END_TEST_METHOD_PROPERTIES() - - auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; - - RemovePackageFamily_Red(); - RemovePackage_Green(); - StagePackage_Red(); - StagePackage_Green(); - SetPackageStatusByPackageFamilyName(::TPF::Green::GetPackageFullName(), winrt::Windows::Management::Deployment::PackageStatus::Modified); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); - - winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; - PCWSTR c_packageSetId{ L"RGB" }; - packageSet.Id(c_packageSetId); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; - packageSet.Items().Append(red); - winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; - packageSet.Items().Append(green); - - winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; - auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; - VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess, deploymentResult.Status()); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); - VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); - - VERIFY_IS_TRUE(IsPackageStaged_Red()); - VERIFY_IS_TRUE(IsPackageStaged_Green()); - VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); - } - }; +void Test::PackageManager::Tests::VerifyDeploymentSucceeded( + const winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentResult& deploymentResult, + PCSTR filename, + int line, + PCSTR function) +{ + WEX::Common::String source; + source.Format(L"File: %hs, Function: %hs, Line: %d", filename, function, line); + PCWSTR message{ static_cast(source) }; + + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"VERIFY Deployment Suceeded: %ls", message)); + + const bool ok{ (deploymentResult.Status() == winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedSuccess) && + (deploymentResult.Error() == S_OK) && + (deploymentResult.ExtendedError() == S_OK) && + deploymentResult.ErrorText().empty() }; + VERIFY_IS_TRUE(ok, WEX::Common::String().Format(L"Status:%d Error:0x%X ExtendedError:0x%X ErrorText:%ls %ls", + deploymentResult.Status(), deploymentResult.Error(), deploymentResult.ExtendedError(), + deploymentResult.ErrorText().c_str(), message)); } diff --git a/test/PackageManager/API/PackageDeploymentManagerTests.h b/test/PackageManager/API/PackageDeploymentManagerTests.h new file mode 100644 index 0000000000..738a4b4c42 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests.h @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + inline bool SkipIfFeatureNotSupported( + const winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature feature, + PCWSTR message) + { + const bool isSupported{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::IsPackageDeploymentFeatureSupported(feature) }; + if (!isSupported) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, message); + } + return !isSupported; + } + + inline bool SkipIfFeatureNotSupported_PackageUriScheme_ms_uup() + { + const auto feature{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::PackageUriScheme_ms_uup }; + PCWSTR message{ L"ms-uup: not supported on this system. Skipping test" }; + return TPMT::SkipIfFeatureNotSupported(feature, message); + } + + inline bool SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable() + { + const auto feature{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::IsPackageReadyOrNewerAvailable }; + PCWSTR message{ L"IsPackageReadyOrNewerAvailable not supported on this system. Skipping test" }; + return TPMT::SkipIfFeatureNotSupported(feature, message); + } + + inline bool SkipIfFeatureNotSupported_RemovePackageByUri() + { + const auto feature{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::RemovePackageByUri }; + PCWSTR message{ L"RemovePackageByUri not supported on this system. Skipping test" }; + return TPMT::SkipIfFeatureNotSupported(feature, message); + } + + inline bool SkipIfFeatureNotSupported_ResetPackage() + { + const auto feature{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ResetPackage }; + PCWSTR message{ L"ResetPackage not supported on this system. Skipping test" }; + return TPMT::SkipIfFeatureNotSupported(feature, message); + } + + inline bool SkipIfFeatureNotSupported_RepairPackage() + { + const auto feature{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::RepairPackage }; + PCWSTR message{ L"RepairPackage not supported on this system. Skipping test" }; + return TPMT::SkipIfFeatureNotSupported(feature, message); + } + + inline bool SkipIfFeatureNotSupported_ProvisionPackage_Framework() + { + const auto feature{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ProvisionPackage_Framework }; + PCWSTR message{ L"ProvisionPackage.Framework not supported on this system. Skipping test" }; + return TPMT::SkipIfFeatureNotSupported(feature, message); + } + + inline bool PreBootstrap_SkipIfFeatureNotSupported( + const winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature feature, + PCWSTR message) + { + // NOTE: Some tests can't use winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature + // due to chicken/egg dependencies (can't use it before Bootstrapper's initialized but need access + // before Bootstrapper's initialized...). So we'll handle them by directly calling the FrameworkUdk + // + // NOTE: Only support necessary features here. + switch (feature) + { + case winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ProvisionPackage_Framework: + { + //TODO Awaiting ProvisionPackageForAllUsersAsync() support for Framework packages + //return IsPackageDeploymentFeatureSupported(L"ProvisionPackage.Framework"); + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, message); + return true; + } + default: + { + // Unsupported pre-Bootstrap feature check + WEX::Logging::Log::Result(WEX::Logging::TestResults::Blocked, message); + VERIFY_FAIL(WEX::Common::String().Format(L"Feature:%d", static_cast(feature))); + return true; + } + } + } + + inline bool PreBootstrap_SkipIfFeatureNotSupported_ProvisionPackage_Framework() + { + const auto feature{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentFeature::ProvisionPackage_Framework }; + PCWSTR message{ L"ProvisionPackage.Framework not supported on this system. Skipping test" }; + return TPMT::PreBootstrap_SkipIfFeatureNotSupported(feature, message); + } + + void VerifyDeploymentSucceeded( + const winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentResult& deploymentResult, + PCSTR filename, + int line, + PCSTR function); + + class PackageDeploymentManagerTests_Base + { + protected: + inline bool DoNotExecuteTestMethod() const + { + return m_doNotExecuteTestMethod; + } + inline void DoNotExecuteTestMethod(const bool doNotExecuteTestMethod) + { + m_doNotExecuteTestMethod = doNotExecuteTestMethod; + } + private: + bool m_doNotExecuteTestMethod{}; + + protected: + winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus(PCWSTR packageFullName) + { + return TPMT::GetPackageStatus(m_packageManager, packageFullName); + } + + void SetPackageStatus(PCWSTR packageFullName, winrt::Windows::Management::Deployment::PackageStatus status) + { + TPMT::SetPackageStatus(m_packageManager, packageFullName, status); + } + + void SetPackageStatusByPackageFamilyName(PCWSTR packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus status) + { + TPMT::SetPackageStatusByPackageFamilyName(m_packageManager, packageFamilyName, status); + } + + void ClearPackageStatus(PCWSTR packageFullName, winrt::Windows::Management::Deployment::PackageStatus status) + { + TPMT::ClearPackageStatus(m_packageManager, packageFullName, status); + } + + void ClearPackageStatusByPackageFamilyName(PCWSTR packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus status) + { + TPMT::ClearPackageStatusByPackageFamilyName(m_packageManager, packageFamilyName, status); + } + + winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentResult WaitForDeploymentOperation( + winrt::Windows::Foundation::IAsyncOperationWithProgress& deploymentOperation) + { + using namespace winrt::Windows::Foundation; + using namespace winrt::Microsoft::Windows::Management::Deployment; + AsyncOperationProgressHandler progressCallback( + [&](const IAsyncOperationWithProgress&, PackageDeploymentProgress progress) + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"...State:%d Percentage:%lf", static_cast(progress.Status), progress.Progress)); + } + ); + deploymentOperation.Progress(progressCallback); + auto deploymentResult{ deploymentOperation.get() }; + return deploymentResult; + } + + protected: + winrt::Windows::Management::Deployment::PackageManager m_packageManager; + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Add.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Add.cpp new file mode 100644 index 0000000000..d0a342240e --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Add.cpp @@ -0,0 +1,700 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Add : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Add) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(AddPackageAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR package{ L"c:\\does\\not\\exist.msix" }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentResult{ packageDeploymentManager.AddPackageAsync(package, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(AddPackageAsync_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(AddPackageAsync_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(AddPackageAsync_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(AddPackageAsync_OlderRegistered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + + RemovePackage_Redder(); + } + + TEST_METHOD(AddPackageAsync_NewerRegistered_Success) + { + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Redder()); + + RemovePackage_Redder(); + } + + TEST_METHOD(AddPackageByUriAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentResult{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(AddPackageByUriAsync_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(AddPackageByUriAsync_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(AddPackageByUriAsync_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(AddPackageByUriAsync_OlderRegistered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + + RemovePackage_Redder(); + } + + TEST_METHOD(AddPackageByUriAsync_NewerRegistered_Success) + { + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Redder()); + + RemovePackage_Redder(); + } + + TEST_METHOD(AddPackageSetAsync_1_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentResult{ packageDeploymentManager.AddPackageSetAsync(packageSet, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(AddPackageSetAsync_1_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(AddPackageSetAsync_1_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(AddPackageSetAsync_1_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(AddPackageSetAsync_1_OlderRegistered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(AddPackageSetAsync_1_NewerRegistered_Success) + { + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(AddPackageSetAsync_N_NotInstalled_Success) + { + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(AddPackageSetAsync_N_Registered_Success) + { + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(AddPackageSetAsync_N_NewerRegistered_Success) + { + AddPackage_Redder(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(AddPackageSetAsync_N_OlderRegistered_Success) + { + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(AddPackageSetAsync_N_RegisteredAndNotInstalled_Success) + { + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(AddPackageSetAsync_N_RegisteredAndNotInstalledAndStaged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + AddPackage_Red(); + RemovePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + }; + + class PackageDeploymentManagerTests_Add_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Add_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + AddPackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(AddPackageAsync_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(AddPackageByUriAsync_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(AddPackageSetAsync_1_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(AddPackageSetAsync_N_RegisteredPackageStatusOkAndBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + AddPackage_Green(); + SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.AddPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + } + + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Deprovision_Framework.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Deprovision_Framework.cpp new file mode 100644 index 0000000000..68840170de --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Deprovision_Framework.cpp @@ -0,0 +1,637 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Deprovision_Framework : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Deprovision_Framework) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunFixtureAs", L"ElevatedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + if (TPMT::PreBootstrap_SkipIfFeatureNotSupported_ProvisionPackage_Framework()) + { + return true; + } + + RemovePackage_Red(); + AddPackage_Red(); + ProvisionPackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + DeprovisionPackage_Red(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(DeprovisionPackageAsync_Registered_AccessDenied) + { + AddPackage_Red(); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_ACCESSDENIED, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + }; + + class PackageDeploymentManagerTests_Deprovision_Framework_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Deprovision_Framework_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + TEST_CLASS_PROPERTY(L"RunFixtureAs", L"ElevatedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + if (TPMT::PreBootstrap_SkipIfFeatureNotSupported_ProvisionPackage_Framework()) + { + return true; + } + + TD::DumpExecutionContext(); + + DeprovisionPackage_Blue(); + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + DeprovisionPackage_Blue(); + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(DeprovisionPackageAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + + auto deploymentResult{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(DeprovisionPackageAsync_Staged_Success) + { + DeprovisionPackage_Red(); + StagePackage_Red(); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(DeprovisionPackageAsync_Registered_Success) + { + DeprovisionPackage_Red(); + AddPackage_Red(); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(DeprovisionPackageAsync_StagedProvisioned_Success) + { + DeprovisionPackage_Red(); + StagePackage_Red(); + ProvisionPackage_Red(); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(DeprovisionPackageAsync_RegisteredProvisioned_Success) + { + AddPackage_Red(); + ProvisionPackage_Red(); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(DeprovisionPackageAsync_RegisteredPackageStatusBad_Success) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + DeprovisionPackage_Red(); + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_Staged_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_StagedProvisioned_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_RegisteredProvisioned_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_RegisteredPackageStatusBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + packageSet.Items().Append(packageSetItem); + + auto deploymentResult{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_Staged_Success) + { + DeprovisionPackage_Red(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_Registered_Success) + { + DeprovisionPackage_Red(); + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_StagedProvisioned_Success) + { + DeprovisionPackage_Red(); + StagePackage_Red(); + ProvisionPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_RegisteredProvisioned_Success) + { + DeprovisionPackage_Red(); + AddPackage_Red(); + ProvisionPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_Staged_Success) + { + DeprovisionPackage_Red(); + DeprovisionPackage_Green(); + DeprovisionPackage_Blue(); + StagePackage_Red(); + StagePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_Registered_Success) + { + DeprovisionPackage_Red(); + DeprovisionPackage_Green(); + DeprovisionPackage_Blue(); + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_StagedProvisioned_Success) + { + DeprovisionPackage_Red(); + DeprovisionPackage_Green(); + DeprovisionPackage_Blue(); + StagePackage_Red(); + StagePackage_Green(); + StagePackage_Blue(); + ProvisionPackage_Red(); + ProvisionPackage_Green(); + ProvisionPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_RegisteredProvisioned_Success) + { + DeprovisionPackage_Red(); + DeprovisionPackage_Green(); + DeprovisionPackage_Blue(); + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + ProvisionPackage_Red(); + ProvisionPackage_Green(); + ProvisionPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_RegisteredAndNoSuchPackage_Fail) + { + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_RegisteredAndNoSuchPackageAndStaged_Fail) + { + DeprovisionPackage_Blue(); + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + AddPackage_Red(); + RemovePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(IsPackageRegistered_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(IsPackageRegistered_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Deprovision_Main.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Deprovision_Main.cpp new file mode 100644 index 0000000000..dc07960162 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Deprovision_Main.cpp @@ -0,0 +1,702 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Deprovision_Main : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Deprovision_Main) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunFixtureAs", L"ElevatedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + DoNotExecuteTestMethod(true); + return true; + } + + if (TPMT::PreBootstrap_SkipIfFeatureNotSupported_ProvisionPackage_Framework()) + { + DoNotExecuteTestMethod(true); + return true; + } + + RemovePackage_Black(); + AddPackage_Black(); + ProvisionPackage_Black(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + DeprovisionPackage_Black(); + RemovePackage_Black(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(DeprovisionPackageAsync_Registered_AccessDenied) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + AddPackage_Black(); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPM::Black::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_ACCESSDENIED, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + }; + + class PackageDeploymentManagerTests_Deprovision_Main_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Deprovision_Main_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + TEST_CLASS_PROPERTY(L"RunFixtureAs", L"ElevatedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + DoNotExecuteTestMethod(true); + return true; + } + + if (TPMT::PreBootstrap_SkipIfFeatureNotSupported_ProvisionPackage_Framework()) + { + DoNotExecuteTestMethod(true); + return true; + } + + TD::DumpExecutionContext(); + + DeprovisionPackage_White(); + DeprovisionPackage_Black(); + RemovePackage_White(); + RemovePackage_Blacker(); + RemovePackage_Black(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + DeprovisionPackage_White(); + DeprovisionPackage_Black(); + RemovePackage_White(); + RemovePackage_Blacker(); + RemovePackage_Black(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(DeprovisionPackageAsync_NoSuchPackage_Fail) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + + auto deploymentResult{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(DeprovisionPackageAsync_Staged_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + StagePackage_Black(); + + VERIFY_IS_TRUE(IsPackageStaged_Black()); + VERIFY_IS_FALSE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageProvisioned_Black()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPM::Black::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Black()); + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_TRUE(IsPackageProvisioned_Black()); + } + + TEST_METHOD(DeprovisionPackageAsync_Registered_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + AddPackage_Black(); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageProvisioned_Black()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPM::Black::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageProvisioned_Black()); + } + + TEST_METHOD(DeprovisionPackageAsync_StagedProvisioned_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + StagePackage_Black(); + ProvisionPackage_Black(); + + VERIFY_IS_TRUE(IsPackageStaged_Black()); + VERIFY_IS_FALSE(IsPackageRegistered_Black()); + VERIFY_IS_TRUE(IsPackageProvisioned_Black()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPM::Black::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Black()); + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageProvisioned_Black()); + } + + TEST_METHOD(DeprovisionPackageAsync_RegisteredProvisioned_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + AddPackage_Black(); + ProvisionPackage_Black(); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_TRUE(IsPackageProvisioned_Black()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPM::Black::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageProvisioned_Black()); + } + + TEST_METHOD(DeprovisionPackageAsync_RegisteredPackageStatusBad_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + DeprovisionPackage_Black(); + AddPackage_Black(); + SetPackageStatusByPackageFamilyName(::TPM::Black::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPM::Black::GetPackageFullName())); + VERIFY_IS_FALSE(IsPackageProvisioned_Black()); + + const auto packageFamilyName{ ::TPM::Black::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPM::Black::GetPackageFullName())); + VERIFY_IS_TRUE(IsPackageProvisioned_Black()); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_Staged_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_StagedProvisioned_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_RegisteredProvisioned_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageByUriAsync_RegisteredPackageStatusBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_NoSuchPackage_Fail) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + packageSet.Items().Append(packageSetItem); + + auto deploymentResult{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_Staged_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + StagePackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + black.PackageUri(packageUri); + packageSet.Items().Append(black); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_Registered_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + AddPackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + black.PackageUri(packageUri); + packageSet.Items().Append(black); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_StagedProvisioned_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + StagePackage_Black(); + ProvisionPackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + black.PackageUri(packageUri); + packageSet.Items().Append(black); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_1_RegisteredProvisioned_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + AddPackage_Black(); + ProvisionPackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + black.PackageUri(packageUri); + packageSet.Items().Append(black); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_Staged_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + DeprovisionPackage_White(); + StagePackage_Black(); + StagePackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + packageSet.Items().Append(black); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem(::TPM::White::GetPackageFullName(), ::TPM::White::c_packageDirName) }; + packageSet.Items().Append(white); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_Registered_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + DeprovisionPackage_White(); + AddPackage_Black(); + AddPackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + packageSet.Items().Append(black); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem(::TPM::White::GetPackageFullName(), ::TPM::White::c_packageDirName) }; + packageSet.Items().Append(white); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_StagedProvisioned_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + DeprovisionPackage_White(); + StagePackage_Black(); + StagePackage_White(); + ProvisionPackage_Black(); + ProvisionPackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + packageSet.Items().Append(black); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem(::TPM::White::GetPackageFullName(), ::TPM::White::c_packageDirName) }; + packageSet.Items().Append(white); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_RegisteredProvisioned_Success) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_Black(); + DeprovisionPackage_White(); + AddPackage_Black(); + AddPackage_White(); + ProvisionPackage_Black(); + ProvisionPackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + packageSet.Items().Append(black); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem(::TPM::White::GetPackageFullName(), ::TPM::White::c_packageDirName) }; + packageSet.Items().Append(white); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_RegisteredAndNoSuchPackage_Fail) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_White(); + DeprovisionPackage_Black(); + AddPackage_Black(); + RemovePackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + packageSet.Items().Append(black); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem(::TPM::White::GetPackageFullName(), ::TPM::White::c_packageDirName) }; + packageSet.Items().Append(white); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageRegistered_White()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageRegistered_White()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(DeprovisionPackageSetAsync_N_RegisteredAndNoSuchPackageAndStaged_Fail) + { + if (DoNotExecuteTestMethod()) + { + return; + } + + DeprovisionPackage_White(); + DeprovisionPackage_Black(); + AddPackage_Black(); + RemovePackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + packageSet.Items().Append(black); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem(::TPM::White::GetPackageFullName(), ::TPM::White::c_packageDirName) }; + packageSet.Items().Append(white); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageRegistered_White()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + auto deploymentOperation{ packageDeploymentManager.DeprovisionPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + VERIFY_IS_FALSE(IsPackageRegistered_White()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_EnsureReady.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_EnsureReady.cpp new file mode 100644 index 0000000000..04d22ab0af --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_EnsureReady.cpp @@ -0,0 +1,551 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_EnsureReady : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_EnsureReady) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(EnsurePackageSetReadyAsync_InvalidParameter) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + try + { + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Not a valid Package Family Name" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageUriAsString{ L"file://c:/assemble.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentResult{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options).get() }; + 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(EnsurePackageSetReadyAsync_1_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_1_NotInstalled_Success) + { + RemovePackageFamily_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_1_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_1_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_1_OlderRegistered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_1_NewerRegistered_Success) + { + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_N_NotInstalled_Success) + { + RemovePackageFamily_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_N_Registered_Success) + { + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_N_NewerRegistered_Success) + { + AddPackage_Redder(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_N_OlderRegistered_Success) + { + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_N_RegisteredAndNotInstalled_Success) + { + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_N_RegisteredAndNotInstalledAndStaged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + AddPackage_Red(); + RemovePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + }; + + class PackageDeploymentManagerTests_EnsureReady_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_EnsureReady_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + AddPackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(EnsurePackageSetReadyAsync_1_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(EnsurePackageSetReadyAsync_N_RegisteredPackageStatusOkAndBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + AddPackage_Green(); + SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::EnsureReadyOptions options; + auto deploymentOperation{ packageDeploymentManager.EnsurePackageSetReadyAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_IsPackageRegistrationPending.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_IsPackageRegistrationPending.cpp new file mode 100644 index 0000000000..17155ce4e6 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_IsPackageRegistrationPending.cpp @@ -0,0 +1,163 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_IsPackageRegistrationPending : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_IsPackageRegistrationPending) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blacker(); + RemovePackage_Black(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blacker(); + RemovePackage_Black(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(IsPackageRegistrationPending_NoSuchPackage) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ L"Does.Not.Exist_0.0.0.0_neutral__1234567890abc" }; + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageRegistrationPending(packageFullName)); + } + + TEST_METHOD(IsPackageRegistrationPending_NotInstalled) + { + RemovePackage_Blacker(); + RemovePackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFullName{ ::TPM::Black::GetPackageFullName() }; + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageRegistrationPending(packageFullName)); + } + + TEST_METHOD(IsPackageRegistrationPending_Registered) + { + RemovePackage_Blacker(); + AddPackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPM::Black::GetPackageFullName() }; + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageRegistrationPending(packageFullName)); + } + + TEST_METHOD(IsPackageRegistrationPending_Pending) + { + RemovePackage_Blacker(); + AddPackage_Black(); + + PCWSTR eventName{ L"PackageManagerTests.IsPackageRegistrationPending_Pending.EndOfTheLine" }; + wil::unique_event_nothrow endOfTheLine{ ::CreateEventW(nullptr, TRUE, FALSE, eventName) }; + if (!endOfTheLine) + { + const auto rc{ GetLastError() }; + VERIFY_FAIL(WEX::Common::String().Format(L"CreateEventW() LastError:%u (0x%08X)", rc, rc)); + } + wil::com_ptr AAM{ wil::CoCreateInstance(CLSID_ApplicationActivationManager, CLSCTX_LOCAL_SERVER) }; + PCWSTR appUserModelId{ ::TPM::Black::c_appUserModelId }; + DWORD processId{}; + VERIFY_SUCCEEDED(AAM->ActivateApplication(appUserModelId, eventName, AO_NONE, &processId)); + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AppUserModleId:%s Arguments:%s ProcessId:%u", appUserModelId, eventName, processId)); + + AddPackageDefer_Blacker(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPM::Black::GetPackageFullName() }; + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageRegistrationPending(packageFullName)); + + VERIFY_SUCCEEDED(LOG_IF_WIN32_BOOL_FALSE(::SetEvent(endOfTheLine.get()))); + } + + TEST_METHOD(IsPackageRegistrationPendingForUser_NoSuchPackage) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ L"Does.Not.Exist_0.0.0.0_neutral__1234567890abc" }; + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageRegistrationPendingForUser(winrt::hstring{}, packageFullName)); + } + + TEST_METHOD(IsPackageRegistrationPendingForUser_NotInstalled) + { + RemovePackage_Blacker(); + RemovePackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPM::Black::GetPackageFullName() }; + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageRegistrationPendingForUser(winrt::hstring{}, packageFullName)); + } + + TEST_METHOD(IsPackageRegistrationPendingForUser_Registered) + { + RemovePackage_Blacker(); + AddPackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPM::Black::GetPackageFullName() }; + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageRegistrationPendingForUser(winrt::hstring{}, packageFullName)); + } + + TEST_METHOD(IsPackageRegistrationPendingForUser_Pending) + { + RemovePackage_Blacker(); + AddPackage_Black(); + + PCWSTR eventName{ L"PackageManagerTests.IsPackageRegistrationPendingForUser_Pending.EndOfTheLine" }; + wil::unique_event_nothrow endOfTheLine{ ::CreateEventW(nullptr, TRUE, FALSE, eventName) }; + if (!endOfTheLine) + { + const auto rc{ GetLastError() }; + VERIFY_FAIL(WEX::Common::String().Format(L"CreateEventW() LastError:%u (0x%08X)", rc, rc)); + } + wil::com_ptr AAM{ wil::CoCreateInstance(CLSID_ApplicationActivationManager, CLSCTX_LOCAL_SERVER) }; + PCWSTR appUserModelId{ ::TPM::Black::c_appUserModelId }; + DWORD processId{}; + VERIFY_SUCCEEDED(AAM->ActivateApplication(appUserModelId, eventName, AO_NONE, &processId)); + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AppUserModleId:%s Arguments:%s ProcessId:%u", appUserModelId, eventName, processId)); + + AddPackageDefer_Blacker(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPM::Black::GetPackageFullName() }; + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageRegistrationPendingForUser(winrt::hstring{}, packageFullName)); + + VERIFY_SUCCEEDED(LOG_IF_WIN32_BOOL_FALSE(::SetEvent(endOfTheLine.get()))); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_IsReady.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_IsReady.cpp new file mode 100644 index 0000000000..7faf3387b6 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_IsReady.cpp @@ -0,0 +1,416 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_IsReady : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_IsReady) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(IsPackageReady_InvalidParameter) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + try + { + PCWSTR packageFullName{ L"Not a valid Package Full Name" }; + packageDeploymentManager.IsPackageReady(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())); + } + } + + TEST_METHOD(IsPackageReady_NoSuchPackage_No) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageFullName{ L"Does.Not.Exist_1.2.3.4_neutral__1234567890abc" }; + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(c_packageFullName)); + } + + TEST_METHOD(IsPackageReady_NotInstalled_No) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPF::Red::GetPackageFullName() }; + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(packageFullName)); + } + + TEST_METHOD(IsPackageReady_Registered_Yes) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPF::Red::GetPackageFullName() }; + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(packageFullName)); + } + + TEST_METHOD(IsPackageReady_OlderRegistered_No) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPF::Redder::GetPackageFullName() }; + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(packageFullName)); + } + + TEST_METHOD(IsPackageReady_NewerRegistered_Yes) + { + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPF::Red::GetPackageFullName() }; + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(packageFullName)); + + RemovePackage_Redder(); + } + + TEST_METHOD(IsPackageSetReady_InvalidParameter) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + try + { + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + packageDeploymentManager.IsPackageSetReady(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + + packageDeploymentManager.IsPackageSetReady(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + packageSet.Items().Append(packageSetItem); + + packageDeploymentManager.IsPackageSetReady(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Not a valid Package Family Name" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + packageSet.Items().Append(packageSetItem); + + packageDeploymentManager.IsPackageSetReady(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageUriAsString{ L"https://doesnotexist.com/assemble.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + packageDeploymentManager.IsPackageSetReady(packageSet); + 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(IsPackageSetReady_1_NoSuchPackage_No) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(IsPackageSetReady_1_NotInstalled_No) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(IsPackageSetReady_1_Registered_Yes) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(IsPackageSetReady_1_OlderRegistered_No) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(IsPackageSetReady_1_NewerRegistered_Yes) + { + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(IsPackageSetReady_N_NotInstalled_No) + { + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(IsPackageSetReady_N_Registered_Yes) + { + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(IsPackageSetReady_N_OlderRegistered_No) + { + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(IsPackageSetReady_N_NewerRegistered_Yes) + { + AddPackage_Redder(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(IsPackageSetReady_N_RegisteredAndNotInstalled_No) + { + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(IsPackageSetReady_N_No_NotAllPackageStatusOK) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + AddPackage_Green(); + SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + + ClearPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_IsReadyOrNewerAvailable.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_IsReadyOrNewerAvailable.cpp new file mode 100644 index 0000000000..9a2b56a971 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_IsReadyOrNewerAvailable.cpp @@ -0,0 +1,834 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_IsReadyOrNewerAvailable : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_IsReadyOrNewerAvailable) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFullName_InvalidParameter) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + try + { + PCWSTR packageFullName{ L"Not a valid Package Full Name" }; + packageDeploymentManager.IsPackageReadyOrNewerAvailable(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())); + } + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFullName_NoSuchPackage_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageFullName{ L"Does.Not.Exist_1.2.3.4_neutral__1234567890abc" }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageReadyOrNewerAvailable(c_packageFullName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFullName_NotInstalled_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPF::Red::GetPackageFullName() }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFullName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFullName_Registered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPF::Red::GetPackageFullName() }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFullName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFullName_OlderRegistered_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPF::Redder::GetPackageFullName() }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFullName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFullName_NewerRegistered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPF::Red::GetPackageFullName() }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFullName)); + + RemovePackage_Redder(); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFullName_NewerAvailable) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + RemovePackage_Blacker(); + AddPackage_Black(); + StagePackage_Blacker(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ ::TPM::Black::GetPackageFullName() }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFullName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFamilyName_InvalidParameter) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + try + { + PCWSTR packageFamilyName{ L"Not a valid Package Family Name" }; + packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFamilyName); + 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(IsPackageReadyOrNewerAvailable_PackageFamilyName_NoSuchPackage_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageReadyOrNewerAvailable(c_packageFamilyName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFamilyName_NotInstalled_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFamilyName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFamilyName_Registered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFamilyName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFamilyName_OlderRegistered_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ ::TPF::Redder::c_packageFamilyName }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFamilyName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFamilyName_NewerRegistered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFamilyName)); + + RemovePackage_Redder(); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailable_PackageFamilyName_NewerAvailable) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + RemovePackage_Blacker(); + AddPackage_Black(); + StagePackage_Blacker(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ ::TPM::Black::c_packageFamilyName }; + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable, packageDeploymentManager.IsPackageReadyOrNewerAvailable(packageFamilyName)); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailableByUri_InvalidParameter) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailableByUri_NoSuchPackage_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailableByUri_NotInstalled_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailableByUri_Registered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailableByUri_OlderRegistered_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(IsPackageReadyOrNewerAvailableByUri_NewerRegistered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_InvalidParameter) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + try + { + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + + packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + packageSet.Items().Append(packageSetItem); + + packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Not a valid Package Family Name" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + packageSet.Items().Append(packageSetItem); + + packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + packageSet.Items().Append(packageSetItem); + + packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet); + 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::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageUriAsString{ L"https://doesnotexist.com/assemble.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet); + 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(IsPackageSetReadyOrNewerAvailable_1_NoSuchPackage_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_1_NotInstalled_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_1_Registered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_1_OlderRegistered_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_1_NewerRegistered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_1_NewerAvailable) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + RemovePackage_Blacker(); + AddPackage_Black(); + StagePackage_Blacker(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"B" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + packageSet.Items().Append(black); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_N_NotInstalled_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_N_Registered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_N_OlderRegistered_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_N_NewerRegistered_Ready) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Redder(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::Ready, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + + RemovePackage_Redder(); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_N_RegisteredAndNotInstalled_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_N_RegisteredAndNewerAvailable_NotReady) + { + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + AddPackage_Black(); + RemovePackage_Whiter(); + AddPackage_White(); + StagePackage_Whiter(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"BW" }; + packageSet.Id(c_packageSetId); + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem(::TPM::Black::GetPackageFullName(), ::TPM::Black::c_packageDirName) }; + packageSet.Items().Append(black); + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem(::TPM::White::GetPackageFullName(), ::TPM::White::c_packageDirName) }; + packageSet.Items().Append(white); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NewerAvailable, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + } + + TEST_METHOD(IsPackageSetReadyOrNewerAvailable_N_No_NotAllPackageStatusOK) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_IsPackageReadyOrNewerAvailable()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + AddPackage_Green(); + SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageReadyOrNewerAvailable(::TPF::Green::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageSetReadyOrNewerAvailable(packageSet)); + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageReadyOrNewerAvailableStatus::NotReady, packageDeploymentManager.IsPackageReadyOrNewerAvailable(::TPF::Green::GetPackageFullName())); + + ClearPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + } + }; + + class PackageDeploymentManagerTests_IsReadyOrNewerAvailable_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_IsReadyOrNewerAvailable_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + AddPackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(IsPackageSetReady_1_RegisteredPackageStatusBad_No) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + ClearPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Provision.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Provision.cpp new file mode 100644 index 0000000000..fd11abd058 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Provision.cpp @@ -0,0 +1,722 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Provision : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Provision) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { +#if !defined(TODO_Not_Latest_Platform_SDK) + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Provision* requires latest platform SDK. Skipping tests"); + return true; +#else + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Red(); + ::TB::Setup(); + return true; +#endif + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { +#if !defined(TODO_Not_Latest_Platform_SDK) + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Provision* requires latest platform SDK. Skipping tests"); + return true; +#else + RemovePackage_Red(); + ::TB::Cleanup(); + return true; +#endif + } + + TEST_METHOD(ProvisionPackageAsync_Registered_AccessDenied) + { + AddPackage_Red(); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_ACCESSDENIED, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + }; + + class PackageDeploymentManagerTests_Provision_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Provision_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + TEST_CLASS_PROPERTY(L"RunFixtureAs", L"ElevatedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { +#if !defined(TODO_Not_Latest_Platform_SDK) + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Provision* requires latest platform SDK. Skipping tests"); + return true; +#else + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + TD::DumpExecutionContext(); + + DeprovisionPackage_Blue(); + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; +#endif + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { +#if !defined(TODO_Not_Latest_Platform_SDK) + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Provision* requires latest platform SDK. Skipping tests"); + return true; +#else + TD::DumpExecutionContext(); + + DeprovisionPackage_Blue(); + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; +#endif + } + + TEST_METHOD(ProvisionPackageAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentResult{ packageDeploymentManager.ProvisionPackageAsync(packageFamilyName, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(ProvisionPackageAsync_Staged_Success) + { + DeprovisionPackage_Red(); + StagePackage_Red(); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(ProvisionPackageAsync_Registered_Success) + { + DeprovisionPackage_Red(); + AddPackage_Red(); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(ProvisionPackageAsync_StagedProvisioned_Success) + { + DeprovisionPackage_Red(); + StagePackage_Red(); + ProvisionPackage_Red(); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(ProvisionPackageAsync_RegisteredProvisioned_Success) + { + AddPackage_Red(); + ProvisionPackage_Red(); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(ProvisionPackageAsync_RegisteredPackageStatusBad_Success) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + DeprovisionPackage_Red(); + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + VERIFY_IS_FALSE(IsPackageProvisioned_Red()); + + const auto packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + VERIFY_IS_TRUE(IsPackageProvisioned_Red()); + } + + TEST_METHOD(ProvisionPackageByUriAsync_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ProvisionPackageByUriAsync_Staged_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ProvisionPackageByUriAsync_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ProvisionPackageByUriAsync_StagedProvisioned_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ProvisionPackageByUriAsync_RegisteredProvisioned_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ProvisionPackageByUriAsync_RegisteredPackageStatusBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ProvisionPackageSetAsync_1_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentResult{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(ProvisionPackageSetAsync_1_Staged_Success) + { + DeprovisionPackage_Red(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_1_Registered_Success) + { + DeprovisionPackage_Red(); + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_1_StagedProvisioned_Success) + { + DeprovisionPackage_Red(); + StagePackage_Red(); + ProvisionPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_1_RegisteredProvisioned_Success) + { + DeprovisionPackage_Red(); + AddPackage_Red(); + ProvisionPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_1_RegisteredPackageStatusBad_Success) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + DeprovisionPackage_Red(); + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_N_Staged_Success) + { + DeprovisionPackage_Red(); + DeprovisionPackage_Green(); + DeprovisionPackage_Blue(); + StagePackage_Red(); + StagePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_N_Registered_Success) + { + DeprovisionPackage_Red(); + DeprovisionPackage_Green(); + DeprovisionPackage_Blue(); + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_N_StagedProvisioned_Success) + { + DeprovisionPackage_Red(); + DeprovisionPackage_Green(); + DeprovisionPackage_Blue(); + StagePackage_Red(); + StagePackage_Green(); + StagePackage_Blue(); + ProvisionPackage_Red(); + ProvisionPackage_Green(); + ProvisionPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_N_RegisteredProvisioned_Success) + { + DeprovisionPackage_Red(); + DeprovisionPackage_Green(); + DeprovisionPackage_Blue(); + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + ProvisionPackage_Red(); + ProvisionPackage_Green(); + ProvisionPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_N_RegisteredAndNoSuchPackage_Fail) + { + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_N_RegisteredAndNoSuchPackageAndStaged_Fail) + { + DeprovisionPackage_Blue(); + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + AddPackage_Red(); + RemovePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(IsPackageRegistered_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(IsPackageRegistered_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + } + + TEST_METHOD(ProvisionPackageSetAsync_N_RegisteredPackageStatusOkAndBad_Success) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + DeprovisionPackage_Green(); + DeprovisionPackage_Red(); + AddPackage_Red(); + AddPackage_Green(); + SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Green()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetProvisioned(packageSet)); + + winrt::Microsoft::Windows::Management::Deployment::ProvisionPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.ProvisionPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Green()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + } + + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Register.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Register.cpp new file mode 100644 index 0000000000..ec2cb9a6c1 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Register.cpp @@ -0,0 +1,712 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +#if !defined(TODO_Register_error_0x80073D2B_ERROR_UNSIGNED_PACKAGE_INVALID_CONTENT_on_20h_vb) +#define RETURN_TRUE_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST() \ + if (!::WindowsVersion::IsWindows11_21H2OrGreater()) \ + { \ + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager.Register*() tests require >= 21H2 (SV1). Skipping tests"); \ + return true; \ + } +#define RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST() \ + if (!::WindowsVersion::IsWindows11_21H2OrGreater()) \ + { \ + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager.Register*() tests require >= 21H2 (SV1). Skipping tests"); \ + return; \ + } +#endif + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Register : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Register) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RETURN_TRUE_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + RemovePackage_White(); + RemovePackage_Blacker(); + RemovePackage_Black(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + RemovePackage_White(); + RemovePackage_Blacker(); + RemovePackage_Black(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(RegisterPackageAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR package{ L"c:\\does\\not\\exist\\appxmanifest.xml" }; + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(RegisterPackageAsync_Framework_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPF::Red::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RegisterPackageAsync_Main_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + StagePackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPM::Black::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + } + + TEST_METHOD(RegisterPackageAsync_Framework_Registered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPF::Red::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RegisterPackageAsync_Main_Registered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPM::Black::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + } + + TEST_METHOD(RegisterPackageAsync_Framework_OlderRegistered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + StagePackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPF::Redder::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Redder()); + + RemovePackage_Redder(); + } + + TEST_METHOD(RegisterPackageAsync_Main_OlderRegistered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Black(); + StagePackage_Blacker(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPM::Blacker::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Black()); + VERIFY_IS_TRUE(IsPackageRegistered_Blacker()); + + RemovePackage_Blacker(); + } + + TEST_METHOD(RegisterPackageByUriAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist/appxmanifest.xml" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(RegisterPackageByUriAsync_Framework_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPF::Red::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + winrt::Windows::Foundation::Uri packageUri{ package }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"packageUri: %ls", packageUri.ToString().c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RegisterPackageByUriAsync_Main_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + StagePackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPM::Black::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + winrt::Windows::Foundation::Uri packageUri{ package }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"packageUri: %ls", packageUri.ToString().c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + } + + TEST_METHOD(RegisterPackageByUriAsync_Framework_Registered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPF::Red::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + winrt::Windows::Foundation::Uri packageUri{ package }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"packageUri: %ls", packageUri.ToString().c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RegisterPackageByUriAsync_Main_Registered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPM::Black::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + winrt::Windows::Foundation::Uri packageUri{ package }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"packageUri: %ls", packageUri.ToString().c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Black()); + } + + TEST_METHOD(RegisterPackageByUriAsync_Framework_OlderRegistered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + StagePackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPF::Redder::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + winrt::Windows::Foundation::Uri packageUri{ package }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"packageUri: %ls", packageUri.ToString().c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Redder()); + + RemovePackage_Redder(); + } + + TEST_METHOD(RegisterPackageByUriAsync_Main_OlderRegistered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Black(); + StagePackage_Blacker(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto appxManifestPath{ TP::GetAppxManifestPackagePath(::TPM::Blacker::GetPackageFullName()) }; + const winrt::hstring package{ appxManifestPath.c_str() }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"package: %ls", package.c_str())); + winrt::Windows::Foundation::Uri packageUri{ package }; + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"packageUri: %ls", packageUri.ToString().c_str())); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Black()); + VERIFY_IS_TRUE(IsPackageRegistered_Blacker()); + + RemovePackage_Blacker(); + } + + TEST_METHOD(RegisterPackageSetAsync_Framework_1_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem_ForRegister(::TPF::Red::GetPackageFullName()) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RegisterPackageSetAsync_Main_1_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + StagePackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem_ForRegister(::TPM::Black::GetPackageFullName()) }; + packageSet.Items().Append(black); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RegisterPackageSetAsync_Framework_1_Registered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem_ForRegister(::TPF::Red::GetPackageFullName()) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RegisterPackageSetAsync_Main_1_Registered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Black(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"BW" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem_ForRegister(::TPM::Black::GetPackageFullName()) }; + packageSet.Items().Append(black); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RegisterPackageSetAsync_Framework_1_OlderRegistered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + StagePackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem_ForRegister(::TPF::Redder::GetPackageFullName()) }; + packageSet.Items().Append(redder); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Redder()); + + RemovePackage_Redder(); + } + + TEST_METHOD(RegisterPackageSetAsync_Main_1_OlderRegistered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Black(); + StagePackage_Blacker(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem_ForRegister(::TPM::Blacker::GetPackageFullName()) }; + packageSet.Items().Append(redder); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + VERIFY_IS_FALSE(IsPackageRegistered_Black()); + VERIFY_IS_TRUE(IsPackageRegistered_Blacker()); + + RemovePackage_Blacker(); + } + + TEST_METHOD(RegisterPackageSetAsync_Framework_N_Registered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem_ForRegister(::TPF::Red::GetPackageFullName()) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem_ForRegister(::TPF::Green::GetPackageFullName()) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem_ForRegister(::TPF::Blue::GetPackageFullName()) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RegisterPackageSetAsync_Main_N_Registered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Black(); + AddPackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"BW" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem_ForRegister(::TPM::Black::GetPackageFullName()) }; + packageSet.Items().Append(black); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem_ForRegister(::TPM::White::GetPackageFullName()) }; + packageSet.Items().Append(white); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RegisterPackageSetAsync_Framework_N_OlderRegistered_Success) + { + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + StagePackage_Redder(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem_ForRegister(::TPF::Redder::GetPackageFullName()) }; + packageSet.Items().Append(redder); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem_ForRegister(::TPF::Green::GetPackageFullName()) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem_ForRegister(::TPF::Blue::GetPackageFullName()) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(IsPackageRegistered_Redder()); + RemovePackage_Redder(); + } + + TEST_METHOD(RegisterPackageSetAsync_Main_N_OlderRegistered_Success) + { + AddPackage_Black(); + StagePackage_Blacker(); + AddPackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blacker{ Make_PackageSetItem_ForRegister(::TPM::Blacker::GetPackageFullName()) }; + packageSet.Items().Append(blacker); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem_ForRegister(::TPM::White::GetPackageFullName()) }; + packageSet.Items().Append(white); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + VERIFY_IS_FALSE(IsPackageRegistered_Black()); + VERIFY_IS_TRUE(IsPackageRegistered_Blacker()); + RemovePackage_Blacker(); + } + + TEST_METHOD(RegisterPackageSetAsync_Framework_N_RegisteredAndStaged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Red(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem_ForRegister(::TPF::Red::GetPackageFullName()) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem_ForRegister(::TPF::Blue::GetPackageFullName()) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RegisterPackageSetAsync_Main_N_RegisteredAndStaged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RETURN_IF_SKIP_ON_WIN10_DUE_TO_0x80073D2B_IN_TEST(); + + AddPackage_Black(); + StagePackage_White(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"BW" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem black{ Make_PackageSetItem_ForRegister(::TPM::Black::GetPackageFullName()) }; + packageSet.Items().Append(black); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem white{ Make_PackageSetItem_ForRegister(::TPM::White::GetPackageFullName()) }; + packageSet.Items().Append(white); + + winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions options; + auto deploymentOperation{ packageDeploymentManager.RegisterPackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Remove.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Remove.cpp new file mode 100644 index 0000000000..4db273f145 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Remove.cpp @@ -0,0 +1,1336 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Remove : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Remove) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(RemovePackageAsync_PackageFullName_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ L"Does.Not.Exist_0.0.0.0_neutral__1234567890abc" }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentResult{ packageDeploymentManager.RemovePackageAsync(packageFullName, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(RemovePackageAsync_PackageFullName_NotInstalled_Fail) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageAsync_PackageFullName_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageAsync_PackageFullName_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageAsync_PackageFullName_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageAsync_PackageFamilyName_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentResult{ packageDeploymentManager.RemovePackageAsync(packageFamilyName, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageAsync_PackageFamilyName_NoSuchPackage_Success) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentResult{ packageDeploymentManager.RemovePackageAsync(packageFamilyName, options).get() }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageAsync_PackageFamilyName_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageAsync_PackageFamilyName_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageAsync_PackageFamilyName_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageByFullNameAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ L"Does.Not.Exist_0.0.0.0_neutral__1234567890abc" }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentResult{ packageDeploymentManager.RemovePackageByFullNameAsync(packageFullName, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(RemovePackageByFullNameAsync_NotInstalled_Fail) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageByFullNameAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageByFullNameAsync_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageByFullNameAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageByFullNameAsync_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageByFullNameAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageByFullNameAsync_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageByFullNameAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageByFamilyNameAsync_NoSuchPackage_Success) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentResult{ packageDeploymentManager.RemovePackageByFamilyNameAsync(packageFamilyName, options).get() }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + } + + TEST_METHOD(RemovePackageByFamilyNameAsync_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageByFamilyNameAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageByFamilyNameAsync_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageByFamilyNameAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageByFamilyNameAsync_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageByFamilyNameAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageByUriAsync_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RemovePackageByUri() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageUriAsString{ L"ms-uup://Product/does.not.exist" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentResult{ packageDeploymentManager.RemovePackageByUriAsync(packageUri, options).get() }; +//TODO WTH +WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Status: %d", deploymentResult.Status())); +WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Error: 0x%08X", deploymentResult.Error())); +WEX::Logging::Log::Comment(WEX::Common::String().Format(L"ExtendedError: 0x%08X", deploymentResult.ExtendedError())); +WEX::Logging::Log::Comment(WEX::Common::String().Format(L"ErrorText: %s", deploymentResult.ErrorText().c_str())); + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(RemovePackageByUriAsync_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RemovePackageByUri() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RemovePackageByUriAsync_NotInstalled_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RemovePackageByUri() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RemovePackageByUriAsync_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_RemovePackageByUri() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RemovePackageByUriAsync_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RemovePackageByUri() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_1_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentResult{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#else + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_1_NotInstalled_Fail) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#else + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_1_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_1_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_1_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); +#endif + } + + TEST_METHOD(RemovePackageSetAsync_Uri_N_NotInstalled_Fail) + { + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#else + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_N_NotInstalled_Success) + { + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); +#endif + } + + TEST_METHOD(RemovePackageSetAsync_Uri_N_Registered_Success) + { + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); +#endif + } + + TEST_METHOD(RemovePackageSetAsync_Uri_N_RegisteredAndNotInstalled_Success) + { + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_N_RegisteredAndNotInstalledAndStaged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + AddPackage_Red(); + RemovePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_1_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentResult{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_1_NotInstalled_Fail) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_1_NotInstalled_Success) + { + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_1_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_1_Registered_Success) + { + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_N_NotInstalled_Fail) + { + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + green.PackageUri(nullptr); + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + blue.PackageUri(nullptr); + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_N_NotInstalled_Success) + { + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + green.PackageUri(nullptr); + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + blue.PackageUri(nullptr); + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_N_Registered_Success) + { + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + green.PackageUri(nullptr); + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + blue.PackageUri(nullptr); + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_N_RegisteredAndNotInstalled_Success) + { + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + green.PackageUri(nullptr); + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_N_RegisteredAndNotInstalledAndStaged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + AddPackage_Red(); + RemovePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + red.PackageUri(nullptr); + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + green.PackageUri(nullptr); + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + blue.PackageUri(nullptr); + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + VERIFY_IS_FALSE(options.FailIfNotFound()); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + }; + + class PackageDeploymentManagerTests_Remove_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Remove_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + AddPackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(RemovePackageAsync_PackageFullName_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(RemovePackageAsync_PackageFamilyName_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(RemovePackageByFullNameAsync_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFullName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(RemovePackageByFamilyNameAsync_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageAsync(packageFamilyName, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(RemovePackageByUriAsync_RegisteredPackageStatusBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RemovePackageByUri() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_1_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(RemovePackageSetAsync_Uri_N_RegisteredPackageStatusOkAndBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + AddPackage_Green(); + SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; +#if defined(TODO_use_Platform_SDK_defining_RemovePackageOptions) + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); +#else + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(E_NOTIMPL, deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(S_OK, deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_TRUE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); +#endif + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_1_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(RemovePackageSetAsync_NoUri_N_RegisteredPackageStatusOkAndBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + AddPackage_Green(); + SetPackageStatusByPackageFamilyName(::TPF::Green::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + winrt::Windows::Foundation::Uri packageUri{ nullptr }; + red.PackageUri(packageUri); + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + green.PackageUri(packageUri); + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::RemovePackageOptions options; + options.FailIfNotFound(true); + auto deploymentOperation{ packageDeploymentManager.RemovePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Repair.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Repair.cpp new file mode 100644 index 0000000000..d343106747 --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Repair.cpp @@ -0,0 +1,625 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Repair : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Repair) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(RepairPackageAsync_PackageFullName_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ L"Does.Not.Exist_0.0.0.0_neutral__1234567890abc" }; + + auto deploymentResult{ packageDeploymentManager.RepairPackageAsync(packageFullName).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(RepairPackageAsync_PackageFullName_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + auto deploymentOperation{ packageDeploymentManager.RepairPackageAsync(packageFullName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RepairPackageAsync_PackageFullName_Staged_Fail) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + auto deploymentOperation{ packageDeploymentManager.RepairPackageAsync(packageFullName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RepairPackageAsync_PackageFullName_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + auto deploymentOperation{ packageDeploymentManager.RepairPackageAsync(packageFullName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RepairPackageAsync_PackageFamilyName_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.RepairPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RepairPackageAsync_PackageFamilyName_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.RepairPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RepairPackageAsync_PackageFamilyName_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.RepairPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RepairPackageByUriAsync_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageUriAsString{ L"ms-uup://Product/does.not.exist" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + + auto deploymentResult{ packageDeploymentManager.RepairPackageByUriAsync(packageUri).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(RepairPackageByUriAsync_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RepairPackageByUriAsync_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_RepairPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RepairPackageByUriAsync_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RepairPackageSetAsync_1_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"ms-uup://Product/does.not.exist" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + auto deploymentResult{ packageDeploymentManager.RepairPackageSetAsync(packageSet).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(RepairPackageSetAsync_1_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + auto deploymentOperation{ packageDeploymentManager.RepairPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RepairPackageSetAsync_1_Staged_Fail) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + auto deploymentOperation{ packageDeploymentManager.RepairPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RepairPackageSetAsync_1_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + auto deploymentOperation{ packageDeploymentManager.RepairPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RepairPackageSetAsync_N_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + auto deploymentOperation{ packageDeploymentManager.RepairPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(RepairPackageSetAsync_N_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + auto deploymentOperation{ packageDeploymentManager.RepairPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RepairPackageSetAsync_N_RegisteredAndNotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + auto deploymentOperation{ packageDeploymentManager.RepairPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(RepairPackageSetAsync_N_RegisteredAndNotInstalledAndStaged_Fail) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + AddPackage_Red(); + RemovePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + auto deploymentOperation{ packageDeploymentManager.RepairPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + }; + + class PackageDeploymentManagerTests_Repair_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Repair_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + AddPackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(RepairPackageAsync_PackageFullName_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + auto deploymentOperation{ packageDeploymentManager.RepairPackageAsync(packageFullName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(RepairPackageAsync_PackageFamilyName_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_RepairPackage()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.RepairPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(RepairPackageByUriAsync_RegisteredPackageStatusBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RepairPackageSetAsync_1_RegisteredPackageStatusBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(RepairPackageSetAsync_N_RegisteredPackageStatusOkAndBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_RepairPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Reset.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Reset.cpp new file mode 100644 index 0000000000..0c2dcc7fec --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Reset.cpp @@ -0,0 +1,641 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Reset : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Reset) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(ResetPackageAsync_PackageFullName_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR packageFullName{ L"Does.Not.Exist_0.0.0.0_neutral__1234567890abc" }; + + auto deploymentResult{ packageDeploymentManager.ResetPackageAsync(packageFullName).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(ResetPackageAsync_PackageFullName_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + auto deploymentOperation{ packageDeploymentManager.ResetPackageAsync(packageFullName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(ResetPackageAsync_PackageFullName_Staged_Fail) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + auto deploymentOperation{ packageDeploymentManager.ResetPackageAsync(packageFullName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(ResetPackageAsync_PackageFullName_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + auto deploymentOperation{ packageDeploymentManager.ResetPackageAsync(packageFullName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + +#if defined(TODO_Reset_succeed_but_IsRegistered_is_false_on_rs_prerelease_x64fre) + VERIFY_IS_TRUE(IsPackageRegistered_Red()); +#else + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"TODO: Reset succeeds but package not registered on rs_prerelease_x64fre; see error 0x80070002 in Microsoft-Windows-AppxDeploymentServer/Operational"); +#endif + } + + TEST_METHOD(ResetPackageAsync_PackageFamilyName_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.ResetPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(ResetPackageAsync_PackageFamilyName_Staged_Fail) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.ResetPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(ResetPackageAsync_PackageFamilyName_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.ResetPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + +#if defined(TODO_Reset_succeed_but_IsRegistered_is_false_on_rs_prerelease_x64fre) + VERIFY_IS_TRUE(IsPackageRegistered_Red()); +#else + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"TODO: Reset succeeds but package not registered on rs_prerelease_x64fre; see error 0x80070002 in Microsoft-Windows-AppxDeploymentServer/Operational"); +#endif + } + + TEST_METHOD(ResetPackageByUriAsync_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageUriAsString{ L"ms-uup://Product/does.not.exist" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + + auto deploymentResult{ packageDeploymentManager.ResetPackageByUriAsync(packageUri).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(ResetPackageByUriAsync_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ResetPackageByUriAsync_Staged_Fail) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_ResetPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ResetPackageByUriAsync_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ResetPackageSetAsync_1_NoSuchPackage_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + auto deploymentResult{ packageDeploymentManager.ResetPackageSetAsync(packageSet).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + TEST_METHOD(ResetPackageSetAsync_1_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + RemovePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + auto deploymentOperation{ packageDeploymentManager.ResetPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(ResetPackageSetAsync_1_Staged_Fail) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + auto deploymentOperation{ packageDeploymentManager.ResetPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(ResetPackageSetAsync_1_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + auto deploymentOperation{ packageDeploymentManager.ResetPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(ResetPackageSetAsync_N_NotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + RemovePackage_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + auto deploymentOperation{ packageDeploymentManager.ResetPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + } + + TEST_METHOD(ResetPackageSetAsync_N_Registered_Success) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + auto deploymentOperation{ packageDeploymentManager.ResetPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(ResetPackageSetAsync_N_RegisteredAndNotInstalled_Fail) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + AddPackage_Red(); + RemovePackage_Green(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + auto deploymentOperation{ packageDeploymentManager.ResetPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(ResetPackageSetAsync_N_RegisteredAndNotInstalledAndStaged_Fail) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + AddPackage_Red(); + RemovePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + auto deploymentOperation{ packageDeploymentManager.ResetPackageSetAsync(packageSet) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_NOT_FOUND), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), deploymentResult.ExtendedError(), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + }; + + class PackageDeploymentManagerTests_Reset_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Reset_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + AddPackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(ResetPackageAsync_PackageFullName_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const winrt::hstring packageFullName{ ::TPF::Red::GetPackageFullName() }; + + auto deploymentOperation{ packageDeploymentManager.ResetPackageAsync(packageFullName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + +#if defined(TODO_Reset_succeed_but_IsRegistered_is_false_on_rs_prerelease_x64fre) + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); +#else + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"TODO: Reset succeeds but package not registered on rs_prerelease_x64fre; see error 0x80070002 in Microsoft-Windows-AppxDeploymentServer/Operational"); +#endif + } + + TEST_METHOD(ResetPackageAsync_PackageFamilyName_RegisteredPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + if (TPMT::SkipIfFeatureNotSupported_ResetPackage()) + { + return; + } + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + AddPackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::c_packageFamilyName, winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + const winrt::hstring packageFamilyName{ ::TPF::Red::c_packageFamilyName }; + + auto deploymentOperation{ packageDeploymentManager.ResetPackageAsync(packageFamilyName) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + +#if defined(TODO_Reset_succeed_but_IsRegistered_is_false_on_rs_prerelease_x64fre) + VERIFY_IS_TRUE(IsPackageRegistered_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); +#else + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"TODO: Reset succeeds but package not registered on rs_prerelease_x64fre; see error 0x80070002 in Microsoft-Windows-AppxDeploymentServer/Operational"); +#endif + } + + TEST_METHOD(ResetPackageByUriAsync_RegisteredPackageStatusBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ResetPackageSetAsync_1_RegisteredPackageStatusBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + + TEST_METHOD(ResetPackageSetAsync_N_RegisteredPackageStatusOkAndBad_Success) + { + if (TPMT::SkipIfFeatureNotSupported_ResetPackage() || TPMT::SkipIfFeatureNotSupported_PackageUriScheme_ms_uup()) + { + return; + } + + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"Cannot test ms-uup: URIs here. Skipping test"); + } + }; +} diff --git a/test/PackageManager/API/PackageDeploymentManagerTests_Stage.cpp b/test/PackageManager/API/PackageDeploymentManagerTests_Stage.cpp new file mode 100644 index 0000000000..5f302b58ad --- /dev/null +++ b/test/PackageManager/API/PackageDeploymentManagerTests_Stage.cpp @@ -0,0 +1,839 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +#include "PackageDeploymentManagerTests.h" + +#include + +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + +namespace Test::PackageManager::Tests +{ + class PackageDeploymentManagerTests_Stage : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Stage) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(StagePackageAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR package{ L"c:\\does\\not\\exist.msix" }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentResult{ packageDeploymentManager.StagePackageAsync(package, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + // + // NOTE: ExtendedError() should be HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) but on some platforms may be S_OK (and also ErrorText() may be empty) + VERIFY_IS_TRUE((deploymentResult.ExtendedError() == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) || (deploymentResult.ExtendedError() == S_OK), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + if (FAILED(deploymentResult.ExtendedError())) + { + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + } + + TEST_METHOD(StagePackageAsync_NotInstalled_Success) + { + RemovePackageFamily_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + VERIFY_IS_TRUE(IsPackageStaged_Red()); + } + + TEST_METHOD(StagePackageAsync_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RemovePackageFamily_Red(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + } + + TEST_METHOD(StagePackageAsync_Registered_Success) + { + RemovePackageFamily_Red(); + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + } + + TEST_METHOD(StagePackageAsync_OlderStaged_Success) + { + RemovePackageFamily_Red(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(IsPackageStaged_Redder()); + + RemovePackage_Redder(); + } + + TEST_METHOD(StagePackageAsync_NewerStaged_Success) + { + RemovePackageFamily_Redder(); + StagePackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Redder()); + + RemovePackageFamily_Redder(); + } + + TEST_METHOD(StagePackageByUriAsync_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentResult{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + // + // NOTE: ExtendedError() should be HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) but on some platforms may be S_OK (and also ErrorText() may be empty) + VERIFY_IS_TRUE((deploymentResult.ExtendedError() == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) || (deploymentResult.ExtendedError() == S_OK), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + if (FAILED(deploymentResult.ExtendedError())) + { + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + } + + TEST_METHOD(StagePackageByUriAsync_NotInstalled_Success) + { + RemovePackageFamily_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + } + + TEST_METHOD(StagePackageByUriAsync_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RemovePackageFamily_Red(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + } + + TEST_METHOD(StagePackageByUriAsync_Registered_Success) + { + RemovePackageFamily_Red(); + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + } + + TEST_METHOD(StagePackageByUriAsync_OlderStaged_Success) + { + RemovePackageFamily_Red(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(IsPackageStaged_Redder()); + + RemovePackageFamily_Redder(); + } + + TEST_METHOD(StagePackageByUriAsync_NewerStaged_Success) + { + RemovePackageFamily_Redder(); + StagePackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Redder()); + + RemovePackageFamily_Redder(); + } + + TEST_METHOD(StagePackageSetAsync_1_NoSuchPackage_Fail) + { + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + // + // NOTE: ExtendedError() should be HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) but on some platforms may be S_OK (and also ErrorText() may be empty) + VERIFY_IS_TRUE((deploymentResult.ExtendedError() == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) || (deploymentResult.ExtendedError() == S_OK), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + if (FAILED(deploymentResult.ExtendedError())) + { + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_1_NotInstalled_Success) + { + RemovePackageFamily_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_1_Staged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RemovePackageFamily_Red(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_1_Registered_Success) + { + RemovePackageFamily_Red(); + AddPackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_1_OlderStaged_Success) + { + RemovePackageFamily_Red(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Redder()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + + RemovePackageFamily_Red(); + } + + TEST_METHOD(StagePackageSetAsync_1_NewerStaged_Success) + { + RemovePackageFamily_Red(); + StagePackage_Redder(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_FALSE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Redder()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_NoSuchPackage_Fail) + { + RemovePackageFamily_Red(); + RemovePackage_Blue(); + StagePackage_Red(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"Does.Not.Exist" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem packageSetItem; + PCWSTR c_packageFamilyName{ L"Does.Not.Exist_1234567890abc" }; + packageSetItem.PackageFamilyName(c_packageFamilyName); + PCWSTR c_packageUriAsString{ L"file://c:/does/not/exist.msix" }; + winrt::Windows::Foundation::Uri packageUri{ c_packageUriAsString }; + packageSetItem.PackageUri(packageUri); + packageSet.Items().Append(packageSetItem); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentResult{ packageDeploymentManager.StagePackageSetAsync(packageSet, options).get() }; + VERIFY_ARE_EQUAL(winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentStatus::CompletedFailure, deploymentResult.Status()); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_INSTALL_FAILED), deploymentResult.Error(), WEX::Common::String().Format(L"0x%X", deploymentResult.Error())); + // + // NOTE: ExtendedError() should be HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) but on some platforms may be S_OK (and also ErrorText() may be empty) + VERIFY_IS_TRUE((deploymentResult.ExtendedError() == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) || (deploymentResult.ExtendedError() == S_OK), WEX::Common::String().Format(L"0x%X", deploymentResult.ExtendedError())); + if (FAILED(deploymentResult.ExtendedError())) + { + VERIFY_IS_FALSE(deploymentResult.ErrorText().empty(), WEX::Common::String().Format(L"%s", deploymentResult.ErrorText().c_str())); + } + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_NotInstalled_Success) + { + RemovePackageFamily_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Green()); + VERIFY_IS_TRUE(IsPackageStaged_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_Staged_Success) + { + RemovePackageFamily_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + StagePackage_Red(); + StagePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Green()); + VERIFY_IS_TRUE(IsPackageStaged_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_Registered_Success) + { + RemovePackageFamily_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + AddPackage_Red(); + AddPackage_Green(); + AddPackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Green()); + VERIFY_IS_TRUE(IsPackageStaged_Blue()); + VERIFY_IS_TRUE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_OlderStaged_Success) + { + RemovePackageFamily_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + StagePackage_Red(); + StagePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem redder{ Make_PackageSetItem(::TPF::Redder::GetPackageFullName(), ::TPF::Redder::c_packageDirName) }; + packageSet.Items().Append(redder); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Redder()); + VERIFY_IS_TRUE(IsPackageStaged_Green()); + VERIFY_IS_TRUE(IsPackageStaged_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_NewerStaged_Success) + { + RemovePackageFamily_Redder(); + RemovePackage_Green(); + RemovePackage_Blue(); + StagePackage_Redder(); + StagePackage_Green(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Redder()); + VERIFY_IS_TRUE(IsPackageStaged_Green()); + VERIFY_IS_TRUE(IsPackageStaged_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_StagedAndNotInstalled_Success) + { + RemovePackageFamily_Red(); + RemovePackage_Green(); + StagePackage_Red(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Green()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_StagedAndNotInstalledAndStaged_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + RemovePackageFamily_Red(); + RemovePackage_Green(); + RemovePackage_Blue(); + StagePackage_Red(); + StagePackage_Blue(); + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem blue{ Make_PackageSetItem(::TPF::Blue::GetPackageFullName(), ::TPF::Blue::c_packageDirName) }; + packageSet.Items().Append(blue); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Green()); + VERIFY_IS_TRUE(IsPackageStaged_Blue()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + }; + + class PackageDeploymentManagerTests_Stage_Elevated : PackageDeploymentManagerTests_Base + { + public: + BEGIN_TEST_CLASS(PackageDeploymentManagerTests_Stage_Elevated) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + if (!::WindowsVersion::IsWindows10_20H1OrGreater()) + { + WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped, L"PackageDeploymentManager requires >= 20H1 (Vibranium). Skipping tests"); + return true; + } + + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + AddPackage_Red(); + ::TB::Setup(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + TD::DumpExecutionContext(); + + RemovePackage_Blue(); + RemovePackage_Green(); + RemovePackage_Redder(); + RemovePackage_Red(); + ::TB::Cleanup(); + return true; + } + + TEST_METHOD(StagePackageAsync_StagedPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + RemovePackageFamily_Red(); + StagePackage_Red(); + SetPackageStatus(::TPF::Red::GetPackageFullName(), winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(IsPackageRegistered_Red()); + + const auto packagePath{ TP::GetMsixPackagePath(::TPF::Red::c_packageDirName) }; + const winrt::hstring package{ packagePath.c_str() }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageAsync(package, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(StagePackageByUriAsync_StagedPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + RemovePackageFamily_Red(); + StagePackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::GetPackageFullName(), winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + winrt::Windows::Foundation::Uri packageUri{ TP::GetMsixPackageUri(::TPF::Red::c_packageDirName) }; + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageByUriAsync(packageUri, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + } + + TEST_METHOD(StagePackageSetAsync_1_StagedPackageStatusBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + RemovePackageFamily_Red(); + StagePackage_Red(); + SetPackageStatusByPackageFamilyName(::TPF::Red::GetPackageFullName(), winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Red::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageSetReady(packageSet)); + } + + TEST_METHOD(StagePackageSetAsync_N_StagedPackageStatusOkAndBad_Success) + { + BEGIN_TEST_METHOD_PROPERTIES() + TEST_CLASS_PROPERTY(L"RunAs", L"ElevatedUser") + END_TEST_METHOD_PROPERTIES() + + auto packageDeploymentManager{ winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentManager::GetDefault() }; + + RemovePackageFamily_Red(); + RemovePackage_Green(); + StagePackage_Red(); + StagePackage_Green(); + SetPackageStatusByPackageFamilyName(::TPF::Green::GetPackageFullName(), winrt::Windows::Management::Deployment::PackageStatus::Modified); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + + winrt::Microsoft::Windows::Management::Deployment::PackageSet packageSet; + PCWSTR c_packageSetId{ L"RGB" }; + packageSet.Id(c_packageSetId); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem red{ Make_PackageSetItem(::TPF::Red::GetPackageFullName(), ::TPF::Red::c_packageDirName) }; + packageSet.Items().Append(red); + winrt::Microsoft::Windows::Management::Deployment::PackageSetItem green{ Make_PackageSetItem(::TPF::Green::GetPackageFullName(), ::TPF::Green::c_packageDirName) }; + packageSet.Items().Append(green); + + winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions options; + auto deploymentOperation{ packageDeploymentManager.StagePackageSetAsync(packageSet, options) }; + auto deploymentResult{ WaitForDeploymentOperation(deploymentOperation) }; + TPMT::VerifyDeploymentSucceeded(deploymentResult, __FILE__, __LINE__, __FUNCTION__); + + VERIFY_IS_TRUE(IsPackageStaged_Red()); + VERIFY_IS_TRUE(IsPackageStaged_Green()); + VERIFY_IS_FALSE(packageDeploymentManager.IsPackageReady(::TPF::Green::GetPackageFullName())); + } + }; +} diff --git a/test/PackageManager/API/PackageManagerTests.Packages.h b/test/PackageManager/API/PackageManagerTests.Packages.h index a30a62d7ec..300e7c6c12 100644 --- a/test/PackageManager/API/PackageManagerTests.Packages.h +++ b/test/PackageManager/API/PackageManagerTests.Packages.h @@ -4,7 +4,21 @@ #ifndef __PACKAGEMANAGERTESTS_PACKAGES_H #define __PACKAGEMANAGERTESTS_PACKAGES_H -namespace Test::Packages::Framework +namespace Test::Packages::Framework{} +namespace Test::Packages::Main{} +namespace Test::PackageManager::Tests{} +// +namespace TD = ::Test::Diagnostics; +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; +namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; +namespace TPMT = ::Test::PackageManager::Tests; + + +namespace Test::Packages +{ +namespace Framework { namespace Red { @@ -87,6 +101,94 @@ namespace Blue } } } +namespace Main +{ +namespace Black +{ + constexpr PCWSTR c_packageDirName = L"PackageManager.Test.M.Black.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.PackageManager.M.Black_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_x86 = L"Test.PackageManager.M.Black_1.2.3.4_x86__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_x64 = L"Test.PackageManager.M.Black_1.2.3.4_x64__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_arm64 = L"Test.PackageManager.M.Black_1.2.3.4_arm64__8wekyb3d8bbwe"; + constexpr inline PCWSTR GetPackageFullName() + { +#if defined(_M_ARM64) + return c_packageFullName_arm64; +#elif defined(_M_IX86) + return c_packageFullName_x86; +#elif defined(_M_X64) + return c_packageFullName_x64; +#else +# error "Unknown processor architecture" +#endif + } + constexpr PCWSTR c_appUserModelId = L"Test.PackageManager.M.Black_8wekyb3d8bbwe!App"; +} +namespace Blacker +{ + constexpr PCWSTR c_packageDirName = L"PackageManager.Test.M.Blacker.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.PackageManager.M.Black_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_x86 = L"Test.PackageManager.M.Black_2.4.6.8_x86__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_x64 = L"Test.PackageManager.M.Black_2.4.6.8_x64__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_arm64 = L"Test.PackageManager.M.Black_2.4.6.8_arm64__8wekyb3d8bbwe"; + constexpr inline PCWSTR GetPackageFullName() + { +#if defined(_M_ARM64) + return c_packageFullName_arm64; +#elif defined(_M_IX86) + return c_packageFullName_x86; +#elif defined(_M_X64) + return c_packageFullName_x64; +#else +# error "Unknown processor architecture" +#endif + } + constexpr PCWSTR c_appUserModelId = L"Test.PackageManager.M.Black_8wekyb3d8bbwe!App"; +} +namespace White +{ + constexpr PCWSTR c_packageDirName = L"PackageManager.Test.M.White.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.PackageManager.M.White_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_x86 = L"Test.PackageManager.M.White_1.2.3.4_x86__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_x64 = L"Test.PackageManager.M.White_1.2.3.4_x64__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_arm64 = L"Test.PackageManager.M.White_1.2.3.4_arm64__8wekyb3d8bbwe"; + constexpr inline PCWSTR GetPackageFullName() + { +#if defined(_M_ARM64) + return c_packageFullName_arm64; +#elif defined(_M_IX86) + return c_packageFullName_x86; +#elif defined(_M_X64) + return c_packageFullName_x64; +#else +# error "Unknown processor architecture" +#endif + } + constexpr PCWSTR c_appUserModelId = L"Test.PackageManager.M.White_8wekyb3d8bbwe!App"; +} +namespace Whiter +{ + constexpr PCWSTR c_packageDirName = L"PackageManager.Test.M.Whiter.msix"; + constexpr PCWSTR c_packageFamilyName = L"Test.PackageManager.M.White_8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_x86 = L"Test.PackageManager.M.White_2.4.6.8_x86__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_x64 = L"Test.PackageManager.M.White_2.4.6.8_x64__8wekyb3d8bbwe"; + constexpr PCWSTR c_packageFullName_arm64 = L"Test.PackageManager.M.White_2.4.6.8_arm64__8wekyb3d8bbwe"; + constexpr inline PCWSTR GetPackageFullName() + { +#if defined(_M_ARM64) + return c_packageFullName_arm64; +#elif defined(_M_IX86) + return c_packageFullName_x86; +#elif defined(_M_X64) + return c_packageFullName_x64; +#else +# error "Unknown processor architecture" +#endif + } + constexpr PCWSTR c_appUserModelId = L"Test.PackageManager.M.White_8wekyb3d8bbwe!App"; +} +} +} namespace Test::PackageManager::Tests { @@ -96,21 +198,36 @@ namespace Test::PackageManager::Tests // Forward declarations void RemovePackageFamily_Redder(); - inline winrt::Microsoft::Windows::Management::Deployment::PackageSetItem Make_PackageSetItem( + inline winrt::Microsoft::Windows::Management::Deployment::PackageSetItem _Make_PackageSetItem( PCWSTR packageFullName, - PCWSTR packageDirName) + winrt::Windows::Foundation::Uri const& packageUri) { - WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageSetItem: PackageFullName:%s Path:%s", packageFullName, packageDirName)); + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"PackageSetItem: PackageFullName:%s Path:%s", packageFullName, packageUri.ToString().c_str())); const auto [packageName, packageVersion, packageArchitecture, packageResourceId, packagePublisherId, packageFamilyName]{ ::AppModel::Package::ParsePackageFullName(packageFullName) }; winrt::Microsoft::Windows::Management::Deployment::PackageSetItem psi; psi.PackageFamilyName(packageFamilyName); - psi.PackageUri(TP::GetMsixPackageUri(packageDirName)); + psi.PackageUri(packageUri); const ::AppModel::Identity::PackageVersion version{ packageVersion }; psi.MinVersion(version.ToWinrtPackageVersion()); return psi; } + inline winrt::Microsoft::Windows::Management::Deployment::PackageSetItem Make_PackageSetItem( + PCWSTR packageFullName, + PCWSTR packageDirName) + { + const auto packageUri{ TP::GetMsixPackageUri(packageDirName) }; + return _Make_PackageSetItem(packageFullName, packageUri); + } + + inline winrt::Microsoft::Windows::Management::Deployment::PackageSetItem Make_PackageSetItem_ForRegister( + PCWSTR packageFullName) + { + const auto appxManifestUri{ TP::GetAppxManifestPackageUri(packageFullName) }; + return _Make_PackageSetItem(packageFullName, appxManifestUri); + } + inline bool IsPackageRegistered_Red() { return TP::IsPackageRegistered(TPF::Red::GetPackageFullName()); @@ -121,11 +238,15 @@ namespace Test::PackageManager::Tests } inline void AddPackage_Red() { - TP::AddPackageIfNecessary(Test::Packages::Framework::Red::c_packageDirName, TPF::Red::GetPackageFullName()); + TP::AddPackageIfNecessary(TPF::Red::c_packageDirName, TPF::Red::GetPackageFullName()); } inline void StagePackage_Red() { - TP::StagePackageIfNecessary(Test::Packages::Framework::Red::c_packageDirName, TPF::Red::GetPackageFullName()); + TP::StagePackageIfNecessary(TPF::Red::c_packageDirName, TPF::Red::GetPackageFullName()); + } + inline void RegisterPackage_Red() + { + TP::RegisterPackageIfNecessary(TPF::Red::GetPackageFullName()); } inline void RemovePackage_Red() { @@ -145,16 +266,18 @@ namespace Test::PackageManager::Tests { // Same as RemovePackageFamily_Redder RemovePackageFamily_Redder(); -#if 0 - // The package could be staged and not registered so checking - // checking for registered packages in the family is insufficient, - // and checking for staged packages not registered for the current user - // requires admin privilege (which we may not have). So we'll rely on - // remove for each package in the family handling it whether the packages - // are staged or registered. - TP::RemovePackageIfNecessary(TPF::Red::GetPackageFullName()); - TP::RemovePackageIfNecessary(TPF::Redder::GetPackageFullName()); -#endif + } + inline bool IsPackageProvisioned_Red() + { + return TP::IsPackageProvisioned(TPF::Red::c_packageFamilyName); + } + inline void ProvisionPackage_Red() + { + TP::ProvisionPackage(TPF::Red::c_packageFamilyName); + } + inline void DeprovisionPackage_Red() + { + TP::DeprovisionPackageIfNecessary(TPF::Red::c_packageFamilyName); } inline bool IsPackageRegistered_Redder() @@ -167,11 +290,15 @@ namespace Test::PackageManager::Tests } inline void AddPackage_Redder() { - TP::AddPackageIfNecessary(Test::Packages::Framework::Redder::c_packageDirName, TPF::Redder::GetPackageFullName()); + TP::AddPackageIfNecessary(TPF::Redder::c_packageDirName, TPF::Redder::GetPackageFullName()); } inline void StagePackage_Redder() { - TP::StagePackageIfNecessary(Test::Packages::Framework::Redder::c_packageDirName, TPF::Redder::GetPackageFullName()); + TP::StagePackageIfNecessary(TPF::Redder::c_packageDirName, TPF::Redder::GetPackageFullName()); + } + inline void RegisterPackage_Redder() + { + TP::RegisterPackageIfNecessary(TPF::Redder::GetPackageFullName()); } inline void RemovePackage_Redder() { @@ -191,16 +318,18 @@ namespace Test::PackageManager::Tests { RemovePackage_Redder(); RemovePackage_Red(); -#if 0 - // The package could be staged and not registered so checking - // checking for registered packages in the family is insufficient, - // and checking for staged packages not registered for the current user - // requires admin privilege (which we may not have). So we'll rely on - // remove for each package in the family handling it whether the packages - // are staged or registered. - TP::RemovePackageIfNecessary(TPF::Red::GetPackageFullName()); - TP::RemovePackageIfNecessary(TPF::Redder::GetPackageFullName()); -#endif + } + inline bool IsPackageProvisioned_Redder() + { + return TP::IsPackageProvisioned(TPF::Redder::c_packageFamilyName); + } + inline void ProvisionPackage_Redder() + { + TP::ProvisionPackage(TPF::Redder::c_packageFamilyName); + } + inline void DeprovisionPackage_Redder() + { + TP::DeprovisionPackageIfNecessary(TPF::Redder::c_packageFamilyName); } inline bool IsPackageRegistered_Green() @@ -213,11 +342,15 @@ namespace Test::PackageManager::Tests } inline void AddPackage_Green() { - TP::AddPackageIfNecessary(Test::Packages::Framework::Green::c_packageDirName, TPF::Green::GetPackageFullName()); + TP::AddPackageIfNecessary(TPF::Green::c_packageDirName, TPF::Green::GetPackageFullName()); } inline void StagePackage_Green() { - TP::StagePackageIfNecessary(Test::Packages::Framework::Green::c_packageDirName, TPF::Green::GetPackageFullName()); + TP::StagePackageIfNecessary(TPF::Green::c_packageDirName, TPF::Green::GetPackageFullName()); + } + inline void RegisterPackage_Green() + { + TP::RegisterPackageIfNecessary(TPF::Green::GetPackageFullName()); } inline void RemovePackage_Green() { @@ -236,15 +369,18 @@ namespace Test::PackageManager::Tests inline void RemovePackageFamily_Green() { RemovePackage_Green(); -#if 0 - // The package could be staged and not registered so checking - // checking for registered packages in the family is insufficient, - // and checking for staged packages not registered for the current user - // requires admin privilege (which we may not have). So we'll rely on - // remove for each package in the family handling it whether the packages - // are staged or registered. - TP::RemovePackageIfNecessary(TPF::Green::GetPackageFullName()); -#endif + } + inline bool IsPackageProvisioned_Green() + { + return TP::IsPackageProvisioned(TPF::Green::c_packageFamilyName); + } + inline void ProvisionPackage_Green() + { + TP::ProvisionPackage(TPF::Green::c_packageFamilyName); + } + inline void DeprovisionPackage_Green() + { + TP::DeprovisionPackageIfNecessary(TPF::Green::c_packageFamilyName); } inline bool IsPackageRegistered_Blue() @@ -257,11 +393,15 @@ namespace Test::PackageManager::Tests } inline void AddPackage_Blue() { - TP::AddPackageIfNecessary(Test::Packages::Framework::Blue::c_packageDirName, TPF::Blue::GetPackageFullName()); + TP::AddPackageIfNecessary(TPF::Blue::c_packageDirName, TPF::Blue::GetPackageFullName()); } inline void StagePackage_Blue() { - TP::StagePackageIfNecessary(Test::Packages::Framework::Blue::c_packageDirName, TPF::Blue::GetPackageFullName()); + TP::StagePackageIfNecessary(TPF::Blue::c_packageDirName, TPF::Blue::GetPackageFullName()); + } + inline void RegisterPackage_Blue() + { + TP::RegisterPackageIfNecessary(TPF::Blue::GetPackageFullName()); } inline void RemovePackage_Blue() { @@ -280,15 +420,238 @@ namespace Test::PackageManager::Tests inline void RemovePackageFamily_Blue() { RemovePackage_Blue(); -#if 0 - // The package could be staged and not registered so checking - // checking for registered packages in the family is insufficient, - // and checking for staged packages not registered for the current user - // requires admin privilege (which we may not have). So we'll rely on - // remove for each package in the family handling it whether the packages - // are staged or registered. - TP::RemovePackageIfNecessary(TPF::Green::GetPackageFullName()); -#endif + } + inline bool IsPackageProvisioned_Blue() + { + return TP::IsPackageProvisioned(TPF::Blue::c_packageFamilyName); + } + inline void ProvisionPackage_Blue() + { + TP::ProvisionPackage(TPF::Blue::c_packageFamilyName); + } + inline void DeprovisionPackage_Blue() + { + TP::DeprovisionPackageIfNecessary(TPF::Blue::c_packageFamilyName); + } + + inline bool IsPackageRegistered_Black() + { + return TP::IsPackageRegistered(TPM::Black::GetPackageFullName()); + } + inline bool IsPackageStaged_Black() + { + return TP::IsPackageStaged(TPM::Black::GetPackageFullName()); + } + inline void AddPackage_Black() + { + TP::AddPackageIfNecessary(TPM::Black::c_packageDirName, TPM::Black::GetPackageFullName()); + } + inline void AddPackageDefer_Black() + { + TP::AddPackageDeferIfNecessary(TPM::Black::c_packageDirName, TPM::Black::GetPackageFullName()); + } + inline void StagePackage_Black() + { + TP::StagePackageIfNecessary(TPM::Black::c_packageDirName, TPM::Black::GetPackageFullName()); + } + inline void RegisterPackage_Black() + { + TP::RegisterPackageIfNecessary(TPM::Black::GetPackageFullName()); + } + inline void RemovePackage_Black() + { + if (IsPackageRegistered_Black()) + { + TP::RemovePackage(TPM::Black::GetPackageFullName()); + } + else if (IsPackageStaged_Black()) + { + // 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_Black(); + TP::RemovePackage(TPM::Black::GetPackageFullName()); + } + } + inline void RemovePackageFamily_Black() + { + RemovePackage_Black(); + } + inline bool IsPackageProvisioned_Black() + { + return TP::IsPackageProvisioned(TPM::Black::c_packageFamilyName); + } + inline void ProvisionPackage_Black() + { + TP::ProvisionPackage(TPM::Black::c_packageFamilyName); + } + inline void DeprovisionPackage_Black() + { + TP::DeprovisionPackageIfNecessary(TPM::Black::c_packageFamilyName); + } + + inline bool IsPackageRegistered_Blacker() + { + return TP::IsPackageRegistered(TPM::Blacker::GetPackageFullName()); + } + inline bool IsPackageStaged_Blacker() + { + return TP::IsPackageStaged(TPM::Blacker::GetPackageFullName()); + } + inline void AddPackage_Blacker() + { + TP::AddPackageIfNecessary(TPM::Blacker::c_packageDirName, TPM::Blacker::GetPackageFullName()); + } + inline void AddPackageDefer_Blacker() + { + TP::AddPackageDeferIfNecessary(TPM::Blacker::c_packageDirName, TPM::Blacker::GetPackageFullName()); + } + inline void StagePackage_Blacker() + { + TP::StagePackageIfNecessary(TPM::Blacker::c_packageDirName, TPM::Blacker::GetPackageFullName()); + } + inline void RegisterPackage_Blacker() + { + TP::RegisterPackageIfNecessary(TPM::Blacker::GetPackageFullName()); + } + inline void RemovePackage_Blacker() + { + if (IsPackageRegistered_Blacker()) + { + TP::RemovePackage(TPM::Blacker::GetPackageFullName()); + } + else if (IsPackageStaged_Blacker()) + { + // 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_Blacker(); + TP::RemovePackage(TPM::Blacker::GetPackageFullName()); + } + } + inline void RemovePackageFamily_Blacker() + { + RemovePackage_Blacker(); + } + inline bool IsPackageProvisioned_Blacker() + { + return TP::IsPackageProvisioned(TPM::Blacker::c_packageFamilyName); + } + inline void ProvisionPackage_Blacker() + { + TP::ProvisionPackage(TPM::Blacker::c_packageFamilyName); + } + inline void DeprovisionPackage_Blacker() + { + TP::DeprovisionPackageIfNecessary(TPM::Blacker::c_packageFamilyName); + } + + inline bool IsPackageRegistered_White() + { + return TP::IsPackageRegistered(TPM::White::GetPackageFullName()); + } + inline bool IsPackageStaged_White() + { + return TP::IsPackageStaged(TPM::White::GetPackageFullName()); + } + inline void AddPackage_White() + { + TP::AddPackageIfNecessary(TPM::White::c_packageDirName, TPM::White::GetPackageFullName()); + } + inline void AddPackageDefer_White() + { + TP::AddPackageDeferIfNecessary(TPM::White::c_packageDirName, TPM::White::GetPackageFullName()); + } + inline void StagePackage_White() + { + TP::StagePackageIfNecessary(TPM::White::c_packageDirName, TPM::White::GetPackageFullName()); + } + inline void RegisterPackage_White() + { + TP::RegisterPackageIfNecessary(TPM::White::GetPackageFullName()); + } + inline void RemovePackage_White() + { + if (IsPackageRegistered_White()) + { + TP::RemovePackage(TPM::White::GetPackageFullName()); + } + else if (IsPackageStaged_White()) + { + // 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_White(); + TP::RemovePackage(TPM::White::GetPackageFullName()); + } + } + inline void RemovePackageFamily_White() + { + RemovePackage_White(); + } + inline bool IsPackageProvisioned_White() + { + return TP::IsPackageProvisioned(TPM::White::c_packageFamilyName); + } + inline void ProvisionPackage_White() + { + TP::ProvisionPackage(TPM::White::c_packageFamilyName); + } + inline void DeprovisionPackage_White() + { + TP::DeprovisionPackageIfNecessary(TPM::White::c_packageFamilyName); + } + + inline bool IsPackageRegistered_Whiter() + { + return TP::IsPackageRegistered(TPM::Whiter::GetPackageFullName()); + } + inline bool IsPackageStaged_Whiter() + { + return TP::IsPackageStaged(TPM::Whiter::GetPackageFullName()); + } + inline void AddPackage_Whiter() + { + TP::AddPackageIfNecessary(TPM::Whiter::c_packageDirName, TPM::Whiter::GetPackageFullName()); + } + inline void AddPackageDefer_Whiter() + { + TP::AddPackageDeferIfNecessary(TPM::Whiter::c_packageDirName, TPM::Whiter::GetPackageFullName()); + } + inline void StagePackage_Whiter() + { + TP::StagePackageIfNecessary(TPM::Whiter::c_packageDirName, TPM::Whiter::GetPackageFullName()); + } + inline void RegisterPackage_Whiter() + { + TP::RegisterPackageIfNecessary(TPM::Whiter::GetPackageFullName()); + } + inline void RemovePackage_Whiter() + { + if (IsPackageRegistered_Whiter()) + { + TP::RemovePackage(TPM::Whiter::GetPackageFullName()); + } + else if (IsPackageStaged_Whiter()) + { + // 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_Whiter(); + TP::RemovePackage(TPM::Whiter::GetPackageFullName()); + } + } + inline void RemovePackageFamily_Whiter() + { + RemovePackage_Whiter(); + } + inline bool IsPackageProvisioned_Whiter() + { + return TP::IsPackageProvisioned(TPM::Whiter::c_packageFamilyName); + } + inline void ProvisionPackage_Whiter() + { + TP::ProvisionPackage(TPM::Whiter::c_packageFamilyName); + } + inline void DeprovisionPackage_Whiter() + { + TP::DeprovisionPackageIfNecessary(TPM::Whiter::c_packageFamilyName); } inline winrt::Windows::ApplicationModel::PackageStatus GetPackageStatus(winrt::Windows::Management::Deployment::PackageManager packageManager, PCWSTR packageFullName) diff --git a/test/PackageManager/API/PackageManagerTests.vcxproj b/test/PackageManager/API/PackageManagerTests.vcxproj index a874267c5e..c60298ae3c 100644 --- a/test/PackageManager/API/PackageManagerTests.vcxproj +++ b/test/PackageManager/API/PackageManagerTests.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.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -110,10 +111,24 @@ Create + + + + + + + + + + + + + + @@ -153,6 +168,7 @@ + @@ -168,5 +184,6 @@ + diff --git a/test/PackageManager/API/PackageManagerTests.vcxproj.filters b/test/PackageManager/API/PackageManagerTests.vcxproj.filters index 50298e2af0..2f54e9455b 100644 --- a/test/PackageManager/API/PackageManagerTests.vcxproj.filters +++ b/test/PackageManager/API/PackageManagerTests.vcxproj.filters @@ -21,6 +21,45 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + Source Files @@ -29,6 +68,9 @@ Header Files + + Header Files + Header Files @@ -36,4 +78,7 @@ + + + diff --git a/test/PackageManager/API/PackageRuntimeManagerTests.cpp b/test/PackageManager/API/PackageRuntimeManagerTests.cpp index 6a055a1896..8e7e4f0179 100644 --- a/test/PackageManager/API/PackageRuntimeManagerTests.cpp +++ b/test/PackageManager/API/PackageRuntimeManagerTests.cpp @@ -5,9 +5,11 @@ #include +namespace TD = ::Test::Diagnostics; namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; namespace TPF = ::Test::Packages::Framework; +namespace TPM = ::Test::Packages::Main; namespace TPMT = ::Test::PackageManager::Tests; namespace Test::PackageManager::Tests diff --git a/test/PackageManager/API/packages.config b/test/PackageManager/API/packages.config index ecebfdd18e..3a42804723 100644 --- a/test/PackageManager/API/packages.config +++ b/test/PackageManager/API/packages.config @@ -3,7 +3,8 @@ - + + diff --git a/test/PackageManager/API/pch.h b/test/PackageManager/API/pch.h index 9ae9d75ea8..900c25a3d3 100644 --- a/test/PackageManager/API/pch.h +++ b/test/PackageManager/API/pch.h @@ -6,6 +6,9 @@ #include +#include + +#include #include #include @@ -28,4 +31,24 @@ #include "PackageManagerTests.Packages.h" +#include +#include +#include +#if defined(NTDDI_WIN11_GE) +# define TODO_UpdatedWindowsSDK_with_Windows_Management_Deployment_IRemovePackageOptions +#endif +#if !defined(TODO_UpdatedWindowsSDK_with_Windows_Management_Deployment_IRemovePackageOptions) +// Until we have access to the updated Windows SDK we can't use RemovePackageOptions +// but we need *something* to satisfy PackageManagement_RemovePackageByUriAsync() in the FrameworkUDK +// so we'll make a placeholder definition to satisfy the compiler enough to let us call +// PackageManagement_RemovePackageByUriAsync2(uri, nullptr). Remove this once the updated +// Windows SDK makes this unnecessary. +namespace ABI::Windows::Management::Deployment +{ + typedef void * IRemovePackageOptions; +} +#endif +// +#include + #endif //PCH_H diff --git a/test/PackageManager/data/PackageManager.Test.F.Red.msix/pch.cpp b/test/PackageManager/data/PackageManager.Test.F.Red.msix/pch.cpp new file mode 100644 index 0000000000..a77728ba07 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.F.Red.msix/pch.cpp @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/test/PackageManager/data/PackageManager.Test.F.Red.msix/pch.h b/test/PackageManager/data/PackageManager.Test.F.Red.msix/pch.h new file mode 100644 index 0000000000..c32e747e30 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.F.Red.msix/pch.h @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#include + +#include +#include +#include + +#include +#include +#include + +#endif //PCH_H diff --git a/test/PackageManager/data/PackageManager.Test.F.Red.msix/winmain.cpp b/test/PackageManager/data/PackageManager.Test.F.Red.msix/winmain.cpp new file mode 100644 index 0000000000..43db217176 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.F.Red.msix/winmain.cpp @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) +{ + // Usage: This.Exe + // where + // eventname = event name signaling we should quit. + + // Parse the command line + const auto eventName{ GetCommandLineW() }; + if (eventName) + { + wil::unique_event_nothrow endOfTheLine{ ::OpenEventW(SYNCHRONIZE, FALSE, eventName) }; + RETURN_LAST_ERROR_IF_NULL(endOfTheLine); + + auto rc{ WaitForSingleObject(endOfTheLine.get(), INFINITE) }; + if (rc != WAIT_OBJECT_0) + { + if (rc == WAIT_FAILED) + { + LOG_LAST_ERROR(); + } + else + { + LOG_HR_MSG(E_UNEXPECTED, "%u", rc); + } + return rc; + } + } + return 0; +} diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/SplashScreen.png b/test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/SplashScreen.png new file mode 100644 index 0000000000000000000000000000000000000000..18482131803409efae8c534cb796c1760d49091a GIT binary patch literal 78102 zcmc$_Wl$UH^9CBExH}YzyK8aR;!cCRySuwXad!w-C{BSEEyXGB9^74Tdj98k?)UrU zW+r5kA@lC;yZh|3l4unr8B`=9Bme+_Dkm$c1^~c*1puIR5TGHSyo5z5LSCR;)nvp0 zb>qYbkTI(9nLn?*V^W>IR-I4R(1dC@XLm zVf%0%e0e@#7J{0F@&1E+Ae4059eizoPUPLoUu-(#S!#$n5e!2oKe2QZ-eJxtp zdukBWTNU6;@jkrc)3&r2&AhnOl(9b~Iy^gr!NgR>g~G(dJh>n5*^yGL{rt0S7+Iz` zcxtV4`=EBfuls`3mZnq4($&tV>2gv9t+I4mqN0Yen;0I@iqDhkXaS6?lZ1cuNrk zGLY<6LFgm3E3@9BBY zr=S7&UH*#eHN@y(s>O#xQYt=+XI?pf2S2QB82Qk|Gol-O*5?sf-}WNv^@Yi4pQ+An zcnXT*6J`u7h#VKRq~A<5UmN87tH~L*vy_5$UKmlr5)(;T(P@T;N{q13NCO29L`we5 zxA_J5&F`)nztTub4Si7xyrpom1I(hL3(Sw7;f2YHdvSKAL#ajb zgW-7dw@&oh8DqN~_Nf)G2ab0?FfcLsURfbl_OZ}=?dCLi`c^`^XuA!wm@?syhVg^k z8~$Bk4EykR=IB}EcSzB}1X#9>MjDa>A!YYQ(K>|`CAC>okGu@&F#}ew{Rk6O6ci@m zNl{TzbzbX)Pd&zmgH@ptK|0(j?1QAttHT79iQyDt`|>n>g>)X6R9PAqo|;}JGOA`H z&ho5{iwY8XwmB_F`gbdTudSj}To&T3+TCYyBY^=kgF-xR6k5xGLpc>HSU*^eg>IEV z1)bzc;J6hv>XO-I%t`rqh1j#-S=`E`RTWNJNoA9n2Mk1%{5hn5{O1mok$XN)cvNwX zUe!Af8~Tz9NY83)m32FWOnCRl6l9 z>5R;AC`06e6Q`h{;NRRaHF#Lle@eeW{UKfu&W-FGv_O~DRI-pF5`%=ZIa067f%9ul zcSL84iKp$k!-WT8bUlgXFFk9Q$`G4Fp+Pjeo@qaHWi@n}+NVSfEsjBYM+Ob={;KbC zUDF&FGnW0ymJq)woe;Yzy-MW={4ZWQDT*w@{7k}hwP|2^lhY>@h#Xpf{W4$NGOzXU z+H*p$;4HDXj)g}JK`{9%+m0fa9{IP-m%*;7rjzr zISAiaGJLi6@vth@VM;HqRvw{vfj_9DqOVH$JTf#9}UFG)feU8P^FFfrhMVqg$!Vnw%6ZJ1| zt~a!Xs-D00f?eXs-aQ)Eq>1WOH^=o#4~vG*aWG)y+RI%Dd3b9(De!89h^H(47l+O%4V=c%6OZ!V=uFanM<|y#ZGkm05P&05 zdDaZI=CCnAscyD}ULgcnFb#06Uum%ip$Sd3>Dbt)KN4pYR}$mOk61#mRQ8+-62?=D z;Jog8DSiC`0_f&CHXaqx-&*O&+S_Kt$Qnfy&TQVJGp4r%0bc6*w(50=A<0%=_UjU7 z?RP|h;)GbXE{%`)09+{=zK$Kb*UCc^cYw)_WAb;Z2zA`q1N1nh#Y|g!`(NOkKxfMb zf%P|fhz`MjgR5m~c0QNA$;_T_?)+mw18T1vZsmjvMfyt$^+=fc25M)Q|HBtt3c_Fj zMlf`s|8==uxx+x5gtUCPNX^Tx4C!+UD-5U@2Ua}t6WZtk8Dc z?ek!M5r_!r9R`jRu=;pytXnem%tV{%I~Wf&Zd-itU*FT^k$&+|rh|osm))hl6*@Ms zA%!@2G$)6#dR5&{4?g_ zK97jtvl|a^BbK0JKoghWxTE2mF460+-xKrZhXd(E-^OIdgilXV0~auE;N5>6&T*s* z<03lWHv1`JMyJ^5W>~mpMexrru!CC!-rhkVOPvrBOG}@K1TW%sGU)GD-f4!_cq?4` zY|U}F=2#ST>_A`0O*@nUg~6??a89FN`f?hXTXx8|8%gyZvbwS@@8>w`q-_ZUgMkK` zVoWNrF|U&%j34z_(u!Sh(mZlfrI;lp``7w$Wo;g#*VyR@x^TN@BG1=50i%K}h3 z*h{|Fyw3ZlCl5;9OJ9k|!|L98|L{(jU2N*{V5M^K5!#c7M9Xjny!udna-C+65a%p# zu!>*wm~P>dZI+pw`=AK2dgl@FD!%q%@9f!oAKddD5ppPV2?S`qxZL;}K7Gfo5aMVe z%17Yhs}$W>{N-W$*!q(r#JdovgYZ;#T z-BtpG_pXXUFNuO|*9buir}iR*D7Oh(LJul99#|UeOLPz1WqSHN8Lkfr(LGNitB`!+ zKu8V2@W~s}z^8ZhZFXk|704>CiB>*qtkF>vX0&J1g2gAOBfIakg6qUMp{4=3@XU=19J)uQY9u; zI!t3Wj3NIz4Bd4}Ypz$2hmF2`cfet3#Nv6hk|rz&;b*V0EN%dY9>3?oE}M;~HE5)d zj%>0Mo|N}!p7rr+$#8(EV%%|*JBAEHc+4cXIit$X5_bU?T2mGCosVZS9YaPj$L|tw z!3#wk`M)Uu*yc2~Zs_@|?nq0f^$jXK0N{Jr+)v-QjkoW>?f4rvV(Xngm*0 zeSh3E(fEt5O=Wcj;H&F;>CV9KGS8F5tZy=l>)NUt1pUNqrzn|9I=cJ#I{Vht|xN&?O! z$};o=j&|2O->QR_>ZWKeaK&N$&~T!I7kZklpP-Dz8JhcVkPl^~OQshJ==jZg-g!Ad zLX-@WT8i;We0SDa`R*rw&VmpIj!375PNBYkY3=lWho(mG}fPQDkG7H4`+b9mqj`fTsJ<4OWbo8t)i!Yr6$fP0=g z98SbSZJQ^N7`^ct;bFvdGfEC^mG*~`0(lnE#Tm6RF7NBtnjXiA?dY>oq9^iTzi zD^ph#c}6fw@0w_cS9$G?C=Iy6|4ZreTn`&Oa|0)>2WCMS2x@XHe3Gp%A1DB~xh~=z ziIo~LVMT?_3T?%dss#++(XvJkrpys1+U-bNV+_-=TICVn=?2nnO0 zNO;N4+~kHvri zgOvG+ovo!6Lp}mp5w7nf3zI%0MZW~O;>$k{^H(iP9KFTYt={ZG6U^=2-olv`ZktbU z_v}IMu|Z8YoJWh4?|M0bZWDO% zE4$nTbMBUNj7G{lwo^K`_3cBnH});IMrCW#%B6gKM7LQnPsxR-(!ACwlJ^gpbCUWP++h_scS69}WqdaZm zO2(lBVmi&?i9wS-r%%Vw@konZ380A!!RuNI z0v+`8G}}z@k78b7*Z7^|k7M%u^8UjD@A`$Q31Kg0!9s+l8MOV>5*d2vs9Rsn=Tan= z2isUO#w<8b)bXER=6wGXC&^V==u{D&)qBKEi1#pGjkuAw<%XzmOnX=|=O`JKXydtNYC0?$d>UFhlPGaar6p>1wl3#Kc2@&o-(D8RuGTjAZOB?)Sz(%ViC06D!y>`5vnDG%V)q`y zzkj-}L~uB&Sf=ICcZLbddAl0+?F@t$vrC>3u1mS@4Mx&yXry&wG%DTI3i<1RWlPsofUKAV_lQ%Au1;6F39wvz1# z6q$alLl1=cACX#CMi9KJ3}xXpT3o)%cQ^0+pmJ)cLvX!nLbiE!16v&M#Q>`cLd=#S zfa2&z_0h4xZPczd=Xzp1hfG#zsi>nlu17fYo4S!sd_pIxb2o-W58sQH{Nr5Iit^QgK29IT9BmX_+>If6yQ5D=IJme*vTP1~`k7mRRujCP$Q z1VV^boB0<=&B*Sj(m#4TC$x0vG5p1I%BucU>FBD;WLTOR{-FUHL$fwasJ6j&Cb1wy zza&0hQTv&d=~lqwHdWwwo}@kzRT9_nNCfs-y?u{ zg-Yv7sD8;wo$-A6XXxXl76_@xo8@n1UykEV&^)P6AK4yqe|aNJh~P?yjP1+m@i+CA zmk?gZF~6$sKJ@vwdYn=}%1uqw-2XDTvO}CL1wOQrZ|7>QP=-~a;-m0`4ULKkG)2Tf zM5QQ(V`t6MkT>LMudOwop{a&su%g1vCV37`0%k$yb1 z6Pf_HU7}iZ6Ir`pC#jbTAq){xjMPHt8a`I!yHGr!EH!CR9H?Y=~R33S)S;8`(;PL5Z=7!W~g<9dU$| z_(yw>ZQD9j-H}QPyoM*_5JSKqH>Cb1lOCJn2z^*qnkZ;`YmD|i7B&wD zK~Ex82I3F#cd&f$xAW7P(=l!Kt87T$mh^tsuW~RTRMby=0n^TR*LHPz*T~*4KztP4 zpG2~$i~n)I#PR!uG{)bS)Rf0o&7TAz*Bcw!6ld9l6ijC{G}9p}B&0#hkYOs~7}1x~ zxKJ1>eX5#f+Zob7ozg@7cqc7-RFXDo?m3?E;*-~)#Nq4Jx!cv7KKOcRmDBgw+Gj+l zEos124t=V)zLzqw=XNFE&`cfcAQZps<5L$?(hCd|bjd~d3mJlS4*N~9^; zVm)6udt`%ySTF;F$c!;Za^AZl=Lmg%)5)^W=uvHd&@}N0jz{T)=tinnXTVU+o#;1) zREO+Bwl%L+Mqgrf;P0JsLSwWqMY?QW?;{+iib(IDK^XB+{Y3J1!79mAqNvcupEatX zjfvlG#tEzEo11sv>t2lo`nJ6y&-)`wE@NxGtM|HLTml|`YmfLd5%5O>T?nE0EdD)2-*pm16Bu$y#H9r|q#e>RKvF`k6nT7CDI#&gbODd3EG4VbT#7M6rRJ)JQMafo z<@R*;LI^2nLPS1en*aLzzEdrivPm_GCnS`Dh z+@erqw{Eb857<#%n5CZaG56-d8bVT&34@Kf5y-dfDo+GtI#`HG=MWyr!?UYKv%Y1) zbYzw3eH1}zg+XyrZ!Q`|Qqz5a9|DgR;mz4n#y*xc$cdL9_%q*8pToIcuiSu)pj(Q^ z|MPra_)k*PYnCT4?43%Kf0ArjEl5*X3Ky4whx9aKw)s7cNPy@jDt%1*}1yGobkZjyU@~FQ|%=k_m*L?Obot!pwy2dea z>@)qvkQh`(3=69%8Ct5P$Rs@5mLuB+dm+=Q?Y3MGHDjKW;Z95;+zl%4Zn3wznU9c^ z9I)i0gGO^IX3mPhwyg7+2%aZlJL07(1=BuG%75L1CAsGkr`YtwkHnBnbze~JV`5UO zZLy}Mst>(g(IANbq{_#Tj?D`@j7YPSgDeT;R9W@A0CEL~S|6j9h7S@E7gv9yuSY@% z_MW1SYBMGm$(2zwJ0AsXv#iDL_ic;(fLW;d4?X*7@rxF52M_cg1hqcqCT^Xvm3vsE zU-$efdvzCE)dZ3LX5CuvNVpY?!iz1VV;C#oLZa}w_1le||Nh#GeWjSi%OX$nG@iKf zgG=^rNzv5hYczMPQ*=A6V;bw)zuB2Ab)$1>&(z385ratBo568JPK*}frvNufkA55q=Bkz>ocq2yJAb2 z*60B6BP(;(Dlo&AVE-(__3Zil=Ht2__CMV%D*?~fiooogV>{2vLA*a(JB}Fd)N9Ra zDk?6%0d424vIUL(a5Rt^B4cop$%GORJ>rp4<~X9MNg~4$o#JM!m?=RBi#w%{x3Qi* zhiSgw{Y|#r;t1On=kQVE7;a2Bnr;&&p-$;h<-gn;wdP70RF;a4ZB=VunUa6E zsWPCIklTJ3^U~c>=E)Z!ycM&IrZ(O3Ph#uijDI^!Ti z9#n26VXluc2xw~7A8Z2i0vVx4EK(Fo%ZCa*>Q$2ug-U*!nHL6?X5e^4OG#eLM|Me5 z6ZEBHTvLThhaVfr%v$R5M{3>Sd`LYUERr_L_yNbjnQf8R{!HSlDAc>I($N!wsx5nw zXl(kvN{@vCDLkrHtGo8TA@4Z)g-1PPKhwv7a%McNn4^AauJp}d`OAoT;HoCt5M*bfers$h2QNPB z5pM&%$%)8ZW{omYZ>>Y8K^17X_$zgVn<1phY2FIxGhbOo_vN&6wl)1T|HULo{+XK| za?6nuI_|?)!rUe9m;jP)#Sg-Wt7jo~GUAfKg@T#gX-jIF_LFZAW}w49sl{!_Oqt@q zocev`x=Lt3jW1@U`P5;IKp1Ce5gqA>|(nC{%fvQugF@C`-7FyA^1kct4vC zPjq&~>3%Kla^8E%`xu`t^9+Lfh+Eo?xO7C5-~7Dlt006D^vC$%wb(8oet)n~y$UD{ z(@R0F0ee7Eq?Le0v%Q2)rJ*R2^c5=?S6W8qz0czzq;)*Au~g2|b9L%_aZOe{!qT-f zs-9oqXm4+2LwLMQoc8Ii=7ZqV^GBm0shYoS*x0a+3D|W_8m)ML<4M}ouWSg_P)m*o zFQs|ZudtNH?M$Nq)&~Y9nq%VJg5nH_Oy5Iijz5}a)p$Lfsnwb@cuHi`-R64jzw-?= z0S1r*=vRW9>nGRHp91Y-q8{ZmI|&?)YRz$^F`SekW{Dk4yXEX|9zBlMIHtd*+43mK#@yxdQ9quR3*)?RFd^1}@x#o0si$v?A4{}W#k&ka_ zo=T`-S{$y42z^*EG>^46M@^b0go~m@&T7~QkEwv_)MQT{OUxNA)+@Y@#sHT$>fq*D z72lMw`#%c04qGGX`d#3r5`b*envhT3wLuHf9{!0ZdZhb=a{Z~FRwObHuAvGA0z%n=YS)}oDXf- z83y^z?i9b=0u6lXa8RIS{S_N>9Mx?JeLHXFI8^8pbk~d8aFW1rbAH2l-24Gwqcm4Q`)vQozG`{AaYEE zG^k&~q3?b3TQ<;81y|Re*;LYgejgjsa=Y6Bj>wiZ$0iJ&D?Pxr zp&bOus}WZIYJsH4HE|q{@@XKA?pe&hw3lsG!X}^V-j=l}m*bk>@i9x_c6H$SnDS^2 z_vhwgNu<7)AmOGWznQ8G6I$sNj!%%Kiphqj=K2#%%bw5GK4e9JfL>DL?HQPxmJZt) z+1WbPk^mqX7SrqkcMRPTp z)Tu81u2aRFx`shKdG)yD5lWg&6tYcW7^cACdEXhYkGg0_lQYKSHrjr38yK=*<#D1( z8^2e+cK4&FA@y-TvX1|Cqx~ecoG*aEd9^*zO3u7)_vxR z5I0?>Ct7Y%eWwv>`qh?eK&iUHR-+d>XNt_cjAnLl`Md3m@W?`)>N-%mlN9Rf5X(?O z*F2cEl?ku`=hz#OL9tdiTVU7;cfX@M0xQ|F29%~cW&+9Dl{JrM?#6yZ#fPv99I2`N zt3%Oit~N*iXAxHW?mZIA&s9zpOEizOwj%C3-QS3^mvRv>V2E&$Kd#(QO4SE2MtMB` z9ZpXja@#5k2i!fn!%%FIDZwJqV!%SE(kYlM?NfG)4m0M@KbX@}y&4Z_2e0g6c{N(L zgkj-7&+9j$86#h7t4ST1Qynu?nv#+gCh$woKx|4&o=VipPfu}8>8fdL`Y<6HV=DGa zFW&(jRn=u|KuAyTQju7mQdr(+X)*YHbPMKLqx^`7@Kx`g z1hx`)S+Jo*R%cT^FbyQ@h0VLnZR0)JTZ-DJT(d%dk6Dhm#&A6Pm8Ocnh`ReuMA6-S zk=-8K^I@#uv|l}P|6D>l-{V+JYK$pU1D37X+^zoe6ua-oT>suWRzb4@nA=s?hsHAX z^09?Yo-f^C5F@M5(WLbs%P3jn!f$Ld9~U}{G-B3olS%!r9vwsX7il1kMIX3Tw>7AC zfydlX*Az@bQc(^xr9pEuzcoa?MyenYG1%KoBzNH_K6%9eCX-<~@*rR_=DR{MNew9` z0!w*3%o9J;p4x9zWkIENY9iLOR;$ABV1vs#Ge!Ls+9RzPNsneXhov;EmgaGK*7*Z@-Y*L2J2CC`@BW^kqtUQCD>P{^uGZx}B5l z$Haiw>h-?c6A9Ai0?OOpADi5oJVvo-^^Z>9e>f&&;O>4?7crAi^-=m~0b}p9Tidao z7c*@K!BSI{7Qr+A6Gi~6mi)?~eu-`%S&?X{Z6CG3^1|+HxL9Z4E-0c;dsnHQ_=gq! zIKQg3(=J6!Yiubrc|K(CKyY}D9eW)Q=jb|^!@&j@I$n+ zpNW;zeS&~P;9MZrefWgm`F`jf@xBjLYPGFh9v!GF&(;_DMyBBQ@U6xGwHR#ickgH4 z)3W|YPekqyd_+z(6De_UKh*fcZ(|**YtsS(P08o)iE&#Dozmo>^hJ#t3j`~j2niJ` z9C^urDy`(NF16w+`c!tjFDat|71f7(o0kHP2i{;|`%W(NmHpMmgWav(CioG@Wgr!f zs4Wg+s#u4tRkd;QWVgLbF=TTtHcTuW!}&Nite9x%)t;}CFkLlaXro#LDA>@&SKvsL zk}$7-!#$aB9My-`etaCN#o`!r7?FP&dK44bWqVcYDeQLT7!b*D)^YjVd8&WcMf!@; z+;yc0Ccb+vcYG^4>nnKVw-LB9ugGn2nQj~oMG`bX9G&|(*V<&!c!SYjrl!XdPrBWh zUec!b!B>|>>SCcP!PXGXsY zs!X&Qg~hj-UajoNTt5 z*;#99&Xt(~cY$)Z5IFyvBY5unR%5#>SW8>`Cw~9S-HOkYxBRr4Jwj1AWdVS^c=!V< zdNQ->h1<;D+w*joP< zSc*sX?{ges-L^Wl=GR($vbI?ttmjy0&<-@S1!q=84|Q`JN3Wp4O~oyRB`tLyx*OR* zwh6CSyY98*cVQf!5!m1g=Wj!cEWFJ|1B+Lev5dSwi8`Ttve?~w(=2fV+M2zS^i1qi z!7<-rzzKVGT}Dey2Y*~Ion&oDB(}bNj?5Ag#aDwx&FR5Vx+9ZTg>xLT^T3E=emA6J54g^ABk z7fSareGBcj>*{Yh>T1Geg6jZ8J*`YF3xfta$E}@%+b_9!op(?{Q^#$4$H(E{hWy%^ z&Bf{1qR7nN+)Z_37K;_8E;zBQXTa94qD`C@`Z;v$P1`6lEk+XoB8by_`X{y z&=nBrZV&&E)j@;bv64(Ku{kcI6P;NbbXZa`Gz8y0v3A_2 zEM@m~-W>}Kn-_}&KKp+AU5h{-OUbEv^hLGuhSt*2M8vJ(SANZ9dy$*HvBc(*+r&i2f z(OUEUPoX;oB}*DU`dSz&XM{d!a5!dMk{+Z=ySz#mPT8@6yQ@M!?t$lz%cQLle=HL{ zV+8>ivMMP9c|1bq<26|%0qj~b9cCA~Q;TL(HJ4(!Y%P&ayHY$*|Dj%lAe+x}E$(~LvUR0((K4loCrjH#2&u4-uU(7e!hA79<3L(G=BXV&)$s2= zDei{k)xKato`4rfi@4|TV!BW_?QJMG{y;Fq~ z%YIzPSN*5K!LpS`&nKcj9|ve;kJ%JzbsS`wpY~TjQZz2@Uc`}zOy!BNH194-rK&EnOJTu-I8DW`nB!=m;kGk()7fl;cAEYgTSbi^1`Y*@L~{UU%z?p7)v z;3j|9!%wMGk;!F~KI|8nmjI|DU5m|Zk?L5x>ZC&%7wb#%p2x>fpK#wA6%HAi*OUwglYi* z3$kX3TQ~R8)iK)nwDkPO$tTw5jgbHX4S2Dn2whJyM%lI_NKY+(-z&CPC8lxy$zLx5fd(H)I5WjoIHDyUU%R z5(cUd5k;)x8hHh#R0|;`d9sVHTaePWRh67Lz?Lv75M>DnCv4ALV$Zb0R|O*1)ci{3 zWbI*v+AzmqNLo4G)l+3WmD|8#TTGACTiTi`Z+8**XW$sn-qX_y!H(*Ze62nx@HfN3H#-srlLJFAHSq%qZ#@cp{4D_yh z+J48H{Ej;O#(`YYR{NU<~V z_g&WxwKpJ>{S>)W>SI_zIpph+a1PDMF@1W+doWy#xD>u-3mjj7%OmDdLFLG!_uwT zu~^8(Q`%^d(kNt=jAfgkjgilz@%^L#?HwAu9WMEeFbvCDRCcsn24O1rCMXDrVc-k! zkWQ%UU>{QvK|m;<+A*lfiww45AdYbX^G{s_6q`TeznVk-=l=!+{zZ6 zTK&RD^mtqXQGI^gmXFN8e{c-?UxW^BXpq)E?WL%#VEyEhS;(Q95lqT2O+`$F$5JEY zrx9AvMyoobLZzC~hlZs(NVyet-lH#nANWJr5bZk@z@u5(5x9Qgr`um4E<*NWG6SSy z@(K$Vr;h;)H=$B&678!dDpTUU7wt`MNe?!4i9oo9WK(al=eFp3pyfL zMtjS7Th$E zrmm{bX`u`*#&&2LJB7rNc5`-YatKnXvneUYE^Y5h5M2c^is_J&DP15t@#1QBsPM%_ zLBxpkP1{y>nxzYhg%WHPH<;pqWL$wi#Z_^{kh~HDV7m}xv(oElq%Um~=6*UmzdnFp z_NH(b7YU0OhmDC*-K8Wxh({5l(l6XkZacm_iLmx28L|DFOjUUUV&)~_u}n(M-@y~e z%D&K!|IjRPD?>5hUMhf6yAs1oH6C{PlZJlb$|{M6ulbYI@xnX-7jIe-e7pFgr;T`>h@+7=p`Uc$5oIb*ExF)8o1Ne6R^z~ zOZ&^Py=FgV7kf?5&@dM)Y+F8?Zg8)sklMYzx*> z11ZL2P-T;X2DRu+|EDA(5%d^w4QNnI6jID5lVBo4@(Z=Mt5bq}&V>_;oW9F*$B(2! zK$tjIb}6ZWE3g8gVY)FpGWDWGm{o}qEFzOM-Eco_lt?KM1s0)Z9lr}K!`i=gx&1zt zeGe)L^jlIhnxZ-;24m8KGa6UeU5dMbM%af1D{XM;CD({;QUCkTFmLj$6OLe@oW2C zDG{)sz>WML7gXi92O7J=i@%^!m6B7PP{oO9?+YZc1tdYJFa!V;Kt#CZ3Y`AiJlp2z zTPgHS(fi}+URvkLeXlRZxLntN5V+xNnPHgSUc<5^{NTI_=0MVskgtA7C~QXIOPJ&E zhsUyUFE6|@N)GL?NF{S>$l(0uwwK2Nyh#YcB1Vrgr zt42VGj_~CC908&iF8%ZsLh&GWXd^5D!8Ht2$b?-?^Cs!Dl3KqpcG}n3>h9KLODJBl z$Pw`DHA${BeLR4y_IpCJulvin7K{DioPK0PoAvnsI8emYq>AA|A|DRgNS^*j=9T-* zJ^v98X#``>4H+AO0s`S*hRBO1yx_C3^x$2p4hJjyO$;CjrHJsP5l^F-PHIH9xlwEG zFg8e@(6rlq6l(DDhunil6{h%^yMKbJvnq7d)uoqm1N=^a829@G4%I9RZ3b=%hPd=7ti`b}jc^>IwrT|AK zJ*~k9merqg`Ify76eC7R2Y0_E&%OgF2JDK!KhHZHKKrUyG8C(^zJryU1Ye^c)Hjdj zC#7VH1Y@)mZXg3_%bQWe`)rscl+hqRrl_u`mV-gG9zV|%iW34y4_P9^N*Qb@NHg(% zx;qs?Fyx9GKvr%)>L^3kSLJclSb@R5ET?N+5g5XP8I0NvP5|ukicXpa1z87SM6#8S zN%>Z&fiA)=5VotuX9$o~aYnBSn8U*88pGJ2i+`(ewOqGzV_i%6=OLI*9dAfF)43wh z%YHQ*>q`CD`I4W|l_Qd_QH*G;?s|23H699uLE@dT5-r_+a^fyvWE61mjWnNg2A=dXuw4$LLD z>p+@-%3Hyh4~GQ`q?Kd13M;ZRk_sC3M}?oTs)rX@>PAHxiPr9?;XT! zVrDH`xx&@EU$%RC@nKVcG;SToh%aAbv8>Wij*=_%xU?-q^3)cAP~j;HUX_u1c{#%; zoQ#=oA~68HU4-J28ixTFc4X1aF*OX)5}%cLlaVBGM|r~FmL)2Gt4bxfgdhX~_BA^| z*Nkk(CrD5HD0q=p?o_KKz8cdX#3gLJ$3r3;tlkAhfM9G5e97q;mp=5i+$Nm8ZbX)h z{5CS8SnEJ$eVU83ox9bgd90@Wz&ySqPLf7rnLn!^f^peQa@#Ur$v|%Mn^O7v?Wyk> z)PHS?JpW5S}8T?mDnz#DXge#!16?lX}Ua_dS)kG$(sZ~!D2pu5wA}caL zxH+2*Q*li64`+ju!xQ(nC0vq^@bj?E0&8dFpulymnt3jLc)pRI1Mcm(ZqMQ?lh`YJ z8i8Dse!Y;`YldJ>&*3^8oIgQtW*B(8CT&f}j_V5ge)n~dD$YXj7a5GkQZ17~zzx4m zA*cF42@uW9-nQgPBaeZ-s2GsL>-}0UurOt!II)Qe_n1JAWc=yjfgZa)$iSmcx65-m zU0B>};ssqXho2Cxto`;!iaEZvwsvrWOppJ(l;v1s`?SA3JViHNEaQ4U4-&Z*eTX~c^>=D2+ocHitRLOt2yz(_`BYSrzITZ-pC{lM0?S(qzW|CDr*c)O84kx#p`o(LOCu4o-7cx}-)XCB2KrfHFt8ZQ2g{tF#lx(|p_|ylfRh_(tsf&r>=3%A2py6T zF~l*Zag>`vTEY(gK zeN596^%^sHc#RAI&=UV=r&#dB!|)d3g3%y>E5XGniZF9*Y&fr~Sa$l5B_6p#bYS^o z24FzWZ@PRAzSK)D;JqXOKnLJhW}w z=+{x=Gq`N_{Ij0x@HB^K6b)j5;kNI~*zEcGPvsBa`}(2w+A3>^?T(-O3=3X;nrQv+ zCNh91**WwW=s_P2!c{bJ>Gu<1{ndCgf05EO4ol8D4CMYGR0#R`>pc^f_WId}-Xese zDQn>S+<9tuK;^F4XJ6Q$_ zgb*i>18()vVxGpAA(lWj3Oj>I>(WNKCuY2Ui2Vq^XPl+i)1v;RLJ5o9zf}wb!emo zjtD-N^!x~f@?3HAm&;a+XT;DsxwWF2p4s((9BA#HuIgp%@!nj`h?n!k8XE)nP^-{} zsqx|D9g0hFiWc{i zwf6t-eXephpE*Z{e6M`(Q0cubT)~Gq4wCk3&<y(lneg+Lh^MjBuDurS8t3aWXh3sZb{VV zD*3s2HSO2t#(P?4nzewz6yXf>#+>+f2c7|)`EoPAd`CCQG71udD>#8z@H2VI3$r@s z=&VD|VaDqd|IqQYfz;5@V8ZW}-NHxVmk2OVW8L!p*6di` zQ_ZQ6%eQvt`^fwEq3^#$*Us(c>+95vD$qSk3}g1k0Sn?JXHtmf~*l% z$zU1=g!Ic|A6HA6R>8bE$JnVwc-c!3XWmGeg$lPSD)x0QA23Y-91;t>VnoWRHHrWBSM-CVKKvx<~k(o2?tjFjy|EQkO$ z#*^?T0|ZUm=xm%%A-yKwE)hR3YFO?SvW{r{H|YDFvX&fw=3l{CXBy= zBBDue$c)}P+qOwqVpt?gwigTkJUeZmqal(gO#KUmM~bM}&5V!lH*Ee?DBoiG>ygW* zB}Q~dzmE%^?&rTgeY_^5`B4bx&tzPx-4vi^>uWD17aST%^8tC|JZ}1lfoFEwxY%*! zV0SUd&$MNP>f=DW%7x@9vYrRGH)W9&h3ZLn-u0#);&gepEp}wRli;axJ%Pcev8s&C zm2RguQ~sh85ohzW0oeEA!c#)IEt(W3LG`=`dEbUvOj3e~6?ljh73Gy><DT{Yv?{?st!tqBVmvQ@9afWtZAuc zbAFo#k9=)p>M~7y%bOqz3@rIuhV*9NV71;rHDwV_SVa{nVwfBhS%DI?IL|;n5Gz6E zSTYeU5b(A4`bFYVWH&*iR$W!$69bo>;(tmx{pQ$6*yE^$d1uq>%)I zSF75gKn%n|$RhDC?>scJ`K7^6=b-gRCPfcTLrd&?kjoieKRXn|{>8f5grg zxhBX;3f{hMB~Cd$blGh{QLBxt?UEzkDrx#=x7ypxW8(Iov3iP50=O9~pl0ztL7L_6 zelss0*;;4k2*JZ?!7Jj=!QBycEu*ib($Ae9_S(qa`!{!6I%gf1DSPSyt+XkJU&8D} z(%}>@dKZT>j1Ao(Ri@{i4{KLe`W44=;J|@%>MBT7w%5#aevANgGP;CRPzZ7UMJuAU zO1FE))BAX_TQa=;@+Y4r=I_*9cECf97?e8Y`X31+*IbElYSo5WqIeO;Lx3=waj_x#|FHvQf^7L?0Do5=pjoYBb|9R`mA2!Cp1vkXmkMV%_?ugmuG^o~7c~+MNbc zZmWC_+x=N$e~_vN2y*Jeofnan?ZZN+frk~U+JAk}ygumZMx)Q@tQQm+tAr9zCF|~k zB7u?hj0A>XKVA-CYo6wS<6bhktc>LJwCv2*_iya{Rd3!zZU_juJm2 zGeV8*r-`T<4a)aDB?Is~En`;?0+B~iPaTE$=+u=OKOEhs4U85MX0CqH@Vhv0f|ln; z=(pciGxFZa+TXZz+LbQW9iB-{JUSt8&ywOueHmxt(^CXo(`)TU{la;B*pb#dAnc2k z>a`Ch6eJ+`j!5DwD^utk*F~x?p#{6 zq`!xLxu|A|)lwLq_kMf(5DT+%d|e{WF-9|Wf@ z(1x$;c5bhHU(bb{WNVEt7-dyheJ_7*7B~PI^#2ab5NWp0DG*=pe*NTs zcoX%Q@3-ZdSrPI^~Wd;?TBjkP>Mz~=JhPM zs#HJJvLs3;Cb|d<3VrEgt*b^&l*1|%13{AD=?)jtoz?7!c&-<@SYrgGwqkN&v0}cx zxdX&z&xk)kJ#5#BbgPNuFPC!&t-{x%w|PigsKsLh`6?&a-UC+#3MiYpjbz^w;%XV# zM-^n*h!9|tWl9T6$E~@LUcR@aTh5qoG?)?i;ooh#{E0)}lPYoP&&CWbqMUij_@Fb0 z#FY30aI)fhQQ+iw=ln%oP7#q@g_QJ(186OkwH*;_rBuM#Xz%82BYQM}jHea*9#@fw z4Hs^@93VbCcji#p+QE&rk1N0w4lCYNpK~AL-D~1$lJMrHLto@=!_$|d+M9l!?~O^X z*HrFLG(0)UrGHA%^~U!9O&T5Vp=(8&*t6I9%Bd#dwTR@SL9JSPwS_HW3L75u6X%S(IZE?c881LlH#M6Pm~n3 zrPoWY8JA|3uY5=n?l5-E52Dd>6_BIS?Z8bl1|-3>#zw)bHBPUePN=s|ZKZE75KIxq>cS1d-8J4f>5H z?AmlR&zLY*CRm%!~4PhGlMDyW|$d&}@n>CLP%VV+KV~!Ls z(HXPIdQ3Ubr8S+T^iPKLld<3Bm$NfA{)hiveV`Jq%FI1_VRveOXh-}d5Sy~5IekVg zoG@tm4|Ek0NximboiYDhl{`~lW==rfm{BQGKg=OKF~$H#yqBzA=`Re1GLZW!AF|Ft zv#i2E$>BGiZsD~>F2a6e?Yw}oJ0{}*e^x(%ubmAjYQQPiZy7WB-2poo_bZ(4qq}aM zjJm)h%<75!^ehK1eGi9Mco-e@T*+N~s&}YMHrTT#bgdJ(`i<&jW+<+fisT1PSqQ4B z77ssO{YzWx+W5rlzhA+i1;a&Rw0_{uP-r<0S3ylND`W-*%9E+$X)7W3k%D7L(QV$= z4yiK7yLtgXvkPwVc(K8|4&KH}B&CFC5o^zV1g}?4CLG@vP5!CD5O?H9kj{I0NHt+q zkGAgb%0!|2Ld!i;o>q5JEs7Bg`v}FL5L!2x*}GC-DXby7XpIHzvcUU?L_}dN$RSV zRtO8`{P>leeyc=CSWu1%5Df^tq1^i!mZZXg3xwB@42ExB&`kP}YC_2MEej{`4HyBV z8cH@1ltkSLG({6PXN0XlV)74}8Aql%oUXx^iZGc_%nBgbSG=Iz&uyIQdOWt zRchkV9bTm#9UI`FdGi3ozy`etgs3VP(rt9k(vllwyT8!<6mRgM9^!jRHhyYRk58oQ39|QT0A1)&2^8GAEx=@V_ zUnYs6JbqJbqLhVfiX_m${bBIJIHGlR=f+K&Ob`Gtppuv{8z20UdEgw9Z|^}vYGY@I zPH$~z7fK`C%YYVnE^^t5iHX9&LluAt(3xwnHYUj2vd>B{U{ep@RUUVZ?oOZ@8-)F@{CM@Eu2UXGK228 z4wOY&>?`NueduEiCy2sPN71A;PC)Ip!2nku7-XaB>sI*r!SFI{0w+99K&oK4m<9r% zXd9j81JJGQU$NK#5#tQ88UN^ED@$hj5z+7N%9EpGS;aZu77vIvqdSFtAqg^k)23$w}MH&cyNeB0qUqjQN=U- z!t+}a4x&@=MT!uvxD`}fB`#2xqWbIF7v7Hi<>PblvE*e1*WR*m-_XIg1Ih@>Ocu%& zFmleszJg27?J=|SU(^4Jmz?j!pjgDqfn*zcB+s19z}o8INao*SNp{m%!5T_U5@2?T{Blu?xf1Z${7SFo2Uw5~@w&9g|mniZfGA;Tt%GqC7B=`jG>i(p6P zb(}WW<8l?4pg|VS&M8_@-__M;n&cHM@A-QI>6u)a&ri2~J1)F+xfU<7Q*mAOQJVcR zjg;gBcH`jceIPC#e%js_OejW`p&>+rQqI=XkBk zM5)zSt4?+#DJe%9ZaEZzFDNU4ha4&qM`1V>I2bHpRV=Qg?3pzp5#^&7Hq1sL-eA*E zVt7+>GqfbHdMY^ZPu8%67^j#@Jm53|bJ*~4pKhhf6>>_B>XTI6t(f0WLDH)CH1NWh zU1UB)VvhE%u44>J^gF|HZgwPw5UBEMhxBwsSe;FaRhI>!Ws6Q@Y6Yt$C8#kaOkT zv}eI}oaP57?Z{Ez&tVk5!p(LVVo3YqNX;U`=Qb;4_0p4l>%j2cphs@ZTp9&BaT(;u zF|`j=_-1c{AM`#$Ee?gXzSm^RxG%?*8C%ujdX`3Y>f7E41Yfz$=IL`h`!b@J)#(iR zy~iaHh<>@W%rqO#u&dk6ln(Dk?`K%mRXPT}RtOuk+s~{8gip^b?$%Y0391=3oT;n? zM>K^hPG&1C#2t$VD_>o|(MlJ-w>RkzzLDBe;o;5dRofSXFf$ ztm^IsY4h4d}zPPA%a&oa$&NLXOM=iR=%;Y0HA}X$WT$CZa0+xsxlV$E4 zp@&s`Pz~bp1M^r+y~AUZ!3}1@CSfrX%!XYqy)7>A(8vo^TEbX@?2KhzN zRyR>dtSL`Klga0_kwDgYSo8K7CA1fDj{6@&rOTB_t5{wmDF+fEoLm=w4J=}uDy)xM zk?wmRnNuvYViKAA-mdG)WhsBP5Sod+O%(z*x4%d$CGTbP3Y?mvbpE_~W!n^;ib)C_&Qokka6zIH$5>Q)3y1Vi1Z%fTN-M(q)qVZHSmm0{ zI@kMj)#|_B)nCw3va<&+-_K^{*EJm%%84Vu0z@R{zyUJA*^iVLXJIEjU7Z+@JHHaw zW4GseulI+1)FnP2sdR$W_yHJTasYKyJwQ079+r{~>!)^9JuC?0W zir6C0S>fhJ9eDVtTjdM_ne!fV0c@%&Ij3I+UQwY(-un6evlE$os#n6Q5W<8H@c9S) z7zwCn@i|F;L5&Ds7edF$r;Fs&znu7{#f1Z$FI4uLDnI`-jpLDkG=kIy4->suofFn(9V#Y>dsl@Ixmg+|FQb-L~e z`p%Dng5o4#F?$nG`Mcuh8Y@f?y?zago5RQ_M}=?Cm7P0@@e6Oap07gFHkl%m$KoxM zKmcybJ(FcBS#qKB>7gV+4a0~W7+!_u<3`U^i)EyZcK6cBfq4kb@A?lR#9-*(5X=>s zY8%&vzO5m_Ac^)RCgLlVOqje3wSO$E46t%AKG;uS-kci|zzlybKMLCL+C%td%zv6M z&z!EMOfJB+T_POx}Lv7D>ob*nE9es&y)Cg z;1#wQv}iT*Cbs!NzqzxgS;NF{)IA7eVZU1`@V@r!pT)NMJJeC4Rb(8e$_Ng z0qp+%d)D{ZhDRA^PdhiC78iq#Oxt|`<;1v?1Iod2ctDS`qA24hnW&Vz&fmWFSr(NK;Yd)QlkB$80n7Ih0#FL+sl*WT1t}$sBCt7j}3M6#^denQHCFhMN!gw5VB~tq$;B{=r>GAvDu!c z;E6Lq!fQ=;`<%!s4Vz5P{Iw^#9rF!RvGKj}&=Jf2Y=s_0Q73(Q9g1B$owSf z)G{mNjlF5D+Wt)e)P7%f&=O*nmXfnLUovbRC)k01FSsxtC^I*D-p|;r zE+i&8$HVw0>*INIVT0iz96#Y8g;g=6k`>y|3Bfezckq(wQB|aoAgT>>5>F9)g{V)z zk0tw)fdCb7SaMO>I3yU5&KHb<-I9`|i%ue|BMxC2AuX@iZMP~2{*3lt2^~!ptirh} z&CmK2`PGpU40{~&NK=$fIFE?^h|EuITWy?-*VHy_kUJZw)obxP`&ljq88e@JeyTvF z>#tM~S}M%vFmaO~!C{>eqmlx2jX@wQZzscp6nW#K9K@baO&)G_cDD7IdcSQ^|E_;( zn;szAVHIP^nj9{ZI);k~Qd|3Nte36&&eYA}!xy1zCEPKBiNH1%yWaeFp~_$Yh4RR= zk^icGPAkRca~!K?b2W)RpJ3c`TSy3g0iDoVD(T*M`?e}=%0k&WR}}$d+$EP8siQlS zK>fKn?a6}?+{4`Yfmg>~Cj{Py9<8d43GifpHsqFzhqf$~I;P$IHk92>;n!vLYeS-Z zBFF8Br+zpY%M!@>bM8$_wHT~-Iubjyi)MMsON9|;oJa|3!#QdiIu|<>Z@_=f5*)}sCU*|o zs_J?nv%i+9lKNw4?~=Z1BRrAG941zX<$lh#*g=BEBKFh$zPZ_+sr^)5riJ%|^^HyCDhZA4XzT+&dYIM0?<|?+1 zJ!h%{yBM)n1%85a=avL2ef`?pv3)E+T(Nzpo^4gV`d5M<%I{`wdIf>mKFMhF-iY>+ zw7IgeFSJ#Z*rNalAx8MmxSX%PI~`T?oRS6~{(8dnB^N(@(l)C@#{qQXEF!i0H=nXq zC-M2nX(nl8S=fj2Rs8|?eoi#>@Q~yaOi%cFWK!*7#v51|{d5@A(40N*cJV}_s)CP@ z-$*=S;tJH%O$fsRIPsVo1$_r;#?bu@hB`@LAsUcjm9QiRrXria@Ws{hI)3DkARZ-y z?ux1^dKF+LPDpP2O0`TBHQ03xQ34Sg`(vbvABuSb3?PuQ&1Q%G|J!Gh_uNQF^6ChL zVP%YYiIGf;wR=m0!{Sl082(yR{-%UOhM{B#hPGB<&}zri-H?R`l`cM{zVU=ds6#VI zqa(g@>D7r@EUMifbJz3pRS!mjoWZmj<~!bOw_HNwGa{$ipxLwx86ySMiHMQ8Q3ZjA zv}Si_gSCLO6eQT0-?kJmK%uq;v&M68yVKrmJwhU@@ho@wh{i*e460&7Gp>#@WkpsB zN%&+BMIsHLS&%H{e(HESFT2iP`tU}&vtc3ko-Za`2NU0htBMN{Fp-EmX^ef9vd6#- zyzb~yN|gkIWo&_zAg}ut`ALRT_<0G7@~iHb-xM46e%IPgUH7*MccLpqz79)WLbpCn z>j|E}9Nwn%^pU(yJs2rinpeBsJW)i@;r7KX6q6=S;t_-91A|MnU-eZy z#rg}#kF{+pHA^Z^mOLYg{qPTq3pC<~-MBGghz+=tcGB0Gm zz;xHTK+!jSKQybJ@xH>^iEsTjcX!voDBt*7BLbl6XPeO}iqm@I zT~Vha6p>VM%KQ$6L{$we-eZPOPtgRhV#P60pMvUxiS_k{GG=g4|MH1@!hN$0=En4~v9~2Qe24N6f%Bhzh|R!z z=6IRU?p*}|M5bw}oV)@6h;MEWzec;BPj!TP09RP)P>TZmdj#7mrq`@q!^DaMGzeBU z@LxUc+KjYdg8p1~(17FE;ee*IFGL2r^Vym`kCW6F?z_(xV}xt76<-ZkA}^%1(U6__7*WR%s~Ue<3mpg)#WRNQwVf3a$5E}xgw0N}}3C2Z5S zJ|))oz)|l%hr4EYc<5!9n4%gPr#$@HxV(OQ8tzu27GnX&u@*Dz@8XqOS&~fb51bCH zE~py&>u73BASXVmnnh|SQvpqlwe?kFfAgS5;lPWre^N$c%%f{1|GeM zbz{E}=a5$Pfk6v-Bghd;rW9bBD(n+$gfP%A?$HoFLbE?AVbgO4k(>>s=7Y+vQmd&* zAScoaBR86NGC*YbP+5pqO5176>f7TlvHp?B|F!<(DT~~x@d%lQl2Vr5j)G%~kc*W5 z+3dZH6ZVqZD<4S_qLWL*ohXp=wd`SoP8GKki6I3|k(;-64)3sABCjF9l`p1fH1NYe zwwFoXuFE%H$-jRW_UMN#H*8vEg*kyHrUlMgZEGd4R#_i8^T_*$ao{@xfQ2n4M&5ndfI!Ct^??xHdSsD0hE4>7l<@nke~?`I;#BtDzhoXDd?o@uD1hVcJ3|d? z5p%|@-C@8HU9^x%DqJLviEX%C2CxP$EiQ%xyHrW=ffqlr-#1z4iFx{;ULGUwGo_z| z0Eg?YMZJiCLqzP^ekl1vXwq%`y?LJQlXcP}7ZeQN%xwM94DR%Bd%LwZsipU!siJ#p zWkQ4>LGz~E{$xP%(sSN@U;p;wS2k2oFqDcWXu}n9L>Ek0T(ofz786x_vX$>No%EWS zC~pbJdURW)QG%~aIBa_N)|W-g{WGD1bIe~8iD>g=%pMsWG%37OrfL(|O8EWhH6k7< z@kf;IH|vd?s9lOn?4Vo7)tlYP+IJ_hLw?^&;pBdrq3K)D5c|>V=l3b43AY{vzsx-O z1@bfcz=veU5P*gzdN_4b)RAwO>hso=Q5DhU(hyXIE$446f90NrveCuMX%RlbX2>2b z*u@}-1Ibs)Pr?Pl#T?$NMLi`%0EKr1`(9g$L$hhXD`3%-85|h=A>HB-!OV|~JM3M~ zgne`1#cSvPcQ$_W?jN!k%h0S$f3G)Y683~aGw&V_j)n@Anb{T!uS0H%iidl0o2{*$ zVt&(i$=WN#N&ZaGsC&>MC4m27c3N-D0Bhy%t~+DZ z9-3tSp7I5A*t=A&7&;Y1JGf|n>hMJKF% zCw|Bs&N01QJctEH z7`tpHlKYM}067p-yi?d$TSA)nxHQ$L8mhz9S`s26rV`q=dXrm{LpXn@0OHJ^6o|3g9 zkRgZdtztn_!C9Z_3>-dG^1?tsFxb_&FD??&4d@A7=1m7~zq#0>+PxoS5~e+w8?aG{ z^;f$^d$hQSwJv*%^bx2n-$*=H6hI}_-$(P4?Y;_9s7*S?@|pjHBX_u+GB_jR9t@zGei~tb41avrKeE>z`1%y_r!L|j z=TcmvZu50Nhs~R_G+Jg2zDV1 z(odYzJRg-QTC|r?5REINfZyR0U)R-s&V_Nmz?CHt|AwO~d@zpWFiUQO_bMA<=407D zYh*RqvOvI(Jd~qU@X*gl+rtmNIAgly;}2Tpn;XPmbS<39?nBerY(qyB3f?VP;7g~2 z<6s%5&MClR0 zxF@y;lA+6ci!AZ5f_|s*RV=#eS?`sR0Gunixs;?icr-89o=5g{@E}N+HEx_Gr@x>_ zyd-kUA4$f-f2<(^e+OjEpWD7oOt1=h*hl^!zKV+_P+W?;0+6ZmqD14tAYdsX_zr@o z3+a(#8aLSM??%v3X0#`^g42{@uZN<50OB@V+=NQvyh(3Md*4^+)iEo}%gDx_vvb^R zS)#90UI~$(gRy3no*Aa$V*IG2?f~UXG z)6Jh@Q$nuuOb*{0Pg4>{yX8mKUj^J>DxdkjP5j#WgOMlUmBp8lF%QtxwLpahcLn!WOTS zmJ?1?_-9!)sjZ@qgoyhp7JEdf2QI(_ePC>i{7=OkMro=UYn>R@zLYrNlUCH2>^{MOpXWpuR9o!dT-h!_>ECr-VBl)DiO)dBJ$0#c4PuI`!kfMH( za+*LTo8H;tle8m7t9hi@oENDcJ+YOIbc^MTotlXTvWXVS*#YsYL)%1^co3Djr9P$q zWoaS?X%FMx-rk$J?ed`rS@vcVUiRDRS9KE7+}z?>`;43WuxV=!gX;|1R-pU6v5cu~5hVH)FKH%binj$PQ}gGo?`b<%-N-idixtj~T4we;7sHG}C_sY!bCVR1-9r92GHZyR2Pk zBe85Be;74D7TRXHeW5o7Fo?4CJMVd(5)(sstId69_sGJsM|Rj3J#Y6k>n2gwZ`sN( zseXTu!$Il5;lE@3ll=2(t-q$bd-F6!E1Qsmw|nDAiAflL(1iLd#iph&>1LF1v)fGj z0&9r2YA_&3ZtFtl7dyuMoPVgqc1Gd`{ij|2?9n)45js}xoE`7?Abz8*Fn)t)8G9SY zy1F`nt6YoXUWORN(3$Id<-q5c0#VUo+(Z9g2Cmse;1j#*)-QXXLZY0N*|P$2Mw`f% zPsiCbEZQ6EuwA=4y+}{J1Xa|tlFHR%;9-J{cD#D6l{vN6LKKPI?zRpz*yW(LZdI{$ zI1J#2OYVsE^SC3=w#B}qzep~53mgIBJ<7YVxPInChXgw#sXhmt({SJ z`lviS3}t>8H%my6cdT_%iLC?>yd)-i>O}f%vy)IOZQEspiT0yRLNnjRtc(c@4B-%W zR5vk-zQW-^`*tIyh$bp*^;~So>enQFNv-ufnmPV+)A0Q2!DM(BFT=dOrhfv|p{Ay; zHfOFI1D4)lga{Bz#|*)hjAZ6ykRVGJ7pd?N*NN#})e{(ty4^!>V~Him|2yY9srxQX z0*Is83q&nzBMQ)p__~mtj&o=q3-A9;xTyCdl3XAW^ik0fe!!%3&jWPJ$zAME>6Bqg z^FNSvlkqf<_|D4*RPg*`LP3ACWFc`bJj7oDZ5nEFlbGgCPFUWhC;c~wgFVO~=Thb@ z4w@1HEqSTtl@}_?Vqdi4)j-71i>cPdA#QmM)D9D_Z(h5%c{zMA)V(#F?NChy7W5p` zGdvzGJmpH4W044XjTq*paI&*@3WNZQvxbduV!bu+~KJ@`ZVFGW8 zUh+;I=o)onq`LFZ#6(|CdW`*$Bc>h>*t+jJ)SZmaCS_s5DzaU=dS!Nc!&Ty?BxBb% z7YjdxB-Fr;qrxGBRnxw*pKZ%z81rS;_#JCZ>PB#is*(U#g#^(MU4k4rKctwSnqGga zk_(%%o$-QkbpB$2<@4DXeb`nNT(?YHMtH_aaGEMCGbe)W4QEfBdiC0LOl z>9tAfH7Z7rm|Y5yhLndLy}a``fbuwCke5g*H}i^)x=Y4Sql~X;mZTHgSES z>D|q}VDp;i4Z=@VE?dx`mw!d?@RjfoKOu0y51Oc=Tt&~+OUmcJXkRk&ywQOk=<}#c zh>>CJv(dy^IT!2FVfdbtBclQ%9%&v9CvuIFwj_pB(;^xtUeT8iwlAxs90WmRB0~4> zz!fMyO(^{}uEb~jjNU8o_yIll!mB%=M~s@f+Zap}HsE-8qc9zSZv=`%?5Fevh8BUY zseoPYd45E1h4TKHH1wd$RUrIt>8Nd}pIKB0tZNg4>J z8sH>yQj2WRGat->@!{*l+8a4U#&6!?>BsS;%YG`_KhAq&6r`hIE$moM_7#J&%RBIf z7X(r1!xyM8h6KVuFGPa)Q1H`#@=K%hL`;ZD~ryWq-k*`bqp)Hnn`sKx{=eJOxSdNA%+tOc(UAMytym&#JU-H zb0QFK#PsQrR~LB47rVgvx2(HXS?q}l@H};s@ugfZ1pF`=%LO7<0ZMEnERLQ+CloTB zT@R!}Ci&|W+_Y;CzH{+Nrl=}I`^kreSg3(cvSg+=oP#tv3<6&7_eC8*a)vyni{hM` zL1Z=sK0(cUYwfPOKWCs;f&X+#-Mt)sE3b)#afOC10ad8@LN1`q`Gv5HP<}QJjB#9U zn>y5Fi@T+!c63}}yVP=&)$>f0Krn2~%HmBBN262-ph)jIkfj5R3tjIAfToY1hGli3_t!;?e!#?eS7Ovo$$E1S$>2kZhfSS4 zpOcIfazh75BxB>J44Et^|MVESWkLwi!UY8dv0xK+8o0Pk0YI?f`no@P-4_&_QwEXB zn#*+Uv?&>_x|H-kSuf@`|iQphN`!E-jsSa)A!8IX2Cd702 z>aMjw!T;P!ABav5E2X3~$vP%)|L*g;jSa9&*EJnx;WeKb~Jhh1Go(@Bkd z-Jt`^2XQOW&UbaIo&NgruAhmu8D-+Ss7Ii|03bP8*@u1fR%hY2#Lc&kl5RtszI*II zf|F{8C+BrNLQdxNf}5Pqp9oa<1aEb3rxdT319wi{ezLX=ASpN_eanCbP!&`3V|NwR z9ICj+V;1=kJt*C1a1}*q_($|m8J(mm7Hnv5(!NLkkNcO`3L5m?FgJPd%MC+J)fBpI zR59oYhCaaO!c%Aoh*c3VRQ`DMu9Nrr(!{M{&imH_RBs^?=95d{-tmQ9z zc!VYU5gkj6O#0m=^1zr-fqbF6-(y3{`98Oj8Cfh^p(8vVf17Ga76;Fe$OvU3=5p0_ zK5cD*35k9g_^gCc^&9rAy<9i41AY)e-McJD`m98U);#6rCi#(OlmN=`kSZ#$c;-$p zX!_=A4*|<77W{USjG0>qhX@x;*`0Ur(0h09LP{X|?x@`2iSdJG8ow>tAtoD4F2ChO zu1m$=i&uYNr~#4afApm93~b-8Q))sC;CTe#Dg};WMr7v@Q$B>aOS@6SQ?cB5{?+|< za-AiavhLU-z(T@=uKapQabd9+Gp3bpC15>byk1P(t&Gzki4Wt$! zmKg9(hi~8;ZOeOlfPfZ|@#}q!YXeFQC#2~f=THtWF$HLgNg?>v*UH~v;?3%uZR-zH zgIG{Omfh4&eh0GyBkR1gURN7Cu5P-aJzmGxgc|Uh1s;Cupka(Ush(a9+dQpe_U=)0 z)?3={Un8TG?>aYrLV4re=X8Uwf1h&OUELI!*;q-$y!Co|`@0OwZU=f$lRP(FVykSk zf~WHpFs8o0B)^E75^S_8Br+&(`YYZFg`E{FQGv3vtE!>BX?V~4Rz6gdIbt4WMe8@; ze=~gXQxig`Uqd*Fay-m==YU8lfCSO^mk8C@rEPiFnz%w>h#6)Wm<0l_am9cjKroN< z^mJbkTQr15M)TX~ibbnXS?{Qywf^}l+;cAnx1y8tB-)%wndwS@_K7-4q6x&YBr`lR~xJ&$UJD|4OHt6uIG3A%g*7UR2uez!^C2DYk7I&H__pd8S z9N9yDh>VfZKz2JEfQ!I!$X)AfxYRcLMb)!&w^+A4*GG^tEEx39`&BH6xa`vp5a$BI-3E(Gq8dZ<@FQQ{g3y; z(?tx{>bwg)iifzWpbU0no1fi_!6KBWRPm;S(dKG=ZbO7_)j5tG-;Ar@-a#YuqW+l- zO_n*8%aV}1qi<&A%Hivwc#7o-X}>fYk+AhPfw2Yjsuuv##^kN)9FIC9Z@!EU>LJEY3g2ryZ6kD`DdmTM-fpyo zll#s>bTHlo2Tv@K2ulv^&3heEy|7{L?lppJ}GXAnZ5tj}%ZuROU3E$q-b zftMzAz*Z?vV&`L3wViFtsq<6CljpDF*Clf%i+IQ74}woCc6zJ)F`)eaS>QC`5gIZn zG*MKH45wGOPgkbDvRvj>caSv1i7^DQ;EB;9iMX@Eb0)Rz-Vs^d+SfZQj-T4uIsV?T z|ISh4PDO6qE-*P za+}TFwJIMzahWU-s1d}bf@^Vjk(?;{mxD444+330z#@Fgw_;WOPnQ6 z9Y_1M`gU#A)T`3no~Y_owqkP#k>tYei#4$Ta1Ds+pVw=i?%XW=o5Us;Qk>NAeMdCs z4dDbO!ay`UM^>=Cxxq}qjK3zvT0^+c^X_+bA!{Wo$tF^ zp-Ub6qhco$X&RI~X6)DBRl1FqyPaS7l=bd8YgZ_(#wi#n!+ctiz0f!EC=d5UCQl_d zoEc{mmx8>0WC3OmZU=FYH8mTV!y0OaQ{Yxei%X+Za>v1%gY z?lfL2(>S6CFiOaag4HRX<@n}#8yu()1q@yPVJaQc1p&O3!HxtY^T7-6m+ZE%JK3Pes&mbsuy6Q=-ddgMZGLxHrSomHR=TBlSGZ$y5mK$p7~JAq zR?P@t8WyFBnvMhAExiA&&~%itLZD<)Hg7x|(2wjp8C+&FO}wuK6w;@;7JfRJQ>UkJ z+h{*v)oY@;OTZdK67R?75Iv)-HGW z?4b+-?yd`er<~*_IyRpp#!fIFmnq$%+^3R!dhnWuFTx5&;+)!-}pM>-^ zGqSdZhB!t*z}|!QBumgO|HOW!IBgb+n!0H5K)yp0BjU=~zWp!}z?llAXycS8_fXLA zSMS0eRgu-%nrA}3%PtfS*0^l2!UwGxF*a3JrTdojg%|i0+A{Hrz8>yaK(BUiSx5wv zK?s3Z|IC&Rzk`>E)ZLat5WwkQ;>)*4^cni8+twJujG^JO0{if}gu zc7F>v&5kEolqiR15W8G5D|EQq@Odz$Ms5mrb+jh7D$DT$;st^1mLwq`cjAIw`)kpC zz9r?L8GIUu4sp08Z#q~bjDXSY0xX_NLZ&P-jQq|74t#zl!M0^h>n<^G#Gm5?yzFIY zsfj#aQ2*Z`?g#wUl!G(m)6gUnsQ`Jzi26S!)UZX6gAxa|*z`ZrcAHaeJA!!gmW@cx zN~KF?K2RBH>vvjQ(H+(_6mD7eodkp?zV*w6PUBl1Mr3cTxy@qk#I+BK91lUZ%8Fbk z8S!%F3Oy$)+;f6M;YalnL)MwH6oPA?V#78tW-p%-yKh&P^;_&GzEOv}i)9$$c0XbS z@z~{MnEBqFp&x<%TN#-4N3e1Z*5y|EoQI_1EfgN)eL6{oy~dT`1DMQ3++T`SL<`W5W zqiu;xVnu~x7m8PO7lxI;AfN^_9eUql=+B+BQx&y_&c}p9$!7;w7I;)7r@=;FRh=x* z3a`nbvy8fq4m@z1vE<+Spq7d4e4#o>9vkn2nhNJ`i88*pvY^l7wF?|mkc1Gw8@W>q zx}}+f1ea+!yRH`D&iJ;}`+kl>A$SX}kB3RwkJc>sa6z4KKFdp@aZ3y?UUr=qR+8`g z0Uup`Wq>KWx8No^tKKz80p-X5EdE(Hg|#iCvon?4-dxmSNt66RY)49^`7L9~1}&(L z0cEKpV9nb1`{VJL(E0OJIxBC9bUa1`#N_`Gbroz;tzCQQ?(U&OI;3kz>6Y&9md>F> zLQ=YvP#P4ZL%N3U?rxC&<{Ulm_X}oUdq4B6weDKfYlC8eDIRT(ckd@AaBZdN+9e40 z3SHXF$UT$e$XiznqA0va_-2p9km6{hO&dc0Y09p$6cd;Ri$1nMW#ZzuUxOu8@4LsU zkO%NTHS=J%OfoDFw3?H+Bn!T}9o(sG5z<)D95u2YBOJ{X3wwNo4F;|`GcC8ZvLCxD zo|cq6G2ITf9tS$Z_^*p5KL>tDmd#NmHu4^n{-}14as@6{l4r&?r%Ns_!=X_d_mjvE z14081&r6;t7U~RmJlmF^1+#zNVGAH>zEx)178{Nxo;yu9auHZxXtYcIYCmdXCky_ScBXJ_1`aP&$HKISHs$CCObQ6ilNG)|2NfGNU z@+482rN*R|I`-k=;W1 zknof;{X8FqB(3bc!7as)?JY(Ead3OlVC(mcc(Z_=V>HsXbJXarS}t!4bo#pXd5VW> zm5>|tExRr*YG+M?i}LgHKQ|IDU=IvYiP>L$s(E8>fh?bv`9u3 zP$r1v`n7Cp&Wr%UQ>>KB-N;Jiji9X!?b^5}!MScnDe|$!xc24L#?5-lvVuH0gOo){ zpW(X{1XkmHolIxCo!bMXJc2P@osH&Vt+hr^{kl=cFuRRuGL}$WaIN$Bd7es(%xiRo zDVRqEcgy`xTdN9caJ<2Q1i3?)|1~Epq;Z&JVj^QU(S>v0wC?r}n<69q_MFqR`6d~$ ztB-%7nvDsY+S*zM(?3m1(x$=#BsHYb=~det=5~R&b7C^MO|jf zN>6`je-ZUQ>zvFt!sWxv5hzu*lLW%b2kTr6QA92*d9Ap39a%MDt; z{={&QSx|QHyTEKuN3&w2aND;UX@PWlgQ4EaHTATdwi`lGZ}}mk*yFww9fYdml^fn1$>I> zY$nZq%uLks&Iw?+hR6K|I3&z4$N$y0w;Xm&1!c0jA97rmxFCVWs`DoK@HY~^F#BzN zx$~87@^}~HQgRRM!qlE!mOWM2d)#a|JYLf)CM*wt5Uy@gZzqUl#b?e=RdVC$^15wF zvM*X`^m90qmNAyNLMOwMs^2rOrHBl@_j?Q)WqRdNLTHL8D7lhWx`~3jJ$hqzeQ0H039edYAG zx66UI!BoFjW9ih;2ZWptx}(s4Pv$uzf;s>8?`QLm2+-+VdD2Vy)WGs;f0C%_=o1M~ zq&A@h5(zqCW!c@e)5{y;fOP%@v6H=hz}ZnO2an$U%DSg#@Sg1OlqSaF)18brEh>@? zA`kDVQvWevywZgnBT6a}Zq(PEhyZ0-snL2w|KyxhUFcir(*uRi+ArTrBHhi1bmN~F zgWuYM&slA~yW{xzWs~U)VPe=iMv_$p4$4Y$;lXEWB!6Zgmah+Qw=!76 zVT??BLNpVySyAY2JuHYj1~d0eUINGXV+r9preYq3Jc;tSzcO8fRS~^xA=w!EMKi?E zp?U3YAAX24h`TT!XdU*;zm~GPvYaAf28JQOUb*5fa0bA_rYd>|?>Pe9U6Ny>#_KqzrjFk!yEJfp@v17< z|Aypt^fjdEowo_~G#IFYpPDc@DPjHawVUd){1J_gN+yZ_(ZRNOp zf>qNvGg|S#>;AQvH@h40E3`F$0u>zg85?LPBTy_$251D{!Rrk^FBU#4)Y!J4V1QTR zAry!p8<<);NhAysk-bS(@w(Tpp!7M>!_&r1ml_|?IYL(f&_W5C$=%ds;QaGCfqxa^ zY|;Hwj>^N)%ZtwyuAWJ~D~f`9ev8H$^xvJp?HGOUIRepc<^3eGwPu&28lG;bOL8tb z+E$_Xxc(!!Lhq98$T|#F(8e4WK?5^V{}FXZP8h7qR1%3|cvKDiPbYHA%P| zD*m0(mq#@3t+d5w7>Ve1$%M8L&mo?*~}oeflu|EFyixg>O&@YI~W*5VHOoq_{l zF3IKfkk+Q&Iy%Hyd^ulz04hq*Rey^+wz;SCUX2R93_9;HIBgNX{Jqc9M^`W}b!tm? z;OROwC=0iY7xTH2=*NKb2|mw!pbCQ5mqIxT zuxlj;ZqYssedt?x`(xT}?e_}KHsoj>E28~zx28ES!0m45UMQ7gzFd;X_FPu#EegSw z1o8qf(*K=ecZ_3!n!NfJc`P`GmDD6i@JNIIaXqrvmK>RWU4e2De)xlQSo_np*IYF0 zy6_*UX?1_{otp0)woGRU@Y#Mu>;ATe{aO{bq%kzAJZ5YzkLm-W<|48BEz%`Kzi2ng+miz2o27io;41C{egs!rUAacv$L_mbR|<5?GVwD z1|kidY6Yes7p?_J(@DDWJ2^Yy&rWGbVq3mp89`H~oJ7hLeF|dpq+%nPOj4)+Bu9_n zjiZ-zd2!+X3iklQOf(|2>MU7vxa8V>Dt>o_1^_BhBIBwqP`mzyz>JALz&HMHwh%ly zA?3T@Dmf~$a#sxRBNx#44DW6V+j93a6>(Q$k;XW{~on)-n{a-|aSai;h=p z-1(ZgUIxrxLc`4GaLo5lo(gl-IEj(rP36$L*RtQ8TxF8EJmVc{G%VfoR|_HybLNyB zEGzw<()@%%@n1bF~Bq& zfMT=E4?pi9#;(rGYo>MVf&jPJ@Dmy_k`J$W=_MAfQn4R$ z+33Emec};E)ngak<=n&9e5*Nr{P98zjGRbc(~6jhLr>+WYbF`WI#f;DR3KGC9(*+3 z{Op+#l?T6p9|6~s&)6Xkdj_o?7iEl8NdFbM*1J*vYi7NMSn$Ew$^_=*S`AX%AQuMr zD~wT-i@|KcYTAz>gz<^t%u1;t0_BDh-)_MfL0 zpU7T2hVZ5vdF~X@T5SvpY01XQdGS%-!Olkw68o_jH+;$W0|Lgxs7lN>4@}KS3h>D_ z#)&1F&tT2&m*SAAgYw2W(I`NMEJ%D1aq^ol)U-*HjUu@Xm3ly6Y+Id9@ULDUAwS zVEDGPS5@o;Qj!~h|M$OK5SXD2vq-MVt31ossv2s~7i!Cg!BUHj9C3;E{%g520qxBp zzmJckTN$0Av(*O;*r`mW&Bu%e@wVM(B%sY?f&j>BKeZVXEH$Acu$Aq@?@f$Z_Y79P zh6POZh2XlcMZ@gBDD~c2Bu4Q32z){{QkEX{mm=%>GA)fwjaH`^b^YuL^O<@rq9cbI zH(p>jKIsQHwP)vcx(Q74R7JxoOh?vp&0x?P`6uVG4ppI>wUS(09z65a|4MkhDiiy+ z6Qh25b!?eT6S1vsRk0{*#vIR!qi=1i%`Pt!g9l+r6D@`2!9XTtSRVpGexuO9a5&%f zoP^Vs2jjiy)NeX*6rvM(=gx&hqxr3_pJEzoZ&Uo%AJNsz_Mq<~qk8xpuRr|=|<#IN33lxO7eeOqC9{bCfPhi4Jj*{T?am4z1UL&cmL zh10n^jmQS+mR7%Fes4zlfh(y~<-QOIveDMjIa>GuMiYApxJZ#gysCf&V8XKwJ3h~j zMPZx-F4!?v8MeA@4-yz-KCWA>2Jf{8KYB|YhasSuoksqhwy!3#8#Xg-`RTN#&%+-f zM0_@SXZN=Bu&H0-FwaD@1*|HPeX8u-E ziubt_Kf29?{S{ive^iWyosVo3Y4 z_Ygu!o_uMnPX?sTmJKiHVtd2n`Pq68KLUjIi)`MiJ2!Y;jo++O;bV9lEIJdavHJ-L z0Me`#$~(-NbiD|WK-nG&#rDMBWt~@(D_u*#uU}9JF0lb+(Y!*qy9*7;(@2`Zt5xh; zKf7+f=Q|Se*lD?6qgC}7?d;9+k5_Yf;Dix#RJ;D=7G6P;seStu9_%{A^v~6IgRppj zhlI|YLdOzK*WPG9Q$B>b5RBd!{Z{nS+Yoe_BusR+zH9Py@s1y4Lm?8>eifJI6xCgM z%Ix$KA(hqqzL-0xSe5P}j#SV(v7L8#$(@O_xc5*HNiroY;>(G$!Ki_(CWhBAr)9AG z1roOyO`!%?9B;UhB)+taI(%oG67UUfwm!oHSG;5t{pWHJfL<{Nq#LymB?^5g4bsvrY{}* zq!(I=;^RKAsZg72wre8bIR2}URaL|?#XlSuz(?YtpgfglqErSMm$3c3;m3Uv;EzL1 zLKRc6qO*vikTdsF5k)JJ972JaEnqf(K@dw6Sa+zemZB_X%Q`3EYCQr*2EWg?gYUq2 zZ^xrV%+o={Y*J?(e%%Ui9giUTKqid1%CaQ9o~Hiq9CiIYvLLI;T34NsV7c@)uSV9| z37S*QyOhQ{V9W2(zS%{)YBT{$>J=NO2&oBY0Xn0AbxsFWJFgm_B|03#Y%=}9Hz8Um z+nOvANL-q;Nn9WVdiyIuv zOOGYuQnQIWiLyYl0rV(k?+di3r@_4sF~2xGTwSe&s5B&R(2|y70Oj=NVC1lJ`DdWz z$FA1fUS3-=ZlAk$S=$XU*z*i4@9-jRyt|7oA-PjW=Q!^ z1FvfvqG=L)0Yu7rx4Vqh4hz1i{lh_fLdV|r=ZniCS@eQ1PRpZ$Naww#T!o(G1=(DA zVgrXy#WprwBa1&)&vp&+g1t{-uf#Pf7G*%+xqe7~CQo`3IJq;G>9vsNWX-y7 z-IZc(=rwZvN{2Pd8HBuU>S0qw9TFIfw4PW`irG0cO@w(Fezi6(^m+Mnk~BQ3GwWw~ zq3A3`9t=>~)+HVd$YHBXU5gpqn$ha!dE?c-Ak%Xew9kQx`_7u#^bG)%0(C7oY)krA zGI1b+Z;JoEvd+6zwBIQsXzg=t=3gWbL`m5=$jbMjYm=o5jd{qBkvf@6xQx#VuSH0K@?$y3caTi)pGiOCSWyv3mx$OVsCZIX7ORv3 zS;ScSA&6gQKUQN29DbOz9%(}MZt59`U3296=|@R@iHQI@ljVJ53JsU7Y#DIyeHNmi1tdnmHWQ2*_F1GO0a{2vyv;IVw35bWX*&5#mO)$d%41csHc8wdP@4OJyL^Tu?d z^jleJa7rNS{qQ?JeK|wgb6$CIIVq@!kh0D6zlo623$g3gtnH_cBS#OPL=DSg@FYi4 zDWzbkm~Y!!Qky0W#?X5I`)dL?P}WMO=LPy>Ilk@_W0fsHS`5FBV?AEQ)3Dgsu+R!f zn1hm)m&e(3QR~5w8IDr)MZ$ieSL@zXF$iAJ(sZ*t7#goWVs>R4q~1}tR)8FYDCW*AAGY}P(y zqr)lTq^Y6B4oTJCh;rvsh0}fMv(C0HNO*~{+xB#|rijl=JMFr}Opv-fR?x2x;VZ}h z=|NfzCMegwfIjrr3I6Y}VVmH+E|Z?^d;dlYn~C~4tV_+#4XBHcnKFlgqWzt^ja^Mo zvh?^#m8j)>=MVzt$;kU1IVxKK&T)P{@%uxUS;=im{7Hp2zHNqCJj=%bP|SBo@|!*6 zQDPp?Q4-$G?87nvY6%&ViT<9=FON9Yrx}6Ae8M)Hd%n9bYqR{%7EisIM;E40qP%hz zRuKkpu8qf)s7E<$=t>yN_@9tHmjd#mhx77N2ag>A=_D z^Jv!9Th;*c7u2iJQ~MwDShRoZs(<6R%4fT(gM&;f#hIY9(2w$s8Jt?`g6DIW0?6J{ zU6w6Dhwg{Z%~WH-$Jc@o9#l|JwVNx>gucMhjp&z~GwH{GfEOl9niLkZW|4j+saQGT zDYGyShC3-~?3P(%3^oKP4cN1WwLryULL z?av!lGtfjMZFCNx2QQ1#$zRnDDN9!#HV@LSj!R;Bu}h#X2@9IGh4X~Rk(Sh$z#`$R zr*p*wBPXHTrPMNm@=EHpM-5={EWn%NHCb!H)^+ z^1yb^_UhBAZq-Mzt4~zMKE@waZTZ=f$`?g8-}8zp=6~r*!qwBk&#Njge2?u)pFEJM zOs1_|QBk%I*!1f|O6gm!#NGE$&x4A@G{&1Or6_9DI&+SZO8wvD2-n{g2NF#L!2;%9 z4859P+wMx*%Q@SAm2u-zJ0|lK1BQGVN;CKZnv1DycfL8T5~T`(X+UhS#=KebL_)^E zf~5)dDwvVjFj#B3qkZ7Iy=xHHduZPk^SferUoL5WTo# zMrGUZ*Cf*ad|9KGl1m_aZ5;r_kMyqiefDuK2?>Rs4Yq(Ig^HyDc9isW1wzOu0?3+l z7y{GiU;hC(I5UU=mQI8V=b#yhLmD@FxB8I$ttuqP>i%lKO2pS+w&QYUOEArSG9tiN~{6^B6u{Ch* zJWTs+pLnsP%EKRDyEC*Sywn{2mzg>iM5cejg!+uO*HRs3@`CO&Zbi;YcdA}1*;BD4 zzfU01fEA5h?4Is@6>%KQGIa4FS>>UJ>hx2|vP zWi3-i?W#)Tki-hJBf zc)f*%PxE?W11aXKuU~^NqS}>&Hi*|An`>yVhfETjvym!3K1ohOG~&Ds7<1$2`y7CKCeQu@lO<7o0FetxDRJa!NbLi>JQnU2m zvv-3{6mYuq21z+P@OX@RP3~ln~gjKI|xt3_|Xh1)peVxC6)q(p0JGYJ2K&2eY0d1_jp1_g*NN;>e$0_ z`MoZD_*?ieVtKxoU%Q1fws{eLP|E-#!m44~jk)dw#UrWAbGzyz6wrbSK(ntK6kl+s>Snf^bw4k@m|MMzP8iyc;18@tc}!VY{hsf^Oq(3 ze#JxSdOnP>yBQS;INtwDFjXuu*k)EbG=a=*@_bpYLWoR)WK@TIT4V&k!>*qQPs(!& zZH)ZrcS)!d1%1fE-9}+ZX9DV-_J@v-?xr-k_KlG?AY#!ePFD zt1T=n;g2^CUj9CvieT)-`EA5>22-N~@xy)bE&4X7Fr`662C>b+C;hEa5LbR+7Su`r zoq+rsGw*+a3nG%3qG>RQw1#~TE%soN`w|F{Eotaz$&>0WZL##y#@en>cgfW!%!Qfk z)DNgX_qcI5tUM>@&LRE+wI1hCDj@U@6W-SD)FXV6C?8)!T+QKr*l$h|W7PNp4~hRk zDrkPW!-hu09+IoBV|>1Kd7A6CvK_1A{9r$DZ_1>rownQ4uJayD*cvL21BBg0{{`gI z=ESp0(DR8MdSk(&4}Hy+FNcUcVU(P>$xM7^uXy{-X!AGY-3 z$y?8*`hy~dw0J7gfaBzf(?Cuv>^7-CTHq3&`-oZducrKTO1+He9AHWbcW0SBv8iSg zalP}b$WAB-Kl65(7sHy1q`_uVZ-MG3|FYTq{oTt4X$(&co8c)h>rXRXluH@MW~(r+ z4&fxf3f&|KB$~HliYnWmkEvY}Y{?eoLcj6lPlw0BV3Y2-DDRJRJ^4D1u?6?nrjo(@ z)z&W5mCv)=drN^vRFk5}MKGGC_e-*u4AC8{2&i2ur-_TXO#59Yd6zn~Gd!#_n?wy& zbSy^)9fLaLXQtT$QJQ+E_#6ZTA@#e%O7idxFoB3Hk-w74AZ~kd=_Z)ML)o*&1}$HE zA2>LhaS-0^Zt0tr6=#JdAm00~PWa_+i9AJ#oKIbb{QWB*>k+cgH`a{bj`AN(Q9WJe zyxRpeyoV3ym=r?Nuk9+3ndSv>67!(f&4x%84{>@K@hiXc7G(bTGxkG`*ZStLyo3$c zBxIV7$7^)i9O&{91>sGxRtT&4w5LRlllDs#*$c9;B5&F-y4NsTlpUEI2I0$1v(0B9 z%GHnAAE(wU3L_BXJnuo2|9>8_toF5pm!Ri1x!iEdL?W#aY}-%|qgj|}&0UK~Gi*S^ z72}Y*u~|&P;SHx}6|pT_8`((9Q=xu~_rpbcfrkKpeM$lSG5H=Z4WpL)7#IL#2?8-& z78C@5s;N8)n`~$9ybZc?7+c$RzZaR3jO@h;s5;v#e8|T8lE@@OGQ!AhFuj=m+COl~ zj21ZA5gHCyFW~<7qIoFqX81sz-CWYr7zZDN(7~y^w&dtci45l4tw~C%{kYlNeEi%J zbOl(`J}6(`7=6E}drXv2Y~OaS5@&a*mcg2x(Ue*3kslEPWG*Zx)<;Dahz7n%5|?Lk z+SVdvc@;QzG^ocduby(S5}4cRUqKAlqTI{lXHooQpf{leCHdQR}xab1F8owEK}4}ZvCAhaG!=n*1ShIi@N z?Fyp$H0rH7!Wo?mc$3zZWG>Z!7Cv)??qD{a$oTh5>O(KoAu1Bm-~67>O$)Qb1`N;R1O9=$!m@s4JuDg{!)r z3G1R*w}0bXD9P$|F|_!9^(lb<8C<+was`;rP8}j&t}lXi$q7qY%>Vc8>kw}%RNM;> zn>_SClpP|%I1E($te_rxj|ao&;2mj=wOpvz&5OZEXm4ydrCkv;?lCM6k|Wkvh~wil z@>2X*c%%u7GpfXm;c^&1^UudXmMwjh#APkmHtgu$U_y_l@W| zK~$gg^~Y{(t&e<~w&rO0&i7-iouUy1yj5$3F93zmG!;W5um^S1tI*BgZfARJOy~F{1XU-_;}x_$jXYKstPDhOIQAK-IyUnWFC*`=&4O|yd3J2NSZOy~kuG%q=s#V-JLWKelV!V(i(-7U-^HQft;_jXr^_CuJEyG`h!e9t7(J*65sQe z#xMbxLZdlSRHbni=(R_H8kG6Y8tTTFqDL`|c})+w4;5~A3Bg`lDCy)LD{P87E~>#=u^Bemh9MCDwaXRoGQ3}U;VNsF-J^KrvK;0bL>7#m)_s2Fn zcDMSURw*8$Bv!@j_pt7qCKpKX>b0kEv$*P-vni&(NW(t+G)uM0+++^on7q_AJz1)Y zI9%;yxrF67Z#V4;@-PC%R*o}*qCzw1G>k7PWZ|he2|mC}I7CSH+bXM*n=w)d26RBU zQndpW6^C>x^)YN+Bmw{QGRWT#w=x*fzcGcx3%Cw;(rZrxBtp~{_ zc%P^Ef-d8g=#`E{qZR%?4`*wlhK;Hgf{EduSNfH!`4aq8n19mpX3z5ziQX(> zJU`LBP&IpgsIh?**Bw)&d9}6K=b^|din6&I&dhb4D^?LOStwSfz8^>$n^ z$=?qPi=86^06AXBh}F&ar_#oq-n>k(X|SRsVUB;c<5cHYdV>!{LrS!|JED57&u>JB ztbDhc5<0gU5a#!77Bx6JyZVvjUOg*~o^0x}wqHfWpu4F7fNRWXGnsmtYP||l;gxyM z@Jt2#>%usu%?;RgQegG$gNqhM?}lh;&+t*o@`9J`7c?Z1rDBvUS4O3U?nx2))qZ3OXC-xgF$<#?18tHZHJXHKiN6 ztl3u(J$8Tsc||w_HA@j3R}Q0B=uMi80e?Xo+f^>FiC>1d?=?0QewjC&6nCa98h4q= zNlVpLX=y9dZPc&7+KXP$T5H3Cvw2>>RIF-#NedQj^1Ehn-9jL6<#e{Fh%oD@}2HPs<7NTOnq1YxLBm9@>-+oq8aG^H0 zRaC1cJ-Oij=00jOy?#E-*SBT6!&6$?9uDF5gQ9vL-8a zwflCF4d^Z+)a~I31!#b=3-VFpKbMhsp%FTnek zI|N^+WANGE`xcm5m<}`!{A|Jys3Wpt>`Rp3pdqkMhprXD)&=0vIgWqUAA1dzDK_dyAguQz`Z{g)f zGvzYFF-6VK_MTw2KX|k`FC#*IZ{a&5CV=Ls-Q7wknhtUhMO5arAlL2fRUdtmpV?1; zLjUnX9=dc0H9NFoe?YOsVYSV7ex$wWcYSgKLVd#@jDT8;80BL;+$gWI7he9mrM(|) zSqF#q-?iQY!1U9M#oqOrTF=uKT*4SXVlQ{-`VHcZ10N^?h6f-xOoRz!ku?E#3UhVe z{aDZ&`CA_h6TXy4x+p)U^17gpkU4yj6vjh+K1#M@xx^C}R1e%szdLBDn;L^UF1IWI z$5wy*j>ri3F_xhe7?Zrv4mjKSYNoub%#xJ75v(ny3}6@GC~&j;Rq?pf2Z6aC>K zA!mGn-IbhD7SZ#op^*RBBXB?xK(8M&Qu(cBna?mpi!Jqo3>n_J?mb*j+XBVsPQk5t zB9kccMjTEHSN1m(=Qe?3ROnK2`MRu_fTbEJJB8^)Zq#OuaD=ELY_$`ksaV&nY}t-& zYvMu626Le^ncwV&kBqS96!(P;7DD)+yHhon)Am)L0d458Wp4+04s^n;8(;9lHg#Hs!ywG~efE*q6OV7zn0pVxP7Mu^q4=^6{-gNY7wbtdXK zV%mv(PLccyxE?A%02e7{Bo2PqZ!aCb9oY>m!51X&U>4v|{snEPD%jiB{CP^K{I+0d z{R!kQ0+VR4<@*FJ*8#W@iL6=#ktHhR{GM~Jk~dCs)iB<0q4H*{7hN-}1YnhTcN1l4 zXQg1;@yq?RL6g;$P+nbaZNA!Ij?-yQ=aSCk5^^u{e3e#-#`1ku5?FY{xHxsaG*AKd zmMPS+S#(48aQAq3eZ6S*)@Sn=%ccFWr{@r1AkRd5Be`cd+>+Y_7M=$83$G}~LS3BI zE%mTU_{{M1^@){$>Eqo>)!$(i(stBRH`eq!#lnvu5|&#T%l{`l2#cPs5IOwYkZc@f zkBn7%Ul&v)LczBWfTi=_VtVKld!DW>wGpr8((`$C$&HE^@LWgJlEnDX{t9}RHtu#vA z<@2g(+}A4Tq-Y4j@7D zZ4NyUMSNPMp=i9#a#Qs;knIcbZiT0aGDLQg|JZDsR4cOgBDgnA0I9Jy%F0uDrPZ>XxRvZ4Y`(J%WQyR%9?n!m9ndH4KZA-J@}5 zV?1rWb)M79ZMo%VR6*ru6v7L^`-%SxAQ3BNrR&|vDU9KVRTr5Mnl(~IL^|p?`tXCC zHT!hcX7Z6QHF+!u09m2~{PpF@^wwnsLh)2m`NTN=$c!UOs5b-Y`d1Za~Th z8w%2ct-6NM2HZHX+Zt+aIiBx%Jt6y04b~tv9*qn=UddPr9YPZzu+H|pc*LLu9{Cp> z;i+FoNYJ*G6@(&<-Qaofn}-hH?Bw9!D+Pmx0cf@wH0d9biGW7b6ww!fCKh}!(DyC{ zB{*>7vzn&QC1w^5Ncuy_+K@`PaYUkxadGgVMQmfuG8%Za%Ts(i8^CxuqopE<1V{a+ z_#7WULyy^-C>ipyToO8A)%@ecHxJViCN{P#-@VZAhnp~Ox3$E&=Vt=-Iv@>S%H8Xq zp{^ER&r%MJqvD%S4yaVb9}_<&W2RdosLc+Bp9Y`doI}0c#}nU3pwiac)77{5(sMb( zP}JizxV`8}_xCs&{|72MfMvG8pdc+MvA;(`X02tJx4$DPXh1vHu#N zTXPLkdasBT3hu?qV0?AFEAE27xDB1K?ZNhjDDCMHaTG& z+LJc)YLGIL!W}L$+gT7XASD1=M8pN$xB8X&yvA+u{pLPEO@nm$hPo2ozu0KDxewxK zl4IdOv2W^vhp*X;+E9f~s`ytq{U+8y>B%Vf_gOMA(y$`Vl*29c*m5)()e8iXVUl`j zW)13kdTzhhqoA8KIiSkFAjn_;#6p?w;DtRKJ5uY6Ma zlIypl*FP_bhea;d80=-H2EXDL0Wk{W3m@=RR%*We*jLa;?lFafzzq%y?RF|lnx|QOoX0Gn&6q~W)BT-wa z*we)W5E{<($31f1N6FKoDx(JWhNXUYvY%b`O;P0est&TuKp{{QY)5G`j0%P>>_bpZ z=Z}96&1DayLq(*oUqPmN7`n|5R}s9v`X}U|wh*=nosai*(EWVCB=6+d$8#OwVQ?Xn zeii-+Lk+~A&kag|7GS8Zcr3>tF_VNsM!d51>=OGUDvBj;GmmXnPDFBLu%6yriLyfptA|b@5gMT?9`2a-+ReWYH-%L|ERM z+n3YXW`;)o*RrPK6C_f&AdFx{iPZeiUD*-~9&0JABCH6BZ}h&oZdkcUcNIW4iaa1A z6?<~bH6wDW@Bh=pgzLkXF~XOKa6_Vs~3SV_xU@8QoY5Ca^_!(&W`F z;BLg5TX);pR8&R3JAS~ISh8>J!J9)A3k-gnBf&z?b44&-nxv1vlgE}8O!Z+MeYXjq zarsXwH-ot7h+XSyl9E9{?EV^S+e~ZjR9L{P^n<4LN9II@FVS%No0oUxTO_E61sG)f zPPO-&QV!40yHqBA0YR6N`NeN3>#Yw?$52L`l}?SI?4N!ei4nYPxB;anEDww;74?kY z{*Mh^5Fn&x+8{?lA+$Sa)nvl>LHTdPwzqLP%7Vs>zkmWJbZyq;wRIfnt#E07aF#1t ztB1SA(zvZ)f$DqbP{HB%QvB)|PaXZjVC?*>S&oR6+y}FhMQNL{+~cRv! z{b_iQVK7uOW&=WNG$GKtVSZ0H^q$5)7~WzS!@qcdR~ZhFgh~Dj?j#|6MomFcQ4uys zynZK4kH`;dqgBNGo2DE6}CHl%G)kgYupz~w<*+GVa2v>OVPIt6# z2X4h4S?dx0)3S}VKMM8qOiY+(B&B^3!rVu8&660s2t)cn$>lg#y%KmYZE>#4isPd26=| z=`i5*3v}bvRU`YS;*2|sBQuuOaUlc}f!&Sc7O?~n zK|gj(&uZYVQ@`tgAW|H;5+I~xg;1V+TVnc=j|t0t3J3?NTVY-mIpPH_|7mK4&s8mkxzIt8J#H9^-pl}&sYi*;xr7w=M`8zjaBj(upNs$(2)O( zy>P6hc1ah~Ukpn@%{B9xYOspW3@LINQOdS~2uT;O3m)T-h%MIT;e~d$HhYH(9fDH| zdN)kreLVRRDw4?*`-u!}G;$Xl5=%bQj-wL15ci1dyS>$XE9jNVT&dAxRDAd9dl&U+ zQo;M7A#|f>%PPY5vlhI9OKikHHK%-jRs8Jg^Uqg@7;|c#h0trVq_XlR3SsE&R09s| zOrQz505yEA@sZpjm81xhmIybHA&SHLg=I#4$)bb}##FD7=EX-lOPR!s}3%0+g^4}&YYe2#G6nbYEiv2a3+|Ep6+AV5E-1wh`~jt z92HDQwL2pqz+`hEIAc$aD!7G<1Fwexe>UEG4ooP2P>sS<#W1o8z9HIm=^8~^2csZ; zG2##kLP7v~iP#3Sh<|YXF`s|jr1lMQ8-Lt5eE)6s;H)kO&xR8Qd1;{B`(Nz%7&a;* zgn!?$8oyG|W`%!Vkgt{E)E2~pL7i~+N89;|oN1AUc_xF+l003$S@}!LGt|QdpDQor zroisjy~*%kyEEp}@)EQ6M&9+Sh`kV1z>ZP>x=F**%@L34TWuZKg}qz6rsb1(=$R?& zW~i^lg1&6fL-V^@6pU`LW3kE;yyK|oG4@?r*>}Waq>GO%wHvjpoNyhQ_K794z|XV! zA{JnS9@;ZYogtR(tw9ST^VgWj;eT!ne}?wEnWwR~3q@s3wOt6Co0<-voQcn2_dbs` zh$YvsB89&Hi!zC#i2I@D1wsrS4^jF3S`pTy_tNwC3YJ-`!qb-9b$TKrKo->`?}HTH zN!@KOJ$+B&lo=jFY^f2FGE;kEN;?W0aN7y=Q^!7t!0M!L#mWDuwZq~Rk#H)JbyLze z(iX5UtTg9ih}W!vPSfz#Jfwws(up8T@{G@XCwHX>K5@fiM(mB#CuviZbt&$|&n zANZm&TCO?+r5UuRdaeI)3y4=qQ<}0s9YGaC-B&ZI_*L zldD^gMVV4(YjvlfuXUqByJ-f`$F~psixfaD?Q1^~aAMGRv%q`V^PI(KP+K7nnK~du zM|1LL7U_8MFWu|(#h$4o&uS>yk zYKH1IObDgz>uUkmwf(Fqyu-C_6GhdhhdPMCf5*kjYTJ9!dDGQ4s394yrWp6*Cmd9{ znd#ZFJaHhQcbk$`u6`cWgkZ8mDWmP*uR$pGgPD-*0 zctlszg9lLhb;G;aYWm74e>6i_92?ow-ve}aPwA{OM~FN%Rj&8bef#2zB75T+to)t1 z0-lZ*`c31qDQ(cp*RKlwhx1768I4phoKA3}cvG;2sh&R&w_(P-z7>>9vIA^b39V$8 zrj(tzeOpTdi@Ne=(jILllFCe!!h>M{93^C<;PbqvOb~K^!N(&2wj-R>=z8*ed*JW$ zzQpyV7&(!t^)UCrLIr`e6gK19S}Lk2_%SkB#qZ= zQM1tGXSOhFqWrSsP}8cgAbVNXF82&fA)DOw7^QkS>$lPd6g!FZN7s>-rlAXF1RIiX zS9SifXd_M8-A>;K?Z4-?ocdw#E!_d6q)(YxYp`TQSG zUl|rf|NXtx(v8H@0@5YjEG;69#FBz^Bi$?w0xBg9(hVZrEv2*B~q19cN+YJl~9v67A_yohrq1 zm^tA9qi2e$i{+5n1va*wo!x6#m!CDhAV3y0@sHk~;+ouAj+pMGr@4=0Tc?=N2GN)0r)+*ddzq!4PSyq75uFw=wgyxX+|raj2rPW zWe_A|P~YR#Qu9yCSVEeVoQ?#o9bHj6JI~Yza)((d>)q>fZ%B{ z7rU&KiNk+09SgM!vmr=@&~;b@&XH8ehJMHU=Q8&dr?OJPZ|MbQYA zW~eD|dz=yl&&H z-Hvp%XipUAwkz!>S*};c3%oib zCs`MB_v;-)G{}en(D45Wh%RbRs|iL(>p+h7VuYxNVOSop1>j1ZA4r{4NT!TabVR}F z?Lq=?cpx8ZYilDIB&Am?O(0|Pzzj?6vEo-{wE@&SyZcQQPpPfi>#tkGH|VFuY*%8J zfj1*;7k53%p6rDe8Dw{aFGr+KYb8C6sY$mAp@~1hJ>S-pz*Kl8_qGaN*ygQl`yO1Y zGjzD%VCcVilPJZ9qs!ATnII35%105`-ZatuKGD0O@vkKj&kY3Xu|EW{NmuF0auE@{ z`bi4^sJwu9I|XxSy*@Q_l4r7ITML@3!9I9T?6!`(y6i6IyUK_A^w@lNdHc{3lTOvN z_Om~TFXP~D!Uczo!<6%GIJo_Qv(lQ&4kk4(@KP3~Ac=6`%ORshfY1yfzN9*ni{M(Z zwG`sEq_6!!N28 zX4<90MvN7j0@Lf3&+J}Rlc%^G7Fb?zS%#A{Vp{l1us+~2-RRz{NscZ&EtAxWoMyYX zp7leNBBXP4Ro+i*reHgdcno;XMk-O!r^Yp4VkK#l2+5npn=OekIne~$q^vr3i|Z(5PRA(<#igz~Uh)g;8MedQW=>X~4#Le4` z36JQ*HL3ayIMmxnlF=7((+JH~J;`Zl(^x`Xvs5YT(-@s^NF#28@crk?LZJq!4FkH< z=FT|l#qm{ntJ+&Yu%#)%2Xy6sU;fyiVrUu}})_+OJ!fwYZd!~44?mM@OGFr>_ z&pPegSkyqmy+k^3*vM>*NI5jI037I|Sf4{$Tr8r`9mcaqL|q=V=xaw{qPTq{6eg_mg^!5X;dJ6Fw3ZjXqG;9#cx0wl0@!mFaJKmvqSM^3pTpZlwBb{jhZV@4 zhT;2EcOI&KYM+nqoAv}hp#MAM@KU(^nlIcn60bq57(Gai`@-t!PC}$isf z-H1%?Jt1A6l$(bhf7v)O^@ZkO%_G`yy)SV%?u{UxNPO+9YAOnT8V_aiC;j!X=&?p>SDzGaPfNA&-F z2_Gz@VV`x;Xuhk8%3!x1)~<`+?|dP*ubfuraBaQl~Ce zexzW1j_&x}|N2>lK-f<0&l;x4^1r|eHgOT(wGHrEV88pvcF<~N|NJ4_v4lT=T)W+UR#CY04vSWjIe{-6 znw%M)=t%!L!^{^FMqtK;MF;r^Mua-mt=_gA!=WdG`=K1-Sxvpib+Pq9=fTTQ*>_MK z4Ww6>FQWTgE5CBBW|dE^kY7b#iI{?Fbu&fnmUPH(RI(}8+)e3|C>^K*}WzVY17r1?yx$=I_@(dy;o0serAldMDL z?YD}bF2cNMVA!X?5yEDJt%rKqHv!oIhV3Fg%l)4loEuYmQTnb78GPdMUo^1QxHj(g zmEIV*h6Z%g5~0c<06du#+ItNHgG2fSaauNV-s|h{kBysdB7{vNA5qn~h|Hp0EBb^f zsDM=4Uws-tU@CExtiYT-vDZ6&(vNawsx^u1AA3yGtvWF|TZtO;d|8L0jb7RrkYz68 z8gQRxF+N>Xuixd#I*TR?(<{AV=Fm?6S)CZoe5XpaQ3l<&EgxnSE`-K$A|(oW6XC`u z*QVmUnj4+1rN_`U`S%cH8@SH}y7UIXx}a)sf5GD%=ww&vdsDQ)k!hO9(u#a0m7OxG zFKZ_=LKc~4b!}+^s{s!^b1dKFaQyF27{#B~1{q!_4u~&|IWZA(lVU}r;)*N`tc7>s zq7(_Fa6vxiAukoOXGJ~wUOhb?=Q2KCR14s_n33V?*$yW*Rt5VEX}}kz0)cb8V2Wm= z0($c<@%Cl*1Id-mFo<~_T0va+r}T5%GPiI{`0`Qvjv!zXx7~&JP1KYxL4tCda{;!Cy zERKvq=9T~B*|XUm-Fm4h+5-ayH-&c>Fj+#e7(cXh2UmV4iF&>`*7KPy?JVOM{nO2w zkjpl;`_QK`140!sU!a7?<3f0yyV2f^hhh~Wf(phbS(|h%Q}k9i0~X3#j&4z@>v0=* za-ujzR)g0!LkXP)h)g!ZSH&}N35ePBYxX%rpza3#vsMCWIu3k>&r8G0R?sFFWSsJY zsRel4%TznwCFId-UkcG7O&xhxS>Sbj|Cceu^_c`>wYvvl)Eqy68U zC-qyl;E4)^*3P`0F5xq1r{In8dniHntPg97#+2=Bv|!umdT(R8qG8W@hU;?C{R!y> z#m1jB3NjiFK4WG_9ko1Vr@JkvJyMI8=$E~q z;4N%^_s3Xa&hPFpi5-Tq=zO``CvjSrmEigF<6XDu8fk#AXmIh%r$#Nft^+ghES>hG zmqKr<&mkM2vX^L3zmN&}nozU^2@{XNlV8uByL>q%apWn5v#S`me0$wJfL(I{mp%4k zX9bh;E|r!n9Z~a18jxd=g?8jX1#s|`p`%e8a43Wb8lCDxnOm`KW{5$-M7e`{k0Bj zVD!PH`B7-yZ165;+NP4i05 z>zAgg{3fDQbq-#%B3E{p*!# zva7fWb|2o0qSLPBchKQVAm36uIql-i#}eu$-$d;<+9!k0LkX1y)s)I;X|)OGDj<~K zCoOjprEwPgpSVkY_reLrP0iT`-pu>KFUz*QOTgbb(U-8qEuS$BFDv>?rOfft0|_19`qC7_WXO@=8yrQP!Ud2lWjlRXBHl{ ztcr%kBM;G~nVFew-F{LV%o;wvAIUG^AH+UNkMlazKZe=>dH1<~UqdV&Pn4v7KfU_) z^0(JktVKo-%Df}ncXYZ>;l6iwpXlVF(*|yP{kEyU2tjd8Q>onJ(H0X~V~3DxZ9rRpEwP0~&3b%h!->M^gSqNg7pcBWjEg z=!jP?RiBBS-C}ka#pznqmn`Zp0%VawCUX)+Xs#nd=R+3)3kM&B-rqv^*wp#6lS$#j zk9V=hy`h8=Cp1axP^VXh>|;Ei1tcl`0zULhuk+<6;+M%F_`4 z+IaPJ__ftn>M4Uzk9_%cnlu|#7?$&B`^b#-5UG6?U$zg%t5ru*FXQta_E8}wa64_n z5J!~gO7wesOj>FUn>dRJn%pTG+ja;t4Ex2Ojr+KO-RE{3bJkA`S_I#5gb-GcKSxe% zsf{$)L#(+YOV1dO-$wrLJ1?5OaQ9X%j&mE6;3Q6RZeK2qs@rJFGD7m z^J^=S_=Hdf!`w)*M#L$3DXebUukXhHfe?!~)BogI?&p2~IXfXQ-Vb_AM2I*IDXM<& zqGzABm+ZqRvsnQgi}$qhr}ksT!QJL0S<{>T;^(Kld7|#vdKNBr;=g(z8$e0F$^r)> z;jQSp_5T?+S0oJ(MKFYr?&aN*#Dp187B{F>Ef)Jayu(dEoCY2^|J@azfi# zpOV9Bi}0!lzBt*Ld|j)BXze(J_T1(q)r1~fa?}$s@l{Mv-9&_z&Fah$kqyS~-+L|{O z9RWIO5cGr=@kQcw@BQ~ys$N>!KaZ%?8P|8~dU`1)?ZUeo8o$fY@*;DrATxsLBgd_& z31ltuRG#OL>$o$%u`RX0dcoD8Wdi?|%B!Wj7*g&a5Q47X;b-}uDhzo&Yw5JBVbuP& z*WYlnfdxBHXVvY*sE2DGnB;&L{GDp&_cu>w?=JkX^(tr^mNH#3sunB-tnma@xfXJ@ zae{4HW8+J`e*u&(WFPyBNH~eoZ+6yv` z6*gNSelI;3ug*!Xj(5r=jGCcuPEE}J46(h~e2&PNbtxD}N?x%c}Om5q2uCOjz zlKAXkM9{0CM|u60ueB+_hNJRX?0I}cpiHmaY4ns-T+56_;G95b}Z%Mq7uyRX~X52p`+4p zSXahVYx#1(7HU~Baen3D&wRhWn)E*~On5Rd>`<-hf~IAHaw|>x&Y#q=64hkw6H<*t zWLR&Zg=?y}6MMLL8t;wR&Q~B=`|guGby;aC4gLENHS}8s?sFS^dxWMy!m!i(=9@Mk zy-lt172chg(!;@7jao5UXHAJ*fzR#ihPENNWUCY>J{B}Z7S^S!rdBmr-jttcoQNr3 zc7;EWOMHz);{IEXkkx0of^40qj=3;2XED0Zz(NrE}!&xo028Mk$ znRTI|(Kcs>Q#4sJZ=>4EGt-+`yLWHz9OC; z?kRmK#xo9U$8sy)q;f0oy9br5@!sR6=}Q<6An!1Z3_X5vbO6C4iBfbDGlao#`F#n( z7GqwG^HO_mRG}WVq4Lv841Z-k-lPlG@ea;4kY~Bvt3R6CXUa4Fh+GDt@AhK3b99v5 zv~N0;3yw+QVn-Vl-9MN%@_y#E5{GoCLMgK!!U_C#Bck%jK7=>YzVk5 zzAvaT;2ltWO*;uV<5{OJYqm2*m#h_Cla;1D_$HN#!c#yp!P)nH(94vw545yMcma7w5YNEIYp+WjW34KwhM(z53f#{ z;*Y%97g@`ee59#y5Cref`V;q4rw_ee6T21)lP2da^vTj^V<|JxF4-4WK%&Jlt-5}= zT7H`N65Ew;xmHy0v~Tnjtl85en^GJ&T;tH{yPHRH2!{qL&~wvLh zvvc9q`*E>$TL4dS+Ti6$no1(5rRhH!E(2=Y$*I*Y%DX7zQ&prD7ouU$VIT`e^`y zZ5E`4N(2Uv=o*=#airQlV(7(rp4Dq`=0$fDoy<}*}HEm=GQGRE4U;TMviwN;vN(|jrpZ&wt6~of?~KDM+j>{Ejr?8up@e_gaDLY?3O5;D ztB41cQ0^_KCR#1ta!#XKCH%u=dd84=mNh}*kI|$;p95rQZe*rtK}^NZgW}ZZV0?mJ z=ZR0EWN16!(2koH)~c&mGHsPY?jMY?N%kKG{!YiDrHS zzu#syCi*NF5|D)adZ&@4n!f$D)B-NWfnXSY4#80|1&_^9#XpW~E?VF3v1pt6h|{@; zM_m;krBHYwGN(3-dfWM$R-Ai$#Y;aLp$EkEdydFfpU_%|RXnE*do{6F!Ns>ePkcd> z#J(K66!y%zFaiuK+A{W{Xq2KabXXt*3lc(iD4BpW>(`9epRGYW(s+sRpY=>cDb`;cyU z9k8Y9Y`B~j&LH%Q<J(%nqXh@RmtL-n4d-?i_ska;M1uU z&vkT=O`F^VgcpxS^BV?A7X3-EDvczR!exAHT~2f$y55TPh9qJ4Ml4t}TWkK1q*PGM zUbSFcjoagoBpI$^hjC?51KDr8F+Qnm9+~awiBkN!pJIlQC%Wo4%Xx%Pj2d&fXOas%i-&xd$aIzpWedk8rNc@NxW z0+F_P`PL-AsU^tV<$}-b#5nKRxAO{+gKhaNeG^LkhqU1!87dg+>lqxAt%N7DTAX-P zWYCh1*}}y{$=EcLE%M)%u@fR1V2%Z5&Ss(QzDyDs!TJ@@;bn3hLtUEz0gJL5>Y+m*}gKCds`id^WVP zANhnf(uN;b3;L*i&E{$~~O{%UTwGf(+<%I?HF^Wu1Q|jzamH!-k6@ zRz9XbKCn@k%J(Unsth+Bcr}vU?p%9V*?Z~JSk%J=J;MAbm@fSYajDfwW6d6c${UUA z*`LR2!H$G~H&K{i&!LhJ@dom66j0=w^qR`C*+Lp!y-af=^%@STa2yaoj#+Us1jdqT z&-g|i9q5#B&;uJAZ<~%=y$@>V)12m*-(u%Xmb}e-;C|VwG#-rQee|Os4R4?$D~D+c z$_sfWEp_AYdSh}VhZb1Bgr^H9?{AN9 z{w7U$`z!R)ymml3rO`hvoe*{iLkPqAMsj56e2Mc24`X2vCo%kQ5mq+Bam9Ap`8JZ4 z!n+|ZKx*Pio-N2r#v^1gM#7}UQad}mdj|6-q_5o+HZgV1xE0wg=~y{g(w*|NrD2LO<9Et@KR{s^m?c&iZm2wWB;q& zNb^qe)VBq2-#D|{W84lDn=lC{H1*|)m2#X4qsIhgZN)E8O9Cll&~IMs11|_LWq)R_ zKjb$Zxm~v^d0Q5YRe1JAJ$7Eqe7_8xmW)tpKaBt1C~i6^!NX_-?_(u}IXp| zHCkV(LLKr+7)jP?E;F@1ug#Rw4(2|j6PRh9Ng+oA;9zr^{dT*NU@b_Zpu`Tz1^=) zg+&lE4R!rA9idRY(heG0ne2G({CzLL;5?APieP-PH;F6mNPV7tZZQ2S&6CbtE&f^e z*DxoBSvBCN*(ikW^PLt^(7V-wQSO$WiF#v80eusVSrJsB3>wv}G+_uQR{kBcncC0u zLX9M@>SMD`#`eFmy2ofuj)-g6IE?FH@c74$WZV$4dwz;EkKK|H-pTu%@?Mf)zh zDuq1=(RUd3me2CsO;d{&`k2S{`}d6AceKw+T>*hV_b=wUOr^U`M1gjpHK(@R{ zX-`--J8qt;>DU|_{GJFgpuBJWB>B2RP^ZzXN=IR<^Xv)HH&Xi6`DL`#i)pN_Xm0=T zgfLy^?J-P1?g)wJ?h`45uEeRsLBJ~lkTO4k;#dTI{RpY~6VJo?vmdRV277r%w@?!N zmxsv~I`d;MB&{3O>6@DTaO|`+I5P9Ff^<1&bCoV1z2Mv*N884(gGDwXxLNOS#QWG@ zMFBFyX2B`w+Wc-nH_#*zx-(mcC(BIP`on(=kEXk}NEn}#$9n4xD#&g_EiS9LxNn^- zxemWLP!i9XE?2(k4Kh3%NbZW_#ka{D`g%r~6{G**=X<(PT$Q`!{&hEL9KTG5j?SKU za&~;#Rw<3;qPb~!3wsubCFtF*Blto#0hvND>EbI|AO z9B7#YKGx#w>scA3EIj^Y$; zD=#NjmG4fB2GkFd&vC-u>Zv0(_=?%xx-a|o30mZvaK9N>&}%gNIZ>1;nc29Nqk*&Z z3nA@TXEMHepitD@_~erp#>oL}R9YT3iZo*#$7sZ`9QmOFym@oL$JEvcwZ_}{%4c@1 zr;ac?CH*WBIl;x=zcrTepP0kJm)9lA&W%#z4K2LS1czm1)9?GjDEKB>diCp|$K3X7 zUqRaQB<&zuzU@23@P=s+^bT@*e6U8|ME5OxlZpukt>a$Kar9M5y% zgEHD>R}T9{3;-|W`cKhp8wbrP zDFQ6McInBY+fugS^i-+te9}K$@4Ta6xk%QuH|CGv#JMcJFrlq4d9bEaJl5iX1}~bz zOOJ3+oDWs8(YX3|WP*%q`?10@cP2Kb0Oa9pT_?d6CQXxQ*>6=fH->fVl~q-*CX9I@ zA-UA%{!fcTWC6mb*MurwqDMnCL{{5wO=ky;LUwZkImkU>#-#;OT?+IsJx^K3M(=r# z>jd)edA*0T28wB=qjHMwcJUDx5VGy3j33Lk-?wcxpT`FPg`lkB^F{29P27ylnAbr9 z1Q~~eDqHg1gq<_P{vsT%f1g!0aCx%`IJmgnMk)J_z7GnXRMpfn;Gr4g*=zpo>{7&C zMjUJ?VKK$TbR7sp!AEOQ*-2QTG70V5HM|Z#Bok2rYkmGq9x&*bjqGvbHT7ZR{IOg# zDGqvMPX9a_Dg{1ypk$m2j(Xi17gcOUxh`E0*J0UFm6=Ymgk#(q6r4IKAVHo_cE{DmTYQ1MRVHR%cYH(mq7OmE%=y5 z9sWRqm&%|V%Pbvzi0~oTyyhx2y#bGJ*N)PnGR@J13M@{4OvGOfsH9@w9=S*P!74%8 zWQR!q-P!Gpc38US@x^FqMq7$hTY=z0URU=mw=}cX2FJMZa#RWu&v_$?1lKrnz|C+% z-QyLu!88fSHTLJuRWvL!Km)vJsG+$O#WWTBlR{oq@#LtZeBho3H>|751Iu~rqW(v9 zp$A^KZKcF?)`xj%&IboM+8HiYL7+l63s}c(7eg~j!03_%z@OzE@tmKICbN9mrx3TW5&@6J zdIWb-uBfi2_`~(v$Z__%8s*txw%Onxn0{tM$N_wx)}EAZXXm0HSHq|R=)1T&KcQji zh*wOnjy2Y;%5ahD*LXzeNc3`H_0tgIZ_-{Jjh4he7J#wE~<#x-o97;Tq8`*q>9^6w-@)Zxu=NIYXw zF)R}BOvGE~oab0bJgtn6o>2WK?7Sd(HyTkV@pu&RlSjKIfxT!tk&h|M(iH(ivIPeW z8YKV0SElHz`rt=4q>DcP_GH8eQBPltWp1ip={tE+bR&i$25YDl6*Z`z93{f%U6W&t z(~U!wDkexq>9DHe2ifv)Xzuq>ad|C3H2eU5fry6@CgSg?86c2j0Dpp=oYe+dX+E^~XI<(6S@Y9+a;tvNc?#tX*>o-qgm`Gz<+nM)Q($CuiT~sCA&tAZr2(o*ayO{*E z!awAIfxa>mxR+R89r$S#CLd{52<8sy&HhZ=`9RRlH_lcBa#EE4YB{#~@?rCsP!8DO zaZPnxcn5)6Bf!h!*Ei+^b;nKcWgf5a}u(Rs*kO>pYr@=9@Y_>q%3J< zmnuC~j}vQ={l>Q()ws9tTvon*PkFxn?-MlJW8WYfEk^Km6UwroABk_JVQBRKSVnBY zf=uTHez<9RNe4?o1sBBfaPbxmIJUjTh4=g>1U>h0|JK*oi|&u)Q-(C6!U+AT%BP3qR?_CmfXfoiMmCodYkl|$k^Ig0?{Y~uVM;4LkNL8v&_Ly>#L^RDU6{cu@8p08ecc;!gt;aegFXx1Em>Hh}89hZa zpqrZs&z=D|hjM{Nvm8ZXWaI8+)?#Cp#Ym%+clax?AOM~B>gyG}2M(n|s3)T{(52p3 z#{n>{ehJpyY*p9u#*25t=AVSkV`|ShV-BZ_Cc%YMSBa1x4ZU#FsAvECRTTOteRs(2 z@OHurJmR|6x6^p&sH|*)%jtrF*s{e(g1eLp<}>KXS1aBMJtmt!hau929*4gDhl}pZ z_CI<)n~=U49_BJGDn=x0Y$?01XuC(8%>on`;_tc@45ra(<9`DxxqQ1N9eqt?bi>$! z(i+Y9Y{7tB#tbj>FGU^f#rILE7)KdvOJ~&$A{mcswEo`Zr@;cp>3di`TC>VO7gyg0 zBB&TaYt8_rpDmXIwsQtRy}st_e^n0A&xug0s@Gz{{-zC(*7HnEy` zgjS=fw_NO)J`UVnOZc}eO3}&3G;Zglx8U%M`f>;38R>@XeIP`Xs`RsqIiU$#DBQz) zRU{-9=aCdo`2x9`N?s2}w z>Jh2nZ;Oqu4~?Fh$y7sKM(=oDWudRpKt3MTujAB;pi{nldf9UK81`3uKclH?(Q$Fr zb~Rjj!_Gb&$Ll+FKY2nMcDxcNLdj&@=)vO%j7+~9AoQ~~c&AfYdDFm&`xb7p1}lq> zV=UXWr3dpW__*#F%l+899`JGkA=?Vsl4(iq$N%mbOkDqGCPc~yXV#yrIA`KCsL4K~ zEhvP5Py=+bbYnxaqBQHKVfxvYG3S$rn>-_5O?WFRI?(7RWFj4Imi2d#tE7DeDU{pV zos9p_YXK59%jUph=ki2|L$II|7_JfZ=Jm;gtif=3vif;v!Gzk}(zjS4i&G(sc# zKRR)~AswzxCCY{|U%d|shY>!)Z^MAoiV!P75VhR6-%D zp~k_W2{{(q*P;27G-hQ`#J?@ucd+LYWT$lCM=g|w7 zH*n4C`#0|NE--p5BZIqHm7xeqi)|7oGJ1FQ3QOjI7$EAbh; zjuPpVjRN-^=j6S-=!tMqg~doeG~6?2x(>AM>6XH4Xic(OUreJgaL1tK)_S zV`G1e<|b8LJMqA+AW6u0TK*oOj?er9{Hil@bC85hzgq}3z>+tG|J}n$L8kFpH*Lh9 zi4z*MH2GHuGi`A{z?%$fX@vV}rBECp8$4iUbuR~x7bko%SH~g~#M{3by6==9Jin5- zp|GX$T>bdn!TT}$>&IcIlpEADU-(T&!Rf_=$iFH5(d&r$Nz_Ir1Cm?3_2-sZOE7?9 zpPP;fn^&4qRm;iCr+8eN#_om`C#}FhaNz6g+q&O|a1-gKgI`A3O;q(yewExiL#PzzMY2~dh8Q2*IvrR(lD2i7rtalpFx zIl}rWgX~Wjy=5}o=Z>%87i>=lvaXF<1xc#U1as|l?I`CsDK?{jOqTJRnpAqeOQ~bL zvTQm3jp?i+)zGNKMg!YoSYtcgXhH3H?nVCBj4wFU3Iifj?Gjltf~BM znp4wa<=30F5{GWRZ*i4CTv!v8?`C*ZhPPD=xyS8A64pdKB={0_Mb|pcWk(JB^ni~v zZz*I>`Nu#Up2xfbl%29sb-tB*el8pT3x~Z1G0KE&;5jC=O`j~R+1~R$L8Q&F>4l=u zIX23F3|!+;bVT2>`y{k&zH{h1abb>7cn%0u<$&9-%QiERjDCYBJFYqW3JnD@!XdO9 zp=v24RXF>n`-?-7&nOVKPGHI|v^mY*Reg zZXYEJ1~gVn-dA>#MVAXU4&%HCXnB{kCIbc`(NzplNggdrpFh9T-8!j%JmYNhdAUh< z&vSpC+TeY3(zJ)T2*H&K8ZgBn2GKbE>9#ZpCfe=(=9nI2QqfU!$Y6&3BKFLdU*VLK z$vUW7W>NMwv7LjtkX=F;Wa5j)?H0sNGaxzhHW^EjAAdeV`W?`}3&5OF| zI&q-JHQx!~6^BFUgXe@l>x8AH%8BO4cL7g(xUG!w5E_4(soapC|L=v~j-){ts<-iK zCrTfcck}WwoPOMl;#!jIINU}b@azTy1PS5AZ%T=w3^A9jx`3Cp>41J6h8;8{)ksxT zq)Yc$$HdC+Do7FcrwdoY=Vo&|0JPB4g)^g^qpi2fax3hq!Y)g%jfSv2N-TVy=st{Wf8Uax z4d>3|$kgz3nOpE9`FHpJBJOK91;_qBPvG)6ibl`JVh9w&**dyub#Vn_!{(EVq;U>O z=G8Dxn~cSJ-)O{=RaH`bbnG=~MchAaMt;7;HBl2Y*pG|@Dv|D)7U!l^iO%H9R*V4wfV>Xnl>2!;MuIefM2_H8s)ketFn2?`x)CYgJ=Wub! z_v+Bd9|kJg+b1`siG$?`@VQECcMJ0FXEF|aPs4hZfkJa?MNe?E+egi);%7I&m|3p( zgFv;je|2&i~5P_F)uJiSWN zq600ffrAO4GQu3N^bjvC`N$@M#gJM42$r-D{nB_az2dX5y7t;a(VbtFGe6^aaEg}F zVDwj6$LvW)Zs@egwrfrXMF~bVP#Q3lWl~^US;roRvN!Hxx9)Ct|iko zF+!K~Ta(h7-gQXqC#e*RWh zk&*4ezuxAE&407UqUG^=nMAqav}3S0!`*TayS0@Q|o zW^ByySj-)vT33za$+p2lH&sN}7tj-q(0=U9Y44zkdEq(%u?vIP^~t#sAq{8vsQoGb zaG+Wetyf~#pfq13Ta;)-kkUPlMWL`pE=y>SS>(~{QOPZ5ywWNA{%=Y7u*tA}|IiHQ z5VG1Rhj~W&UixEa;94lf245(sBGYc`A2HF^NDz2(oLFn1jzAG{45TD~r9~G1%@tJGC7AT6om)Bo?oH8FGd=4hzb~?Opm*dE`t&X?*Y{5 zj=OiGn%hbMPbvq$2QwPk>2!W~88A1B1gO8sd^i)y1b}R~ki-;8FU6)QDw*>_(gjEB zJ5yN&GR=bM2=z9E6m-4l>#mw^3x2$jQah|^OHr|ap*x~h_h%WMB&}q%E#2&DK$+;%u;H)6q>RJ7C?!&>-Os`+ddQXXK{#k5>RGXx> z$R%aUL6Vw}8B6e=;E@Z(q5l5-Nx$aK-gLoGAn=2}xZaS*P($fweB>_Md!ojhaNsJ;tl-U3Mf zxw!KU#@kT=jQ+nYOSLR*;8fS=UzlC|Zt+$5?~a<%WlvKO9@B;b=70bA@jPb%!Q3Af`xne4Bc%ozFeCp zlHAxrVGt<%)$1c)-Du?HRDNwyaRFDu1+7}kpD#(T(f$fuEqNRtGgY1j zPriXkbc@Vk=O}Zy2s&%5SoNT)T4J?;HKeI89jKATP9xZ2=II0=%QeZ2EJ3m8Moa8}dYkG+1G#)<>GJ*Jl(HAKq`4&?zi3n*E_;b`8W4ZV={a?yLV zV3ceCX#R5a#ZeH`=HYRShO0a&yaaa7wH7d%ZI@pQ@dVCQkZek}3&+LQX5NjeSTARu zl3}U-&o2V+c=gn>x8+h-%9KB5rR<;GR6nHs7Qi0=Bx0QsCpAS4EQI8x^jYjxO?X?G zWgui@WD|MGZRJgJnTx&vOg5HP+*>VMzh*1(-=y%O)6a)|16K34Ws^6eCDhjP174(Z z>FEe}P&{rGCnKFr9HX_WsNch6(qaj;*{z0SEdUEJWPCdidmVp^m>W%aGxs4)x*FW^ zn4`bmF>13TSqA+F908&6_?%1LbF@vK*-70&WzpPs;kX`aU5(2XfG}nIORWgO8x0j( z%TKVG391Z&#eVO6iTg36KwIzIh}S&X%V@|!(SMU76n5MQBQp@<$@7RLkK`RnpyM>i zhQ6D56|J|3s&x|~3DGB6W)iXoNRH`(9~>n|e!bg*^`96|od(zCa|R$_{73M2LYmLk z4CJ)cb{Kw1M&U>Ge=_!N#8;(Mo?Lw{=@l20_BGT;MdxY4>;=#QPoFI}E_pd%*os!8 zQxAOKHS)*93hi#aQQE4p?L^+82$S|+JCR3lod~{!AcNH4jrMGM^^PZNvSahA0Ld@9 zHT5S}l3x^dQHE3G?mOGK|DN;EZT2;Zis5O8dN?T&!CUzWvSr`c|Aydf1UsjQyr>}zo^CL*WJ zD%W1_N#mQ_!3B`VHH8}Y*NP+{asS&2*SDqe4GNBn4K``GW5R#yCkyzLBkDWCqYyQ_YSvU~bV2`Js&-AIen z3W&7Q9ZD=9-7PE)f(p_toq}{pOE*Zjv~(@7d~d+#djE%)pSX7SK4m`%{o zcF1|2#>MODCS{@y_n_`;{}pt!!J<`*0V?|(M@OoUknxgMwsTaxCnhH!7jz^FHK&N$ zc2g3UV%}UFBmVw|d)I7d*jz&4xocZOpsV9=Ez&slPvOzp>G23}?A{^`&~Nt*R_1 zzx=2J(xjfG!vc$I%L};dG~$I0?Nbnb4x5@uBd|M>Iy#K}p!qS_)D)_mSoLn^BoV~p zyji}=bp3bp{X8Sqi_(zOU5eFK3!}gRa)i4J3R-`5ZtYhmok_pR?I+e!QNi{)Frc(>1^~fgho5Ai4)eaG zaNaoVtemWCF(OL5nPvOF$?`72y$v^SUqf&lKW?5yCEwGM8tRzAe-+g15UhC=tb8 zw`iYgp3G3^>@w%LEqESJ8Tozqn6clIUNxclw$adTh3U;vZy)#M)YOZi49gU;TeE>N zJ8zNIkaVqLeaz|pE0>WcYJVcB8pen^F+gjMPj#$SVcvh9SGu3nKHjLvfSt@5wg16* za3$(@(uq?9GkKiedeRd?iu49B1Fe$sGSr>C_Vjwr-+>eAc*Xc!a>=DN&@(~LhoJUd zg)1#{7j!4&%;`XOoOM|cL;8?tej^2Je8#2f_|L7)&{n@l=JQ{C%mAbjP)rx}0hFmQ zD1Mk?P(Xpb@J!%flzjh%;YNz%Zu!$8CG2LjWKR8ic>gxcokjQU-Z3l=D8|UwuCGZz z%|^JvRs`EiODbxH#CoizaK0`P9E}|H4~>5&&*I5q8^x)A*BX?HQ)6=()c03^NA7vX z9EL_hwIqgL zlg|+Ifv+;(3R>3qW`rUvkAuj@x=4@kNmboV=fda5GGiG+3}^4v&W!KNe5MZOU51by#4R3KB#A~rC6Q2a1qU4JdWZ}`dQTAJC{PbIHT0AWx zi)CYfG;2o#6+fK~2s$h68-q^vJl7*=zL`ws8Kz-)a}Y+nfc#KuoOvxET>lwt*w3H! zen6H3oWH`w;R1V-8P8Iv=2FY5fkrFo&-ciK(}tsQDJ}7)@{x+jx;hB)6_D=&8!T(# z43*9H_%ihDulv^PkoH5Ebr~Y~9|A_QHfFQ?J|w${;8)+cix`D`NAe#wmN%5jo0#ga zDXG#|oS9GqQ%IkILgtzcUSC}G8E)DMuuwXTkHoAwiU?@zv`5HHl@u}dtW~aAwPDp{ z1L2>IB---BEy_&n_2CbEyJvRALyYI7F|*)eiP%|XlJEJD&6LESlE>~K8$Eevw^?*h zR^7b%h_FQpuWgd-bE{3>OWPi;fK$(%trNl^zh=1Ka5Ru&%B-P5o0(-=-n|#xoIwtY zB(204L*5zUnf~qJma|c3xOD6hExd~ZO#g7Tk=$==Kk8Rjzq7J;ZHwr^JBAEmD^CC8 z@gXLyjAHcwHs6_3IHtrxsPchNjEMJ?WNqTs`XE31Bd!2TcOZGoqnva<_{2L!EI1m@ z;Yce9&-oMI%S+<_8{Qv%^<4DumjTwo#Qr&p<7B)A_?IFdFZnxZjSn?`nO^u{@XzJ5 z0$Xkd!8BrS^I$4$)F^l9X1!AMWud<7o9ah78%FLPS9@Kjm+p7iSnOIQ%A}y)k`2*? zIPn{lq+Cj`6I_3s2Z+33e=77e_kMVTomTaEbr|^>3j$aat?jI=lv@b=IcKtj=3A^4 zRav_lh@#k9I!aqR8oDxq#!$iMhXdpr-EQop1;XEN4x0d=#Izf8WY|Eu6xhhp7Lq7* zyHVW3{IPxn3SdGt!wUOMeoCP|#IT!@YAU~N`=n;=mKSZ2X{Bk^pN}d(qJ2%U6qy+5 zge1Igi1S9u$D1dxFh*dt~Vnv_cg!1WFf(Lx`}d7QggyAfhq&6;b4n^gRL@3H;E&>6ECm*rhPwZ zj}90!3(G-#+}Ac)pgOYALjpB0^SWm$hw0j8dpv~N69nUf;&8DA-sR&Voh_n*x;}Cd z3JBXmXE*3pkUTTQW)+b+415moXNIg*>z8wri$A{6sQOl0t72sj zzcvDAmRI2^cHup(Mw)$cWcQi`>*XVROggAN_^$9Ylb!q7aV+|JV8p9R=5}^VJd&L8>!t6wK)$SM2mQBs_0?75d36n9w(D zP7Nfd5-@B9jiQFyU2is?O>P)33I9o0g`e*G=|vQT$H@Sod{NeipL5R02vFy(+kWV* zv}21O^e|JmKMMFyO#qLB-}T+=@9`L{PlGRzs5F?Nh&jl`x(efzp%!6*r!z>{Xi8M< zlO8eLB;`^hk*q4-WL_tUS|*a0zGu-%xu-oPfx(dLqdvQ3`;NzT*Gep3%J`IoZ<4oa z7G0nG$EfigzMpTIc6myZ>~wywO-6R)51FFOnv+2*wdzW}miRmpHzgf549=;%52Qe< zhML;|_Mjss9JYh_I*=4ea$$f;F%1(rFfZ*0byEh7_905T+4_;~M&47yu4BP1iP0t* zDSr6sVkFNf=!2~7^UY%q)VTO|Sptlpj<~Et?fwN9Nb_PndCHTTb-^*$|>j4_8m@GHes5k~5)c)2#v6Jg&_Gp( z9x|<8Qj0IQ-C8>oJ<9B`YGfI+qRRm>I0S=Ud4q6a$5~II!yO0+OEhl-`3Bv=S%itx zJqofrNZYsKc0OwbTE@no*(0oy>Uphs2(ThrjT!LbIOC_GNACc%52A=v`?(RIF+&sH z{gL$trUQuP|C4=>M5v;NtO!$R=2pmFX5=Se^s*a-3*x&n0U+S0A7rw*RXZq@0@~uu|O%zD3H-yJz`a!`TcvY zc@!k+@{5XZ)bU^b<(JgHCre1@fG2P|^pLS)G9zpH_#3%v zBIbZO?cxw;d%vj{^{u$Y;3em^)kY%7zI#)RSm1CJ_PAw2fd*_v(;nrP5|Y zL_WF;epfm@$Q})a76f{?9Jv@p<){DRn8tZhqb>y#-V_9nmzh@%8TG5Ml#fvB^7xRpRX30m~vkC-e{ky^mDGfQ4Xpa zHR&4;G)@QjO9k%$zqgr&!5`k5tABGsE83Z;&_560uA%P#Oe3KETBl&j*tk1GXq1Vc zN=a~eC7Ni+`-m68|2H-m1mbZ$IrxHVhS9IszssPLN;c!m)6|0Gq~9m>Rs8Cx!7-u! zsJFEM9i9K>R8 z4V;(#;WyI6ab(5$`TP}}`uMOky-9$&B$b;)qY!@3)JwPNL*A4WWA))bTTIZ@Fv>wiBx=7rk);>7(V zw2(+Yuyh9swHt1f>fYus-{2Bqjwx<`D`w<(Z1CpIo8vXUY3QGq1d|gJN)&#jAW4q< zMdfqctlDtha*I`pRe?%r??eulPkzO& ztyxZHgcj>pb%l!IEB$W64XSdf8mIBsMhB$#0O+VId`qJDx$676;v*B^bzBcK2M@ui z(ttv{_>$Wktm_U!t!vMtaR^>2Fy7uttYkPBuqh<1xYIT!QU&Ot)@mVk0P+_`(+3x7d`HRzo6B~$e{ov znT!hPQNlBmxyaWVVMJP+1kYFYCQ^senhy?%Effe^Eek*6CI9$XSXj6Cw=bvBEpGb+xWY- z_sbe9l%OEx_(}n*gR(J;#g^w%ckKAid#mubaQ zQ_)B1L~iS|dm}i<_=`Qew|m`jV|~3w7IQH5xEXo?M67H%NrIV=)4em3hifnQTW&e; zBrTYoY>-mPvW7rW&GCMq?137LPUGUz4SU4F&NCB$gmx0yDXY2 z7DyWY)ppR6_arVtA>Oy%wDTzfs7o0H8vbK@yE9(t_4iHEW5v&w4D#<;L}3d;ex@2c zvfi~z^kq{!Wo>`wM^Ujhxl!L+EB^&b%I(IDNk~Z(_Xl7`j*b<)+TchNJlu~g&UO0q zFEQ{z#z8nBf9-NtuT#6UGEYAR%~Vlk@9nus9db{7r;U(t<6RaG4t^#uQGD$9#1yqR zrlI#pkhzs=e0_dQp0g@k*wloRd=CB z+?%UyQL)C~BGwCUq&QgFILO>4g>iEr^0(=;d&&ws&M^WcuMh0zYBOI(N5XHeBIFX7 z#)BZ>`C^^@_cOIpAb&zYc}!c8{L-I3_o=z?ZsJ~TOOE$FJUtH}$+oL6DzoDuLRZ*3 zg9Qf@?UP^c`@zQo))xW%rh@YFe8{d0f0pXy?o6H9KiN=haqKNWNrg{I8yQWlwnY1~ zgla?(^-sl)dMiNXV;9Uv>0qo+(|xMdb=R7`_DA^5It-u45;&${+}SYy1Rk@t+K8(? zoKHTdl=}uYK8Jfj0VKIY=!$ZRs!5~X8rqtgOrN|=|BQ7tw-Q~P&6WY(EXXOm0P}+Q zpun3GMdt#6MKbTI#CBTB_Ll`lUVxRAOOJ4K=4@5WG;*X(*9!$|7Q6!~QoQ~)X9Kq! z>iBF)IQI|lHrQ_S7JS{7X}Iclx5Uj0qhcfC*3D-f&}IOdz(rZ^EQz@-GPXe77Cf|A zr|s~=x4xg=%i*wKS0ss}eBSkjrrGn0Ht*KVx65sp4h{}%KewF2A!Utc!QWjDXvD7i z`)6kAGnn{!s{zEaJI4PE#eXJo{C38Rngf@@YS+vRzAklRDvoweNRZ&CGade!1d+jWxWNB(62EqaM zU=U|)a&nQgtZAaCf~-WQx-UepTG00kKmgxA0{p+`mldhWLl8{cP^tUlG!F*#?84<# z@u}=>ZkAeKJWT0Nq>9k&rPhF&o^&bAo@%dVw1_hftv`6X!&g~>a!-{%5s9#6jNfgB zZ&Y-2Jd%gsnLb1SP&dNYO3A7P_DTRS9$JoAts8*&?zYGIQz7!zA_xHhdDPc!8P|n=hNxNoP`GRHLao zosBJ#A8R!VWmCt8*;Q0L{qHr zmd5o5;r?Zp9P1dXn+{<`rr>z4)c>Zl$;rW+Jvur|5IOks3yZSj9~HfQ>>V%1_|bPl ztJzCO-!vrrl*)b(ZM3zuwNMpr??&iEksCFH9$;&3fc6D?5j_E?zsYDq14eX5Y_(5Xr8|Lw5%?CWS6y=n}n^-NI_@%~}s<6I@Y+K0Kl$g-=<+;2-7XQT7|9^N!k^zj+1d z>DB%tsXaK#v9|UvOya)*2#5%T4V1$)7Jbf35(LfrE&tr4T2U*_uPJ}%-f|G4NihY}=%S0pcQV>%PYOffX_^xsnb z-g8CY1MWG$R;#J$(dT+JEhO94DJeei83$^{Riglw+n+R;8JsK;!3%4(NHekegmeEe zh*936GEN?iImJEe2c=hm5?v-_<^wT0!o9o+pU)kxsF8S*FK>Qo&)K`%^62=Te%Z&eYH}c!sJKRGd6JNL?`tmlr zpWCubyd3%WxUcfir=DjQ$40q*9{??#VFz>-9iQ34!h$_VIt)m0mLGk>tCRFfPL4## zws_vK*>#UBtbS~WBqc7675CZcxY|kLm57L5j>vZ`{FlW;YJy3 z|1DDEp+SSIhA-YPFk}5pJ#6Lk=k0B)vZ>@4oHEFauSyc>Q=5)xiEEr7gCG=?pts#o zU%qaSI1OYelQldL6bFMXIY z`PDQuTyBxD#RZPhA!aaJNgoyCH*Y>uAjkJrU92+Rc^5w{K-#o`nfle+EB@#A+rW5K z9~6=k6CaM)cfT42R@q|MUeuBc!3DD$^=^dV|fx$P^ykNAI-J|1}>F zQXdbUx&cjHs~RC;3P97s!qB_&F`U$0_r<9>b!k8|jEsQOb5OT;*3k8la_7*qjT`%s zK<4dtuX9^UHMLHQnIFdzS2hLGeJ7;1<+BO`N|pR@%SHw!rma4FX@^v7VThGdQH zmJ*;No=tHY8ia&|emBR|R#sNXl3rMV%LdYSA7SJ(?>}&Fq{|AZFP}a#9u}a_ws3Ix z4z~cf?lm;;CjVm-$fz{4&~r}8CHpd*6?-H`>V4j}DD#ecu zknm)*3|*q&WkOMsHw%lt2(5AXYVs(}_H#(*i|nA8OR76k*ETlt^78iQ>auHV^J~jh zjZWBES*zn>f6Lnl-gKE)#&6$F@8#s2xlKe^q#$;h_P_vUA@qQ4?!pab*x{tenlKZVKpA6i<%^Z5sU z8w(pR(S&6IepOlYVQ1SM|4k~Jaql=J3+aB*X~f0F-#va*lXXEICudBn+}W+i7*5om z&g`2xtI~4em$S9cKZ%ErhbM!2Z+sf5&(YOH>Q zR`CXK>jy6-qrRT4gFSnhDr!~lnjw6$#Nch@Hz7^LKsufaC)|OT(p$hu2J(Xo)!W;9 z(?rA8s)rirr*p|4tf`@41_lR6M~FYZZE{;A!Y!JZ@lNII|HLOB=J%<*zWy02>nq@R z4X~;isiN=;{Mbpk%L}_mT&(82E^4W0PqVst+vt}q{P4~BhM}$~a-bb2*AxJAqFJK< zDK0KGZDC;9p8qO%r2!r}#ZHyFFY2bSUv1WBjxcPib>~sp!?rBKzef_m2uN3ZmautV z0Dz1?f;^7@h@Wk~h>*}-6W!;R@&;216_SNXkbUv6Ca~OKzY7mY+$N`~Y8t-(b(V-| z{8^bRo%9@)N`|#2x;y)JqoAlrug3QMY}2Xkchk!XYTt{}{PJ?OZsnIbR5{(5@RFob zQs5BfAUU2}r$QU_gIOLJ@xaLsc6{>GtHAtlgg-}M!Rp!KkUXTBIpS7_b^TT&HB^`a z%O`mGBjxNyKRlfZiuc9yWYghfL`>#ec{vTYT{J(+gL?-AACE97#xq}_7EJ&L>G=5g zGU@=IX|Oq2Sy^G+b^2U4b@lc2jg7kvb}jQiAc3I0gPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>DDjZ2fK~#9!?7@Kn zzz_fcpbhx{V^0879{>OV000000Q>s?zt-|G#^2a`5BR8x_5XinPT5}4drt_E5C{-L zN1CW0SU|(Accf)@)#tVk6?50C<+*Uj!``#F2gnfcG24SRzzilBdk z=EG!Ovxmc`yz@NsJTuQ3z@H#vv_5`FoGH&3oo3KS>k=gBTjgB1atG++>PLtW%o&@S zH7f%a8vOt=3g)rGNthMoA)CfCO+s8Q5TBYbWS~>PHxxY?^&{ao(InXkrNj3JCEd5GwQo00ammB*>8gUfrhh zM$p&Pk8t?Zj9GUN(j{_~7YUgoKRM;ZAyGvD|Bb@}`P=p*V! zh#;JO>G0AE;{d0c9RLt9=j30FAkwnhD+{jiNv`tFYKjmMLYs`0B%gNg{xU76L+>3K9}R5_AbCWt=)PZj7V|36t)93mcf8*v#sM< zy({Sataj0grsah4BkD964r&;XE%W8&_J9xs{rWRfdxMsbH|jV=iRSraqc+E&9b(m& z#^~Z$LLkPJ2O_k`kVG09J8MzSKD*ee03-n@Lnr|hgir*uA;jvk&4W^Osj-N@Es+9( zyRvS@d&@unt{nU=gb*UC`U=8$qyFQ9EHeXjJfq`~hJ!o{Sq4HTM2;Y$KoueC;zwT+ zgJJJQXRU2tqELPy#E()8LX=|4o1Q$jMAxnfY*f6vC813SLLmTL9`woA`47IaPEjy8 z##JyV@03~7AAR~YMN#^SBlQKP1hXz*!?Or7YC{kr1R#WfA_M?L1^^NWLSs2-O&ea0 zDslKC0A@|>{M`BTtZiwYXBq!$DAfS$BLrX!Fo6JIQQ&viA)CVkj%A&5=Im2Wnsnb| zuSk;Ax8}lDOiqrrP=qW(3<9(v6(m%FQK{rqeqlkt2IbCyc}}sJz8D&R+y!ZQsoqDS zuvv{p0SpOH?1VN9u>uhccDU2F?r8$YrVIxCqxW8CF>3yO-}97TpNmKjINY11psWxX z6NLZ;140`iVY`EoKHStW2G{H^U566<1Q-S|EQpI1 zh7aJ)Mm;zNm7bdP;p-1IHa6Y;2=$-1k4B_6LQb%ln2;et2C7zwK-dsflHHOF6(i+j zHYDW?oslcOf`VH^TtWB)AOJ&ss0&*mz!=gdib`u|%)UAs_)9ghBsVY3;uREsAP5da z(H@0RmzZbxl)xP<)>hv<%4!l=9;Z_;LjA#bMt16&PUP-H!d((dh$!niK_B>~Fr{v{6sqGGjzRst{DltD2^a&UxdO(Wg#KDHxE101o;* zM3%IyGAP5!B~F|@DR)EJPLKZ(ql}M>e(kyYh7E|l?8c|J?yNdCQu}6q@Wiw@GXN?@ zfMAzLh25+WW#rjUx$eQ_)1R%EWenOxZfV(VP6Uq3?T_Rys6vv zHvM@Sn?bKB$WPZBj0^*g8<8|)bjrk%ERJQ2CZpBBs{Xy}Tf(x;n^X5Rvn8WO%*bw8 zTkddr1fZ&P#Nc;cy2s~izVyat>l<5-rCs~E*@?F##p=0k2_mZ+qREJckF6Xw^BtVA zxG5kh3Lpd$j4=Lqct^2xHiSxuHz46D5JB4L7$QQj0wfuTA`}GR^MjQe3vYRLqdy@0 zv2{A>$uV=L8B7gKpQ}+Au=jU22zI5 z-pN+f@)ZX}r-$?UqBoQWzg=JP`(k>%u3$iJ+0NYtDo^*Tdh|D z6d1-lBr8hxr24N$Nad#*VyFS&^ze&TfKOJ4TX(y}pbS)*jJhk%9R2uPKm4u*s@c;f z9Y225&V6;Sf3PTWF)lVn6a=F|lM<`jwcjQP!EiaqjN^vSnL21{Ng@;+qSwV}v@EM3 zn1Yk2@eu&cd2`G;CqTpk0LnJ3$uAscGMVU@5PV?EC-*-7&e9d@kKtwRj)vNf5wmJ! z)+PgiKnziMKAaq@d23Y6>~tLm0T1EVZ2<_VLLeYY8E^anVkc5B(Z1QHx&IY#;cbpD zzVB>o4Rp_?frIpJ3LHC>T&Wv>-m(VzYOw-LkW`(e^`G1H)JsfG1jfTpAzbH2|)#28x-;X_;1dY-o?^aO}m(-p1xJMJcCE$;(JK z$3~mYMlH2DhSNYq#X<F&rMHjnW}eCI%jce#(00?HV7UQrGM1{BWokJoVx=yDMGb zx0G)*j$*l)X-Oup(n6F#H;~a@ln)FIf@RdB3KDEMF}BPFrPd@mog4Tk|cEw zkR<7UMIoF9#1CO@?`vx-g|yRtSiSn#E(MMmP$*sVD&}>B(-4-A)A4&|r)e2r_sb1F z>4#STH!XpUb^%}v07jTtYRlT5xz^`$fx{5XprWLN(@rYf`QKfW_2za(`ZnNcmVy&4 zQPC{(URz7MKLAuE>h&|?;v3BRd2?q51W^!08L*-;Apy868rqyrM-XOhHAiZNlHkWsYaMk5%j+1#bXx>aC_=4P3%W}V0IzLdN3f)1 zq%6zF@UDHp-kvyQWWbsP5h9TB5#R}urH#UE+dE(0?^$gV8v=58t(3!(?wfb&U%V|S z2;lI931K8$JRouLzGiA|F&5LT_#}}iOKojGbaeP6xhpn~jy*dn?zQFyndiq97s|3C zD@srlh|e*2*oa`juhH-?ytl&c@{>~1FAYwR-6~D8?kTZ+7=0!{} zazA}Tj^jXgAr5FQ(b3Tkhoh`)^RZoos1semq0<1v0E7Ty%3ShJw;WKyksASoZ~z;2 z|0uk4L)(vEg5Q%NXgGGL!B`T6qf4^l+@#6xFL%36&|4J*t9)JnfR1G^OiU@%=$~nC z@&e}U3hAgbN~)&)Tq)=KKZ22&WP}^ZbB&Sz7HJn0|0eL zEDso#HVA=67Ikg=$<}ZDKP>5NtUcndV0vuKxHCsQ`1*H}YIb^_za=@nlOy|NDOQ1- z-LBo8od;7%!_^m@Ie1`xht1}&+a;MAB$hG$X=g>*j`ER(sZ&bQhUOm){)`g~ ztY)3p-a^v}n%YxyWKHSj;Wu(Dg~b3>E|<$GQ@S8`(f#i!3q zO-()NjB~Mqw{KcsyRT}**ooGd*tcGIs@2}PX!*C18i+x;sp%;(A3SlI926)OYJ!pw z(4-!x&zi+DY}m-?&8=Q6M=6H?in0t3BD(Fi+g^O}g=4syJK*XR>Z)9O zwzzg~^z7a&)>V4jn&qGf{vdUF#F-NZZrstUDO=2@f6YHtui^cEpH8Qz24RkhPS4Ke zIbKoZhPqlJ1wDSj=5PX49S-;Oad~uKg7Q;S1_eOCCm+Y^;~B(+ou|*|r(u!VY@%b9 zWy^P!o6TkjA%aj*bByj3Crp??ZLzhrwNKWO_5roo-3XFstEsnbhxxOPH)u8L^0cyJ z^9EaUqrI)UqqW)A+SJle=W;p#07V0`VPwfI+PvVbQaX^u0ELJcmf^IFA*Fj1BZ?vg z9C44-4(H6C{q?FCgP3B&mD<4q>xMHgK-Yv#-?TegNQSHb>37sY_j_ulI-9XEM$Uv;E?KpmZd zxzh{RY&r0=Rc{T?Uo!7x4bNioKhden(P5LsU`tb@tJ4{|oQL!iwHum&rdlq45L+-M(Opm^o)-_`mn97ZQ&=MP`^5S#0ZPoOmE{@ zmg9N1+uhvSzGu&#ek=TC31YC~Kx@H(G;pZqOh3+Q(t{qNHe|E42Lgdeim70%<=~BH z7p74AQ)EtS2&IFHtVluHkT$xz35Msta3B*2f+kLwFn+>>@Os-nDxO1l>fp2FDc-Ry{4)y|1pJ)%Gi~HN+ifOxC8vF`@(* zUJDT-fOJiV7$eRM!669sI&Ij8)3_$GL2>_m4@4lfwzkZlf7XtjJLyDt*WGsyD=r?G zmwU%;H}@m#RgEo9v!0{LA5fK&m~g>qCqjybkS|tme1GY3sn>-rsO1sIY3=UdwNIBF zX!0K93bCR<1l7eBeRqCTI-QPJS7anviWuU^kt0t#?R0QZd-v`=@q`)0!-hWl%+ofT z?V6kJyz|!UF1qM~euTZQx2@e$Ger$*Qj-#IxcICnvq`JhFa2))k3Vfux9s&nNtV=* z5i2-6Ych!8SO!8a${bg=r+wp&>bPhPy-w6nQ;|fL*D7)lGMb+uq%UJ)q7hEeSr2-V};O8CDhrf)zftn9;@mj3PovtJ8)} zFl>=jlwWjo%!(B&z%Oaj<}H_BcJcgqCo76nGGa*C)?J6J+Vmr&7FIks^X`A&7N3~P zuR!= z>n}cWPNzDSWxLZYDk|E%xvZw<0O%o~&j$dRF>TV+<3>-LSR4~&s@&J$>~!@z(k`8U z&e`Xkf0eU#D+|6Y8HqXpehua>I{(8GlryJ zKRV!NwZAXF{Bl%O6!;}IH@6TH1dye-U2(~&SsBT(G1h*BU2?eGiRlAf-i}tc`-$gX z>{;F0RV^M7LZMD=gHokI>4ekjyYJxTW%+jIt|+sGytt{=lx?RX1NXpF;|foJbP~WFN%d z5rg7v4xh&-HMcqc=?J}kA;K@B;RX3dy%rE)FdB0Q4iWJCSx9CG)MoOhF-7lX^8Zqv(q~`FUewHNzeiHDYOTQe|&L#T9S3)vK@qw zJ`j=iF~vqlF^Hi;5OuV+*h8(+Tk|yti9l+CoGzf~ZEk*FgQP@Hg`5fe5egS)^h^++ ze{JDy54{VBOvw>{J<_KGhyYQhmBxMc@|mEg`Vk@sSXBfo?M)4B%?-BdwL}WV8lC`n z_``iuuKs%IdbDz**nta8iACTjbeL-{o3~YM+P0rkBw_~%I-x$D01PQqEJ4_h@KDjM zJBv}zGKe-pa7$xDZFOa!r3?Vz3V;RAY+tylf?-%mlA_`gr_MP89G&VL8f8U^7+kNx zS8db7FDwN_p^XTw05V9QMKg`*rP1HKd2(Jx)ZctA96TUr=H&4wOd5OqgwX|gSw^Fw z!|4k4a(FPuGLuS%p|Btng@7alb4|4ng6m%2SH8bP-Q0*9Ikf1U%dgcNjYnBUP+3(? z$;HORKnOKj?WRqe+-?`W-qSjZ24@Z(m>g|p07Q_{0YD(s&_Q~vwDkLi`et|EKG^vv zl#&>K_mvmPisBc8{(!(x6a>>4^vAND>$mRgc^*%+)pFZq=hC|(Q34C)VNu&&``Y%& zw>3c3jaM!B_g(jC^#*WsaymP=?btzWIx#*zH#eJM7`0SDbU5rZuAyUkMW@#TLg=3G zYp=cL_j~^P>ZQ}iWkc2s0KGW~utWlNzRsG)R^PDsYH8iy4@Lrbn|D;z)JOJ!%tpg;rNzgU4u^;M5Q+7yyXwVVSpAt^cG=|*Km72~ zS11XBu&Hc|D2fyz%P@L_J~bsJ%4!L}bGW945FGv%c%G+w8fTm_Z|2mZr7xTUAPe|d zfI|oY2@D>O*C$^tvVKCE?f+F;psCAax&@lP34sfzg!g`Yd!zM|GVRk zJC4A4O0paX1n8Uh_HXIB=-!GdXJ@CnRL4^50}!;gwKX<29yqXnUv>27aMEUvE>Nkpzr&66H=%J1d`x8$-@#Pm^ zc)ea4%Ybe=eeS&5Zo8c#)M+(YS(&md&zV+u)meEHhv@-Ckc$l?BqY@1U_fwVML}3m z&jlrf4vzo#`aLxr7~_8mLaW()&3UIY2rgfg9!2Ir&8vHq2vu>aD9)c% z8gARR?ZF2h{N|glyZ^Xza&kZV_!H`N6~Y>hPdxH-6?9g8zurJ}xFol4XtF_~2ttz4X#cN5hXgJ!&*0BoJ=lgpXdQ z)<)@ex_b-GCUPsC<-+)S^l5t(7}cc8?L(Y3Tk_iFp5^q(9C_{z(HAAStTP!PMkD} z#;Einf^cNX$jXWe006!6`4`J|dflM>0i#Ec-nXwBsJi5|{FiP_C4g6VzNiVxA##cm zK2?|UQzb_F-T8O3LW=F81y>qPreEhLh$8iY zl+Z7(nNh>)u-hd`4tq{2O7!*DUOWH1b1A>>W@@+F8ygzF`FhnGufKNLW&byI$`rfZ zA*c_aM;_8Y?X+58cxlk#6E|-L{Q_&(6sy zDjJ%Zl?6d)H*v>~9c7z016AK_a-KFh&8$TT$uMMjUHlIA-T4vq2Fw$`7I+NMmB6+7 zWYehptZ_v-vC)=o)lJ8SBjq^u!jp$wJTuFzM+h+xA)+Wj!B^Mft!{981B#XIL(Qc>jgpPe$Za^=bgAGqJ)aDc;8Y3b;XKK?j5D(a_An-(ryMAMMb zW5y&TB(Mydk&%AR*=LoNm4So$_SGq+12{kk3j>fS2l?UdJ;4}aLb}l50yrQ4>TH6_KM*D@?eup$Y5S@2<5GHGyH49ZPlvXk_& zLr%BEWgpHID1_`!>iKILwluff{rTsg-+Id}pM3lgjYPm<%hqAL=;DjD8cj+{YT1@8 zEX!IgR+Gt0lf?(_yLbKib=~um>LxiY!I&1OMMOqeQL**phe-%tgdbMN1Yuc6d?w-) z`LsbPQ7O@;y)ABnn1CSm6@=6oMzSl7hI{^&X%h;~bgalhIVdQSs89fkde{%4jj)_1 zVbDm~IK&*Ca(MON5}gqNh&W6FRJFIaKk&c|#%M_xID&drucJji zy!{%z!Ei9uiwM(b<)H^3{QR?}!C(*^k*L|Fr>BSAKPiN;ZhmLkv zaBH;~kWGHs`g49tcYe4hKN9L;G`6MT17^}G6DEqT6Ki+~VV|(V{dG2*Q#^fI{;895 zlVdfKq8?RB)b9<158G1D<%h@^lVncHq*s3YVaxh@3r(vvJbyT`t1Qc6Fc@B=rbgM+ z+|t(8{_;yN&@nht(c}01U$b_t$L#@!CzHuU2%#WbTidGl?RUA{Gza(j z{73m8`$&?6F{XCBcHO$g|5->^XTWdi+bzw41YJ1Ahhq-q7mi4K=ck1D$%KcP*kC*+ z@b#~^J6!I*l^4p2GB7*g@>2!^2s8#WLR=m?18NkUCGA1%~I{`uaKm2sk2XG@3bcPQCTtw;S|^#Kgp^s;V>Q&2=5#A#<`M zpK)K=MbA_Ouvx-d8MBcE8WM4y$|3v+X1v5K5w01f?PQAgutOLk0{~_e=k&RVbYx-r z|GR6NK?^ypo?$t^%T5S}6sO+I>rH?VZ%5-ROZP8bQx}dVXnIE@dum~a6PMB@F=~R5 z9RH_{8;|&8(X8y8Aw!C2_)2rZD693t3ooShclf9DH@174JA`3*aT;SHVJrs47Ret# zS40Yl0#tZNBnBHyZiJcbFwrjQZvJRvWt%@MC3#bg{mCUi5<>a}LJA-+GvSJ}O7CA# zs@FjEPzoq`oJ3L7YI#p8cJ#*$PlhLHpX@9eLsf`ApHe2M% z@?~E(H#dPJQfypYe*Qp~<(is8@9@sMZ+ktS-}}(y;?=dg>U?v?q{~?22T?l32^1XR zN69IK?*wu6%m6y`E(l(7Wh# zwf{hkAP5nn@4xqs`tnE=7ava_apI|C$9T!&#oM=S1xF;kPFs{6YqeN{M9(Qc0hm}t za=Tm&7elb{C-})D?kxm|4uC|suUk76LV%6Uv!U!3Cf|XQ>$o8j&|rcDsC#JX zj#D1_3=`6~Hk*MQFZ^=b(r>E+L5x_IPyxVdv=By~#SNJt!IY>ZE99PctM?q} z_{IGCr59hIMn(s};zeug>btL~tzW+u9EE5#DZ?=9)~(sLbqhE;NwRGBNc-D`R+mf& z@Dk&?3R{z#tgo_9x^w9ROLly@ey`K*>!X`Z5W?#&nsVK_#Y(_Mfl+=~QK$)Gg*J&c zYLtW!MV9Y*d+%qfdyN-jVq(Ah{)fzr^xoFHZ5{S)+jn4$!@IbW6ujz+1vG#>ny)-J zH;;xeilQ9-55b_*c>MyypgYeQySv`G_=nv_y*4GzQd!s5r?-4rhPn6JnYUg#CbZMQ za15^j-J(jwa`YmENKwEeA6ECqFS2E!(`tL;C&_YERW<6SojZ0M4ZpBiS65dZJ-_f< zQGVe_^}!D}e7bs1_!+J+zrKi&VNjISIA{9MFW$WTU-L%-DiZRa49j)hz;POr1u+b! z_Nain-YQ@CbtU*!&6;(x)oSUjuCS_VUr>?|g5h(2X}9#hpMpLqMJ*`q(?y63!<;aA z#Dcj6BMTF0OdN7+Ay=u;p7O%D%ZrA4k3V?pOIyDE={NGNyu1Nlez}ZR{PpsXcYS?h zBgU!&RX=|C{=4U%eH!$2^#Ozi9Y3)su4GV5MuNc-Wo0?uWYk;D8mmReYqgYL7eYlQ zibVSe!Z5$RwXU0dQn11LqlUzON+{mU{y3TyyogFeLgSv zTZ;ilt+Yhz<+C!QO-NP%L@3Ux$w}5)O{|6m>XMP_&L9Y9=yV*Z7o*MQ6rTBb*PSn~ zu{pfpw{-C(m;P(P0&3hnv%s3#I=Yq?E~BP`04f+i{Lll9jSb-MF8F7>BRv%R=JQ6J zFeZfplY;`mgwyJIgNf4`LR2M@{@K0X{?YQ?OTOMM99{|K(4j-WTJ^O-uLp;UlA{Ot z$g&c)J#x?p-+TAnk3M`K{9g4VjEgePosuRM7MV7g?@y;LmHkv_xS8f zPfFM8c))5sB69c{Tc_U@0Cb;PBOtFvg;P{Qm|PW$Je~<0Wg`*Y9d|y8M60`G9n5;@x-OOG!xv zhw6h5K6vuUCl@aI4^|bSSh08Sb=O{VEQT z4i49brO3yjH92N7xq? zo(luLAZ%%F-m_=7dK)un@Zf%geNHVc&A*vtu3ftpsG_B2{RsP<><&kGhU>XT+Wr4@ ziR|h3BkXgks;mqnWLXaMqR2zibWgY+VIMrIdtdlLK#uPfq2JfFBs*ZhfIb(|^dpoc zY4fH{;s21Q_c}qZqA1~=jZvke`w{jzZBh~bO4=s~g4gQ>s?Is*+a=Z8#~FcJJ?#DHT#Gf$qaHyF$&<5~0P8}x>se%dI@a?gUfDO0Bc zRTCyopbKyGfwX>veMR(mkgV)%yWL5>B|SH9?%cUweEEgX>pgU_w2G!5^!yi&<1`x0 zNi%1T8dbV_^=j&4`w{;2q7O4fMMY<3W(FmRKH$P}d`wKt_uqd94i$ZZaKrlbI-Q=L zW#Di+4F)4ZXvg+#{Rsbh$+En0!}_2k*M?MAQ&Z!1ySJ2W?zw8?a5xeY5-DaoEp2ny zS(e?r=_f)+e>n5kOMTQm7^#$D7&a{}{TH{0%QkOvxm-joN7QO{^tS%;r@pe%O%HI6 zj)`H}&{Wsj(z1Q~RyC36^#LfW)v92np}zi4-I4zP+JgfE000mKK>uHRqZ9xD00000 d00000_$g05eC@HB`+ooc002ovPDHLkV1ggJ)A|4a literal 0 HcmV?d00001 diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/Square44x44Logo.png b/test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..844b60c201cf8c1eb46866ac5bee1def5e5e6a24 GIT binary patch literal 2793 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 bR~Z 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 WwDLL`=mUcOt0oOr5U&t32>3tVaPEr$ literal 0 HcmV?d00001 diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/logo.png b/test/PackageManager/data/PackageManager.Test.M.Black.msix/Assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fd2293e7bd8621a23122c5d65ddcba9ed2dd8f45 GIT binary patch literal 3138 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 + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {39277b4c-4fb5-45f6-b0aa-ee8086590cda} + Win32Proj + PackageManager.Test.M.Black.Msix + en-US + 16.0 + 10.0.22621.0 + 10.0.17763.0 + 10.0 + + + Application + v143 + Unicode + + + true + + + false + + + PackageManager.Test.M.Black + + + PackageManager.Test.M.Black + + + PackageManager.Test.M.Black + + + PackageManager.Test.M.Black + + + PackageManager.Test.M.Black + + + PackageManager.Test.M.Black + + + + + + + + + + + + + + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + _WINDOWS;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories); + + + Windows + false + %(AdditionalLibraryDirectories) + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + WIN32;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + + Create + + + + + + + + + + PackageManager.Test.M.Black.msix + PackageManager.Test.M.Black + $(TargetBasename) + $(OutDir)$(ProjectName) + $(TargetExeDir)\$(TargetExe).exe + + + + appxmanifest.xml + + + appxmanifest.xml + + + appxmanifest.xml + + + + + + $(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/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.msix.vcxproj.filters b/test/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.msix.vcxproj.filters new file mode 100644 index 0000000000..008c8045a6 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.msix.vcxproj.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 + + + {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 + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.vcxproj.filters b/test/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Black.msix/PackageManager.Test.M.Black.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/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-arm64.xml b/test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-arm64.xml new file mode 100644 index 0000000000..5905f6985b --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-arm64.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Black + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-x64.xml b/test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-x64.xml new file mode 100644 index 0000000000..e7a465393f --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-x64.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Black + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-x86.xml b/test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-x86.xml new file mode 100644 index 0000000000..ee06c33eea --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Black.msix/appxmanifest-x86.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Black + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/logo.png b/test/PackageManager/data/PackageManager.Test.M.Black.msix/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd7c0ce4d75499f6bcf2224412a39a23d5298a3 GIT binary patch literal 5632 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 O#tu8o`e9I1 + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/pch.cpp b/test/PackageManager/data/PackageManager.Test.M.Black.msix/pch.cpp new file mode 100644 index 0000000000..a77728ba07 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Black.msix/pch.cpp @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/pch.h b/test/PackageManager/data/PackageManager.Test.M.Black.msix/pch.h new file mode 100644 index 0000000000..c32e747e30 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Black.msix/pch.h @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#include + +#include +#include +#include + +#include +#include +#include + +#endif //PCH_H diff --git a/test/PackageManager/data/PackageManager.Test.M.Black.msix/winmain.cpp b/test/PackageManager/data/PackageManager.Test.M.Black.msix/winmain.cpp new file mode 100644 index 0000000000..6203782aee --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Black.msix/winmain.cpp @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) +{ + // Usage: This.Exe + // where + // eventname = event name signaling we should quit. + + // Parse the command line + const auto commandLine{ GetCommandLineW() }; + int argc{}; + PWSTR* argv{ CommandLineToArgvW(commandLine, &argc) }; + RETURN_HR_IF_NULL(E_INVALIDARG, argv); + if (argc >= 2) + { + PCWSTR eventName{ argv[1] }; + wil::unique_event_nothrow endOfTheLine{ ::OpenEventW(SYNCHRONIZE, FALSE, eventName) }; + RETURN_LAST_ERROR_IF_NULL(endOfTheLine); + + auto rc{ WaitForSingleObject(endOfTheLine.get(), INFINITE) }; + if (rc != WAIT_OBJECT_0) + { + if (rc == WAIT_FAILED) + { + LOG_LAST_ERROR(); + } + else + { + LOG_HR_MSG(E_UNEXPECTED, "%u", rc); + } + return rc; + } + } + return 0; +} diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/SplashScreen.png b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/SplashScreen.png new file mode 100644 index 0000000000000000000000000000000000000000..18482131803409efae8c534cb796c1760d49091a GIT binary patch literal 78102 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 literal 0 HcmV?d00001 diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/Square44x44Logo.png b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..844b60c201cf8c1eb46866ac5bee1def5e5e6a24 GIT binary patch literal 2793 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 bR~Z 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 WwDLL`=mUcOt0oOr5U&t32>3tVaPEr$ literal 0 HcmV?d00001 diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/logo.png b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/Assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fd2293e7bd8621a23122c5d65ddcba9ed2dd8f45 GIT binary patch literal 3138 zcmV-I488M-P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D3)e|RK~#9!)RP4Y z15pe_Behdh?|-|xeSrytsTbXWx4VDifv=mz@**PMU}>WW#NXhRJlU0vl;hU8w}a?%tfi0zxC}FMEcH5|aO|7x@G`4NeRAW8ccJ*x4b{oD14cg?|=bq`>gJyN*tYjwr<9l`1-uK}9 z^KWn4gdW~xR&nLqP!)y$uMklS1Ndqj_}}3`uTxQzand(xbhd>iWebwg_<6sKacl(L z$ea{Kq481=^*>OVxwxJ=#q-FRRlIY|Oa_wixS=oGP0_IHZ_aiW8;4c(qx=vaorSsnn|VFsxaHBQ14Mlr$QWkYZZ?-bYr#_p(zfE z6>!I5?7K6-%dZYj-n0zh^?C>df{6bbm>y#s%Qji&E0WH~Rh@Y&-irU{e??Ku)Eo@q zR$R2$OssPs<9n7D__%2cADY`QOmDIh*Ut|qCY41CW}sy3?ZjP4~OJ?!P>wAgE69^bc-w2A|>-}|DQCKADnBHth8a_pruZ%mF zexGAMpz$sR0bmC}5btfcaV50z5ki=m}c zm^}65&iE>4LRq{%Kfhi5J=Sk}ZPFoKXhhd_`cwx4QUKvqMJ2g%4Lb{{xG=j%@}^!Q&19N)wF zNNO7Kw9cSSLyBvtszPrn!OZCmG)|u>%+_y^6t?9wZSs%~;TNos;1RHj9bY zaFE_en3m~N$;QLzl7z)-P+C_k6xnle)9G~J!;bhfo3=^3tgtCz*Iy-2cz$u|qLr#%q}tRa5w}Jm&?UhzxFk@Z`;O)KlmYTyX{VX@cnP#cDu$gt+9_M zMWm*>nk(M@c3#|ZfT7_LvRNHjl0_0UsVXyTOaOw6YAXN`=H>BtkR*vqF1>`g7ta+D zZFqPXn^ofJ4OdcIU1GTEVO;%A0?A~O7xuJ~j0XY8>N*~uk4r!MWj^%QLdx>9;(;xB zEtuRjV^-O#)~vzlbONw()3bP;GFPs{Nmi}A1f4XKPJ#QYv z>2kB`tL1pzW+P2ZK5ETsoXWJyQVMhZ!od^CBvy-snNzDsM8gc7I>sF@#rWLUen8`_ zc^DxUi*fMaL8_~(sjRA^uC9*8=4Q5RJIK=6PW*l!6*q0h&=C9g?Z<33<8(QNc8ZFMc<{cv z`21VC@cUe36MYPI_jB3mFeBlNhPnb+5 z@yTQ|Y}&YyTW`LF{{DXca^>GdmUm|Nv-(RO(9>k1BgBR?3=WxC`$&d89Z?|=0BH=< zniSkFC*S|^Px#O!mtr!T|0RBqq|v4%GJAJ-H@Dq#E3K_37#bX6#>|;4TfUq}AAUq6 z$6zqX{sYIkWN{otk0YlOSV-Yfbt=ic zMayWMH5VjlbW{@|S&?Ot^;5|tZ@m5nSN`p9gwM|X3qHS}2OoY&6ptk(r3?-XGH@nE zXSYgiVFD?cfkXx+rQwzn{BmiO-X;gP?)LIxdz45b{U4c@ucJA20{rBBR>xmPLh1>7ElM`p>+S}XNxPCo}M1qCQ zF8=!I6qZaJ5*j2m@hc^==t-TCu#2q&KGtrFBQtRbyYxC0S{mKhtulHxi)yi;_)B>7 z*%M;^97H)Hw9wVran_V>F(hHP+l8}7qY)l^e_U@P8di`JqS6+>By@-= zIMXSbtWlZ^?Ee`NRZ);-iRNl6ifR(MM77%a)7{N~~xnS1!m8P1&j3=9k! z=7A|wr_k2g%C%QtBb*<^yb#R8uLk(VMmHmIC)tFK9+!y5ZR`mZ@cR=5T-oa2#BgHb z&OWU+pEciT=90x$JT_f4OW90@2Vaiz+@7E)SJIg@3l}aF5ey)iNO1Vb5#H?VV%N@{ zV6c=^QBlcLPd-IB93Hbk>>5mAbNF%F?YtTF@k+mk+YV%SwIf9PNP<`@gFMmDDoZ*( zmxR!Sq6lql-ld(D*a#pX!lyLK+1uLNktK<}d-njwmFteP{xdi*fP}G0U;n}xzW8vG z&p#UC&##>3cz#5VMe`WArej$?M zZFk(x^cgcm*zM`T>o{Ry`gwpJ8OHi0=XI2%A3`aQF z7UTBKLwx>s9X$T>fFSX&!td9sRtXa6REqYFPNAJtI>kMA-7QFrhN0xg8Iz1_En|(; z7TcIpYh_n^n!$iZB$hHP4?gh053*{_YGLEQUH2P4_KA;^Oe9&mW)1CaZTxRQ#sDKx znfqTJp|v|A)~^gm2pl+YK!n*}{ou;xDg4XEn%acT_68EVnH zxs$0BufFmM0587qA|9_t1c`}m0*>F-8k~2bx7)PLxytm|(W9bw&&kdGU)fgR0ud38 zojq3|3PQa-Jycay8aG4ZZ?sSRybDDn5{WP}Jc8fnI~VoN46}U23Iw?cYzs)n^W&d) zp@`_fu3bC%qXk3RAU{+t{>`?=2|N%HuMZsX1y%w6byAP7KFTkn5U7q-$3-(1N?ch}3ohMD6V;y;BZ zaR`%#;!74~CO{rQss{NyO5QYV&nr?p^QB_4QRe&xH&OtOB!BT2nkVKw0Tm1zR_s{o zt%y#m19x(xl~M2RApKOuTz8E;b-W^zJ3N5Q10?DQ + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {ad7d0a19-44b9-41d6-a68a-9fecac28078d} + Win32Proj + PackageManager.Test.M.Blacker.Msix + en-US + 16.0 + 10.0.22621.0 + 10.0.17763.0 + 10.0 + + + Application + v143 + Unicode + + + true + + + false + + + PackageManager.Test.M.Blacker + + + PackageManager.Test.M.Blacker + + + PackageManager.Test.M.Blacker + + + PackageManager.Test.M.Blacker + + + PackageManager.Test.M.Blacker + + + PackageManager.Test.M.Blacker + + + + + + + + + + + + + + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + _WINDOWS;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories); + + + Windows + false + %(AdditionalLibraryDirectories) + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + WIN32;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + + Create + + + + + + + + + + PackageManager.Test.M.Blacker.msix + PackageManager.Test.M.Blacker + $(TargetBasename) + $(OutDir)$(ProjectName) + $(TargetExeDir)\$(TargetExe).exe + + + + appxmanifest.xml + + + appxmanifest.xml + + + appxmanifest.xml + + + + + + $(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/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.msix.vcxproj.filters b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.msix.vcxproj.filters new file mode 100644 index 0000000000..008c8045a6 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.msix.vcxproj.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 + + + {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 + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.vcxproj.filters b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/PackageManager.Test.M.Blacker.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/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-arm64.xml b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-arm64.xml new file mode 100644 index 0000000000..aef1532b99 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-arm64.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Blacker + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-x64.xml b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-x64.xml new file mode 100644 index 0000000000..f228880da1 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-x64.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Blacker + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-x86.xml b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-x86.xml new file mode 100644 index 0000000000..1311717bfd --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/appxmanifest-x86.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Blacker + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/logo.png b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd7c0ce4d75499f6bcf2224412a39a23d5298a3 GIT binary patch literal 5632 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 O#tu8o`e9I1 + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/pch.cpp b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/pch.cpp new file mode 100644 index 0000000000..a77728ba07 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/pch.cpp @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/pch.h b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/pch.h new file mode 100644 index 0000000000..c32e747e30 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/pch.h @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#include + +#include +#include +#include + +#include +#include +#include + +#endif //PCH_H diff --git a/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/winmain.cpp b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/winmain.cpp new file mode 100644 index 0000000000..6203782aee --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Blacker.msix/winmain.cpp @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) +{ + // Usage: This.Exe + // where + // eventname = event name signaling we should quit. + + // Parse the command line + const auto commandLine{ GetCommandLineW() }; + int argc{}; + PWSTR* argv{ CommandLineToArgvW(commandLine, &argc) }; + RETURN_HR_IF_NULL(E_INVALIDARG, argv); + if (argc >= 2) + { + PCWSTR eventName{ argv[1] }; + wil::unique_event_nothrow endOfTheLine{ ::OpenEventW(SYNCHRONIZE, FALSE, eventName) }; + RETURN_LAST_ERROR_IF_NULL(endOfTheLine); + + auto rc{ WaitForSingleObject(endOfTheLine.get(), INFINITE) }; + if (rc != WAIT_OBJECT_0) + { + if (rc == WAIT_FAILED) + { + LOG_LAST_ERROR(); + } + else + { + LOG_HR_MSG(E_UNEXPECTED, "%u", rc); + } + return rc; + } + } + return 0; +} diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/SplashScreen.png b/test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/SplashScreen.png new file mode 100644 index 0000000000000000000000000000000000000000..18482131803409efae8c534cb796c1760d49091a GIT binary patch literal 78102 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 literal 0 HcmV?d00001 diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/Square44x44Logo.png b/test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..844b60c201cf8c1eb46866ac5bee1def5e5e6a24 GIT binary patch literal 2793 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 bR~Z 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 WwDLL`=mUcOt0oOr5U&t32>3tVaPEr$ literal 0 HcmV?d00001 diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/logo.png b/test/PackageManager/data/PackageManager.Test.M.White.msix/Assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fd2293e7bd8621a23122c5d65ddcba9ed2dd8f45 GIT binary patch literal 3138 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 + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {28dcf9ce-d9f4-4a7d-8ad1-f2efc0d3b4df} + Win32Proj + PackageManager.Test.M.White.Msix + en-US + 16.0 + 10.0.22621.0 + 10.0.17763.0 + 10.0 + + + Application + v143 + Unicode + + + true + + + false + + + PackageManager.Test.M.White + + + PackageManager.Test.M.White + + + PackageManager.Test.M.White + + + PackageManager.Test.M.White + + + PackageManager.Test.M.White + + + PackageManager.Test.M.White + + + + + + + + + + + + + + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + _WINDOWS;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories); + + + Windows + false + %(AdditionalLibraryDirectories) + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + WIN32;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + + Create + + + + + + + + + + PackageManager.Test.M.White.msix + PackageManager.Test.M.White + $(TargetBasename) + $(OutDir)$(ProjectName) + $(TargetExeDir)\$(TargetExe).exe + + + + appxmanifest.xml + + + appxmanifest.xml + + + appxmanifest.xml + + + + + + $(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/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.msix.vcxproj.filters b/test/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.msix.vcxproj.filters new file mode 100644 index 0000000000..008c8045a6 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.msix.vcxproj.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 + + + {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 + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.vcxproj.filters b/test/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.White.msix/PackageManager.Test.M.White.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/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-arm64.xml b/test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-arm64.xml new file mode 100644 index 0000000000..37eb2f2970 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-arm64.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.White + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-x64.xml b/test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-x64.xml new file mode 100644 index 0000000000..39f2b8fe92 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-x64.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.White + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-x86.xml b/test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-x86.xml new file mode 100644 index 0000000000..50a82c629e --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.White.msix/appxmanifest-x86.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.White + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/logo.png b/test/PackageManager/data/PackageManager.Test.M.White.msix/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd7c0ce4d75499f6bcf2224412a39a23d5298a3 GIT binary patch literal 5632 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 O#tu8o`e9I1 + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/pch.cpp b/test/PackageManager/data/PackageManager.Test.M.White.msix/pch.cpp new file mode 100644 index 0000000000..a77728ba07 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.White.msix/pch.cpp @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/pch.h b/test/PackageManager/data/PackageManager.Test.M.White.msix/pch.h new file mode 100644 index 0000000000..c32e747e30 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.White.msix/pch.h @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#include + +#include +#include +#include + +#include +#include +#include + +#endif //PCH_H diff --git a/test/PackageManager/data/PackageManager.Test.M.White.msix/winmain.cpp b/test/PackageManager/data/PackageManager.Test.M.White.msix/winmain.cpp new file mode 100644 index 0000000000..6203782aee --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.White.msix/winmain.cpp @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) +{ + // Usage: This.Exe + // where + // eventname = event name signaling we should quit. + + // Parse the command line + const auto commandLine{ GetCommandLineW() }; + int argc{}; + PWSTR* argv{ CommandLineToArgvW(commandLine, &argc) }; + RETURN_HR_IF_NULL(E_INVALIDARG, argv); + if (argc >= 2) + { + PCWSTR eventName{ argv[1] }; + wil::unique_event_nothrow endOfTheLine{ ::OpenEventW(SYNCHRONIZE, FALSE, eventName) }; + RETURN_LAST_ERROR_IF_NULL(endOfTheLine); + + auto rc{ WaitForSingleObject(endOfTheLine.get(), INFINITE) }; + if (rc != WAIT_OBJECT_0) + { + if (rc == WAIT_FAILED) + { + LOG_LAST_ERROR(); + } + else + { + LOG_HR_MSG(E_UNEXPECTED, "%u", rc); + } + return rc; + } + } + return 0; +} diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/SplashScreen.png b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/SplashScreen.png new file mode 100644 index 0000000000000000000000000000000000000000..18482131803409efae8c534cb796c1760d49091a GIT binary patch literal 78102 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 literal 0 HcmV?d00001 diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/Square44x44Logo.png b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..844b60c201cf8c1eb46866ac5bee1def5e5e6a24 GIT binary patch literal 2793 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 bR~Z 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 WwDLL`=mUcOt0oOr5U&t32>3tVaPEr$ literal 0 HcmV?d00001 diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/logo.png b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/Assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fd2293e7bd8621a23122c5d65ddcba9ed2dd8f45 GIT binary patch literal 3138 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 + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {ac79b8ff-4c27-4326-ad20-bbc70059ff51} + Win32Proj + PackageManager.Test.M.Whiter.Msix + en-US + 16.0 + 10.0.22621.0 + 10.0.17763.0 + 10.0 + + + Application + v143 + Unicode + + + true + + + false + + + PackageManager.Test.M.Whiter + + + PackageManager.Test.M.Whiter + + + PackageManager.Test.M.Whiter + + + PackageManager.Test.M.Whiter + + + PackageManager.Test.M.Whiter + + + PackageManager.Test.M.Whiter + + + + + + + + + + + + + + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + _WINDOWS;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories); + + + Windows + false + %(AdditionalLibraryDirectories) + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + WIN32;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + + Create + + + + + + + + + + PackageManager.Test.M.Whiter.msix + PackageManager.Test.M.Whiter + $(TargetBasename) + $(OutDir)$(ProjectName) + $(TargetExeDir)\$(TargetExe).exe + + + + appxmanifest.xml + + + appxmanifest.xml + + + appxmanifest.xml + + + + + + $(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/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.msix.vcxproj.filters b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.msix.vcxproj.filters new file mode 100644 index 0000000000..008c8045a6 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.msix.vcxproj.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 + + + {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 + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.vcxproj.filters b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.vcxproj.filters new file mode 100644 index 0000000000..2df21c891a --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/PackageManager.Test.M.Whiter.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/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-arm64.xml b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-arm64.xml new file mode 100644 index 0000000000..7649cf2a96 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-arm64.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Whiter + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-x64.xml b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-x64.xml new file mode 100644 index 0000000000..95d68f9f88 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-x64.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Whiter + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-x86.xml b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-x86.xml new file mode 100644 index 0000000000..f2de7b3f59 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/appxmanifest-x86.xml @@ -0,0 +1,49 @@ + + + + + + + + Test.PackageManager.M.Whiter + Microsoft Corporation + Assets\logo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/logo.png b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/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/PackageManager/data/PackageManager.Test.M.Whiter.msix/pch.cpp b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/pch.cpp new file mode 100644 index 0000000000..a77728ba07 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/pch.cpp @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/pch.h b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/pch.h new file mode 100644 index 0000000000..c32e747e30 --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/pch.h @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#include + +#include +#include +#include + +#include +#include +#include + +#endif //PCH_H diff --git a/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/winmain.cpp b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/winmain.cpp new file mode 100644 index 0000000000..6203782aee --- /dev/null +++ b/test/PackageManager/data/PackageManager.Test.M.Whiter.msix/winmain.cpp @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" + +int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) +{ + // Usage: This.Exe + // where + // eventname = event name signaling we should quit. + + // Parse the command line + const auto commandLine{ GetCommandLineW() }; + int argc{}; + PWSTR* argv{ CommandLineToArgvW(commandLine, &argc) }; + RETURN_HR_IF_NULL(E_INVALIDARG, argv); + if (argc >= 2) + { + PCWSTR eventName{ argv[1] }; + wil::unique_event_nothrow endOfTheLine{ ::OpenEventW(SYNCHRONIZE, FALSE, eventName) }; + RETURN_LAST_ERROR_IF_NULL(endOfTheLine); + + auto rc{ WaitForSingleObject(endOfTheLine.get(), INFINITE) }; + if (rc != WAIT_OBJECT_0) + { + if (rc == WAIT_FAILED) + { + LOG_LAST_ERROR(); + } + else + { + LOG_HR_MSG(E_UNEXPECTED, "%u", rc); + } + return rc; + } + } + return 0; +} diff --git a/test/PowerNotifications/packages.config b/test/PowerNotifications/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/PowerNotifications/packages.config +++ b/test/PowerNotifications/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/PushNotificationTests/packages.config b/test/PushNotificationTests/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/PushNotificationTests/packages.config +++ b/test/PushNotificationTests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/TestApps/AccessControlTestApp/packages.config b/test/TestApps/AccessControlTestApp/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/TestApps/AccessControlTestApp/packages.config +++ b/test/TestApps/AccessControlTestApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/TestApps/AppLifecycleTestApp/packages.config b/test/TestApps/AppLifecycleTestApp/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/TestApps/AppLifecycleTestApp/packages.config +++ b/test/TestApps/AppLifecycleTestApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/TestApps/ManualTestApp/packages.config b/test/TestApps/ManualTestApp/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/TestApps/ManualTestApp/packages.config +++ b/test/TestApps/ManualTestApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/TestApps/PushNotificationsDemoApp/packages.config b/test/TestApps/PushNotificationsDemoApp/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/TestApps/PushNotificationsDemoApp/packages.config +++ b/test/TestApps/PushNotificationsDemoApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/TestApps/PushNotificationsTestApp/packages.config b/test/TestApps/PushNotificationsTestApp/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/TestApps/PushNotificationsTestApp/packages.config +++ b/test/TestApps/PushNotificationsTestApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/TestApps/ToastNotificationsDemoApp/packages.config b/test/TestApps/ToastNotificationsDemoApp/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/TestApps/ToastNotificationsDemoApp/packages.config +++ b/test/TestApps/ToastNotificationsDemoApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/TestApps/ToastNotificationsTestApp/packages.config b/test/TestApps/ToastNotificationsTestApp/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/TestApps/ToastNotificationsTestApp/packages.config +++ b/test/TestApps/ToastNotificationsTestApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/VersionInfo/packages.config b/test/VersionInfo/packages.config index 1117ac430f..dc444ff576 100644 --- a/test/VersionInfo/packages.config +++ b/test/VersionInfo/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/inc/WindowsAppRuntime.Test.Package.h b/test/inc/WindowsAppRuntime.Test.Package.h index cebfd74e4e..5ce92a839f 100644 --- a/test/inc/WindowsAppRuntime.Test.Package.h +++ b/test/inc/WindowsAppRuntime.Test.Package.h @@ -8,6 +8,7 @@ #include #include +#include #include #define WINDOWSAPPRUNTIME_TEST_METADATA_VERSION 0x0004000107AF014DLLu @@ -126,19 +127,36 @@ namespace DeploymentWindowsAppRuntimeSingleton constexpr PCWSTR c_PackageFullName = WINDOWSAPPRUNTIME_TEST_MSIX_DEPLOYMENT_SINGLETON_PACKAGE_NAME L"_" WINDOWSAPPRUNTIME_TEST_METADATA_VERSION_STRING L"_neutral__" WINDOWSAPPRUNTIME_TEST_MSIX_PUBLISHERID; } -inline std::wstring GetPackagePath(PCWSTR packageFullName) +template +inline T GetPackagePath(PCWSTR packageFullName) { UINT32 pathLength{}; - const auto rc{ GetPackagePathByFullName(packageFullName, &pathLength, nullptr) }; + const auto rc{ ::GetPackagePathByFullName(packageFullName, &pathLength, nullptr) }; if (rc == ERROR_NOT_FOUND) { - return std::wstring(); + return T{}; } VERIFY_ARE_EQUAL(ERROR_INSUFFICIENT_BUFFER, rc); - auto path = wil::make_process_heap_string(nullptr, pathLength); + auto path{ wil::make_process_heap_string(nullptr, pathLength) }; VERIFY_ARE_EQUAL(ERROR_SUCCESS, GetPackagePathByFullName(packageFullName, &pathLength, path.get())); - return std::wstring(path.get()); + return T{ path.get() }; +} + +template +inline T GetStagedPackagePath(PCWSTR packageFullName) +{ + UINT32 pathLength{}; + const auto rc{ ::GetStagedPackagePathByFullName(packageFullName, &pathLength, nullptr) }; + if (rc == ERROR_NOT_FOUND) + { + return T{}; + } + + VERIFY_ARE_EQUAL(ERROR_INSUFFICIENT_BUFFER, rc); + auto path{ wil::make_process_heap_string(nullptr, pathLength) }; + VERIFY_ARE_EQUAL(ERROR_SUCCESS, ::GetStagedPackagePathByFullName(packageFullName, &pathLength, path.get())); + return T{ path.get() }; } #if defined(__APPMODEL_IDENTITY_H) @@ -188,19 +206,6 @@ inline bool IsPackageRegistered(PCWSTR packageFullName) inline bool IsPackageStaged(PCWSTR packageFullName) { -#if 0 - UINT32 pathLength{}; - const auto rc{ ::GetStagedPackagePathByFullName(packageFullName, &pathLength, nullptr) }; - if (rc == ERROR_INSUFFICIENT_BUFFER) - { - return true; - } - else if (rc == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) - { - return false; - } - THROW_WIN32(rc); -#else // Check if the package is staged PackageOrigin packageOrigin{}; const auto rc{ GetStagedPackageOrigin(packageFullName, &packageOrigin) }; @@ -213,7 +218,6 @@ inline bool IsPackageStaged(PCWSTR packageFullName) return false; } THROW_WIN32(rc); -#endif } inline bool IsPackageAvailable(PCWSTR packageFullName) @@ -229,21 +233,26 @@ inline std::filesystem::path GetMsixPackagePath(PCWSTR packageDirName) { // Build the target package's .msix filename. It's under the Solution's $(OutDir) // NOTE: It could live in ...\Something.msix\... or ...\Something\... - auto solutionOutDirPath = ::Test::FileSystem::GetSolutionOutDirPath(); - // + auto solutionOutDirPath{ ::Test::FileSystem::GetSolutionOutDirPath() }; + + // Filename is packagedirName plus .msix (if not already present) + std::filesystem::path filename{ packageDirName }; + if (CompareStringOrdinal(filename.extension().c_str(), -1, L".msix", -1, TRUE) != CSTR_EQUAL) + { + filename += L".msix"; + } + // Look in ...\Something.msix\... auto msix(solutionOutDirPath); msix /= packageDirName; msix += L".msix"; - msix /= packageDirName; - msix += L".msix"; + msix /= filename; if (!std::filesystem::is_regular_file(msix)) { // Look in ...\Something\... msix = solutionOutDirPath; msix /= packageDirName; - msix /= packageDirName; - msix += L".msix"; + msix /= filename; WIN32_FILE_ATTRIBUTE_DATA data{}; const auto ok{ GetFileAttributesExW(msix.c_str(), GetFileExInfoStandard, &data) }; const auto lastError{ ::GetLastError() }; @@ -264,17 +273,39 @@ inline winrt::Windows::Foundation::Uri GetMsixPackageUri(PCWSTR packageDirName) return winrt::Windows::Foundation::Uri{ path.c_str() }; } +inline std::filesystem::path GetAppxManifestPackagePath(PCWSTR packageFullName) +{ + auto path{ GetStagedPackagePath(packageFullName) }; + return path / L"AppxManifest.xml"; +} + +inline winrt::Windows::Foundation::Uri GetAppxManifestPackageUri(PCWSTR packageFullName) +{ + auto path{ GetAppxManifestPackagePath(packageFullName) }; + return winrt::Windows::Foundation::Uri{ path.c_str() }; +} + inline void AddPackage(PCWSTR packageDirName, PCWSTR packageFullName) { auto msixUri{ GetMsixPackageUri(packageDirName) }; - // Install the package winrt::Windows::Management::Deployment::PackageManager packageManager; auto options{ winrt::Windows::Management::Deployment::DeploymentOptions::None }; auto deploymentResult{ packageManager.AddPackageAsync(msixUri, nullptr, options).get() }; 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) +{ + auto msixUri{ GetMsixPackageUri(packageDirName) }; + + 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())); +} + inline void AddPackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName) { if (IsPackageRegistered(packageFullName)) @@ -288,11 +319,23 @@ inline void AddPackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName) } } +inline void AddPackageDeferIfNecessary(PCWSTR packageDirName, PCWSTR packageFullName) +{ + if (IsPackageRegistered(packageFullName)) + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddPackageDeferIfNecessary: %s already registered", packageFullName)); + } + else + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"AddPackageDeferIfNecessary: %s not registered, adding...", packageFullName)); + AddPackageDefer(packageDirName, packageFullName); + } +} + inline void StagePackage(PCWSTR packageDirName, PCWSTR packageFullName) { auto msixUri{ GetMsixPackageUri(packageDirName) }; - // Install the package winrt::Windows::Management::Deployment::PackageManager packageManager; auto options{ winrt::Windows::Management::Deployment::DeploymentOptions::None }; auto deploymentResult{ packageManager.StagePackageAsync(msixUri, nullptr, options).get() }; @@ -312,6 +355,29 @@ inline void StagePackageIfNecessary(PCWSTR packageDirName, PCWSTR packageFullNam } } +inline void RegisterPackage(PCWSTR packageFullName) +{ + winrt::hstring mainPackageFullName{ packageFullName }; + + winrt::Windows::Management::Deployment::PackageManager packageManager; + auto options{ winrt::Windows::Management::Deployment::DeploymentOptions::None }; + auto deploymentResult{ packageManager.RegisterPackageByFullNameAsync(mainPackageFullName, nullptr, options).get() }; + VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"RegisterPackageByFullNameAsync('%s') = 0x%0X %s", packageFullName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); +} + +inline void RegisterPackageIfNecessary(PCWSTR packageFullName) +{ + if (IsPackageRegistered(packageFullName)) + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"RegisterPackageIfNecessary: %s already registered", packageFullName)); + } + else + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"RegisterPackageIfNecessary: %s not registered, adding...", packageFullName)); + RegisterPackage(packageFullName); + } +} + inline void RemovePackage(PCWSTR packageFullName) { winrt::Windows::Management::Deployment::PackageManager packageManager; @@ -330,6 +396,63 @@ inline void RemovePackageIfNecessary(PCWSTR packageFullName) } } +inline bool IsPackageProvisioned(PCWSTR packageFamilyName) +{ + // We have no random access check for a specific package family + // so we'll have to brute force it by scanning the list of all + // provisioned packages for the one we're interested in + winrt::Windows::Management::Deployment::PackageManager packageManager; + const auto provisionedPackages{ packageManager.FindProvisionedPackages() }; + for (const winrt::Windows::ApplicationModel::Package& provisionedPackage: provisionedPackages) + { + if (CompareStringOrdinal(packageFamilyName, -1, provisionedPackage.Id().FamilyName().c_str(), -1, TRUE) == CSTR_EQUAL) + { + return true; + } + } + return false; +} + +inline void ProvisionPackage(PCWSTR packageFamilyName) +{ + winrt::Windows::Management::Deployment::PackageManager packageManager; + auto deploymentResult{ packageManager.ProvisionPackageForAllUsersAsync(packageFamilyName).get() }; + VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"ProvisionPackageForAllUsersAsync('%s') = 0x%0X %s", packageFamilyName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); +} + +inline void ProvisionPackageIfNecessary(PCWSTR packageFamilyName) +{ + if (IsPackageProvisioned(packageFamilyName)) + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"ProvisionPackageIfNecessary: %s already provisioned", packageFamilyName)); + } + else + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"ProvisionPackageIfNecessary: %s not provisioned, provisioning...", packageFamilyName)); + ProvisionPackage(packageFamilyName); + } +} + +inline void DeprovisionPackage(PCWSTR packageFamilyName) +{ + winrt::Windows::Management::Deployment::PackageManager packageManager; + auto deploymentResult{ packageManager.DeprovisionPackageForAllUsersAsync(packageFamilyName).get() }; + VERIFY_SUCCEEDED(deploymentResult.ExtendedErrorCode(), WEX::Common::String().Format(L"DeprovisionPackageForAllUsersAsync('%s') = 0x%0X %s", packageFamilyName, deploymentResult.ExtendedErrorCode(), deploymentResult.ErrorText().c_str())); +} + +inline void DeprovisionPackageIfNecessary(PCWSTR packageFamilyName) +{ + if (IsPackageProvisioned(packageFamilyName)) + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"DeprovisionPackageIfNecessary: %s is provisioned, deprovisioning...", packageFamilyName)); + DeprovisionPackage(packageFamilyName); + } + else + { + WEX::Logging::Log::Comment(WEX::Common::String().Format(L"DeprovisionPackageIfNecessary: %s not provisioned", packageFamilyName)); + } +} + inline void AddPackage_DynamicDependencyLifetimeManager() { AddPackage(Test::Packages::DynamicDependencyLifetimeManager::c_PackageDirName, Test::Packages::DynamicDependencyLifetimeManager::c_PackageFullName); diff --git a/tools/ProjectTemplates/test.cpp.dll.taef/packages.config b/tools/ProjectTemplates/test.cpp.dll.taef/packages.config index ecebfdd18e..3a041cbe69 100644 --- a/tools/ProjectTemplates/test.cpp.dll.taef/packages.config +++ b/tools/ProjectTemplates/test.cpp.dll.taef/packages.config @@ -3,7 +3,7 @@ - + From 421d95d7bc8999b2785a1e9994c918d68556f62c Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 27 Jun 2024 00:47:15 -0700 Subject: [PATCH 2/2] Added #include sddl.h as WindowsAppRuntime.sln was fine for all users but the WindowsAppRuntimeInstaller.sln wasn't. Better to be self-fulfilling in case code changes again in the future to avoid unknown-symbol pains --- dev/Common/Security.User.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/Common/Security.User.h b/dev/Common/Security.User.h index c37fdafcac..9916be05b7 100644 --- a/dev/Common/Security.User.h +++ b/dev/Common/Security.User.h @@ -4,6 +4,8 @@ #ifndef __SECURITY_USER_H #define __SECURITY_USER_H +#include + namespace Security::User { inline bool IsLocalSystem(HANDLE token = nullptr)