From 6c16c79afe64cc4f92efd7be3b66f5aac9eef602 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Sat, 26 Jun 2021 00:13:34 -0700 Subject: [PATCH 01/53] Add c# in proc winrt wrapper and projection --- src/AppInstallerCLI.sln | 147 +++++ .../AppInstallerCLIE2ETests.csproj | 13 +- .../ComInterfaceTests.cs | 42 ++ .../CatalogPackage.cpp | 43 ++ .../CatalogPackage.h | 24 + .../ConnectResult.cpp | 17 + .../ConnectResult.h | 15 + .../CreateCompositePackageCatalogOptions.cpp | 21 + .../CreateCompositePackageCatalogOptions.h | 29 + .../FindPackagesOptions.cpp | 25 + .../FindPackagesOptions.h | 30 + .../FindPackagesResult.cpp | 21 + .../FindPackagesResult.h | 16 + .../InstallOptions.cpp | 90 +++ .../InstallOptions.h | 44 ++ .../InstallResult.cpp | 25 + .../InstallResult.h | 17 + .../MatchResult.cpp | 17 + .../MatchResult.h | 15 + ...osoft.Management.Deployment.Client.vcxproj | 195 +++++++ ...Microsoft_Management_Deployment_Client.def | 3 + .../PackageCatalog.cpp | 26 + .../PackageCatalog.h | 17 + .../PackageCatalogInfo.cpp | 37 ++ .../PackageCatalogInfo.h | 20 + .../PackageCatalogReference.cpp | 25 + .../PackageCatalogReference.h | 17 + .../PackageManager.cpp | 36 ++ .../PackageManager.h | 27 + .../PackageManager.idl | 540 ++++++++++++++++++ .../PackageMatchFilter.cpp | 33 ++ .../PackageMatchFilter.h | 32 ++ .../PackageVersionId.cpp | 21 + .../PackageVersionId.h | 16 + .../PackageVersionInfo.cpp | 42 ++ .../PackageVersionInfo.h | 21 + .../PropertySheet.props | 16 + .../packages.config | 4 + .../pch.cpp | 3 + .../pch.h | 7 + .../readme.txt | 23 + ...ft.Management.Deployment.Projection.csproj | 23 + .../PackageManager.idl | 4 + 43 files changed, 1838 insertions(+), 1 deletion(-) create mode 100644 src/AppInstallerCLIE2ETests/ComInterfaceTests.cs create mode 100644 src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/CatalogPackage.h create mode 100644 src/Microsoft.Management.Deployment.Client/ConnectResult.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/ConnectResult.h create mode 100644 src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h create mode 100644 src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h create mode 100644 src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/FindPackagesResult.h create mode 100644 src/Microsoft.Management.Deployment.Client/InstallOptions.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/InstallOptions.h create mode 100644 src/Microsoft.Management.Deployment.Client/InstallResult.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/InstallResult.h create mode 100644 src/Microsoft.Management.Deployment.Client/MatchResult.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/MatchResult.h create mode 100644 src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj create mode 100644 src/Microsoft.Management.Deployment.Client/Microsoft_Management_Deployment_Client.def create mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalog.h create mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.h create mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h create mode 100644 src/Microsoft.Management.Deployment.Client/PackageManager.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/PackageManager.h create mode 100644 src/Microsoft.Management.Deployment.Client/PackageManager.idl create mode 100644 src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h create mode 100644 src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/PackageVersionId.h create mode 100644 src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h create mode 100644 src/Microsoft.Management.Deployment.Client/PropertySheet.props create mode 100644 src/Microsoft.Management.Deployment.Client/packages.config create mode 100644 src/Microsoft.Management.Deployment.Client/pch.cpp create mode 100644 src/Microsoft.Management.Deployment.Client/pch.h create mode 100644 src/Microsoft.Management.Deployment.Client/readme.txt create mode 100644 src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index c40948d17d..0cba406aca 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -123,6 +123,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServe {1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Management.Deployment.Projection", "Microsoft.Management.Deployment.Projection\Microsoft.Management.Deployment.Projection.csproj", "{EAF57FF2-A05A-4E73-80A7-CF686CE2D340}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ManifestSchema\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4 @@ -145,20 +149,26 @@ Global ManifestSchema\ManifestSchema.vcxitems*{fb313532-38b0-4676-9303-ab200aa13576}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|ARM = Debug|ARM Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Fuzzing|Any CPU = Fuzzing|Any CPU Fuzzing|ARM = Fuzzing|ARM Fuzzing|ARM64 = Fuzzing|ARM64 Fuzzing|x64 = Fuzzing|x64 Fuzzing|x86 = Fuzzing|x86 + Release|Any CPU = Release|Any CPU Release|ARM = Release|ARM Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.ActiveCfg = Debug|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.Build.0 = Debug|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.Deploy.0 = Debug|ARM @@ -171,10 +181,16 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.ActiveCfg = Debug|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Build.0 = Debug|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Deploy.0 = Debug|x86 + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.Build.0 = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x64.ActiveCfg = Release|x64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x86.ActiveCfg = Release|x86 + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.Build.0 = Release|Any CPU + {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.Deploy.0 = Release|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.Build.0 = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.Deploy.0 = Release|ARM @@ -187,6 +203,7 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.ActiveCfg = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Build.0 = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Deploy.0 = Release|x86 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.ActiveCfg = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.Build.0 = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -195,10 +212,13 @@ Global {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x64.Build.0 = Debug|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.ActiveCfg = Debug|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.Build.0 = Debug|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|Any CPU.Build.0 = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x64.ActiveCfg = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x86.ActiveCfg = Release|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|Any CPU.ActiveCfg = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM.Build.0 = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -207,6 +227,7 @@ Global {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x64.Build.0 = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.ActiveCfg = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.Build.0 = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|Any CPU.ActiveCfg = Debug|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.ActiveCfg = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.Build.0 = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -215,10 +236,13 @@ Global {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x64.Build.0 = Debug|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.ActiveCfg = Debug|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.Build.0 = Debug|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|Any CPU.Build.0 = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM.ActiveCfg = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x64.ActiveCfg = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x86.ActiveCfg = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|Any CPU.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM.ActiveCfg = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM.Build.0 = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -227,6 +251,7 @@ Global {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x64.Build.0 = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.Build.0 = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.ActiveCfg = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.Build.0 = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -235,10 +260,13 @@ Global {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x64.Build.0 = Debug|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.ActiveCfg = Debug|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.Build.0 = Debug|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|Any CPU.Build.0 = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM.ActiveCfg = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x64.ActiveCfg = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x86.ActiveCfg = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|Any CPU.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM.ActiveCfg = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM.Build.0 = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -247,22 +275,27 @@ Global {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x64.Build.0 = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.Build.0 = Release|Win32 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|Any CPU.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM64.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.ActiveCfg = Debug|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.Build.0 = Debug|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.Build.0 = Debug|Win32 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|Any CPU.ActiveCfg = Release|x64 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|Any CPU.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM64.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x86.ActiveCfg = Release|Win32 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|Any CPU.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM64.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.Build.0 = Release|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|Any CPU.ActiveCfg = Debug|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.ActiveCfg = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.Build.0 = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -271,11 +304,13 @@ Global {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x64.Build.0 = Debug|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x86.ActiveCfg = Debug|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x86.Build.0 = Debug|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|ARM.ActiveCfg = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x64.Build.0 = Fuzzing|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x86.ActiveCfg = Release|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|Any CPU.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM.ActiveCfg = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM.Build.0 = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -284,6 +319,7 @@ Global {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x64.Build.0 = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.Build.0 = Release|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.ActiveCfg = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.Build.0 = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -292,11 +328,13 @@ Global {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x64.Build.0 = Debug|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.ActiveCfg = Debug|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.Build.0 = Debug|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM.ActiveCfg = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.Build.0 = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x86.ActiveCfg = Release|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|Any CPU.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM.ActiveCfg = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM.Build.0 = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -305,6 +343,7 @@ Global {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x64.Build.0 = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.Build.0 = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.Debug|Any CPU.ActiveCfg = Debug|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.ActiveCfg = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.Build.0 = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -313,10 +352,13 @@ Global {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x64.Build.0 = Debug|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.ActiveCfg = Debug|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.Build.0 = Debug|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|Any CPU.Build.0 = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x64.ActiveCfg = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x86.ActiveCfg = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.Release|Any CPU.ActiveCfg = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM.Build.0 = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -325,6 +367,7 @@ Global {FB313532-38B0-4676-9303-AB200AA13576}.Release|x64.Build.0 = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.ActiveCfg = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.Build.0 = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|Any CPU.ActiveCfg = Debug|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.ActiveCfg = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.Build.0 = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -333,10 +376,13 @@ Global {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x64.Build.0 = Debug|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.ActiveCfg = Debug|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.Build.0 = Debug|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|Any CPU.Build.0 = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x64.ActiveCfg = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x86.ActiveCfg = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|Any CPU.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM.Build.0 = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -345,22 +391,29 @@ Global {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x64.Build.0 = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.Build.0 = Release|Win32 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|Any CPU.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM64.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.ActiveCfg = Debug|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.Build.0 = Debug|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.Build.0 = Debug|x86 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|Any CPU.ActiveCfg = Release|x64 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|Any CPU.Build.0 = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x86.ActiveCfg = Release|x86 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|Any CPU.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM64.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.Build.0 = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.Build.0 = Release|x86 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.ActiveCfg = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Build.0 = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Deploy.0 = Debug|ARM @@ -373,10 +426,16 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.ActiveCfg = Debug|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Build.0 = Debug|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Deploy.0 = Debug|x86 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.Build.0 = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x64.ActiveCfg = Release|x64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x86.ActiveCfg = Release|x86 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.Build.0 = Release|Any CPU + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.Deploy.0 = Release|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.Build.0 = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.Deploy.0 = Release|ARM @@ -389,34 +448,42 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.ActiveCfg = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Build.0 = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Deploy.0 = Release|x86 + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|Any CPU.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x86.ActiveCfg = Debug + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|Any CPU.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x86.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|Any CPU.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x86.ActiveCfg = Release + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|Any CPU.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM64.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.ActiveCfg = Debug|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.Build.0 = Debug|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.Build.0 = Debug|x86 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|Any CPU.ActiveCfg = Release|x64 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|Any CPU.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x86.ActiveCfg = Release|x86 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|Any CPU.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM64.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.Build.0 = Release|x86 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|Any CPU.ActiveCfg = Debug|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.ActiveCfg = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.Build.0 = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -425,11 +492,13 @@ Global {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x64.Build.0 = Debug|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x86.ActiveCfg = Debug|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x86.Build.0 = Debug|Win32 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|ARM.ActiveCfg = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x64.Build.0 = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x86.ActiveCfg = Release|Win32 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|Any CPU.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM.ActiveCfg = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM.Build.0 = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -438,36 +507,45 @@ Global {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x64.Build.0 = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.Build.0 = Release|Win32 + {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|Any CPU.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.Build.0 = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x86.ActiveCfg = Fuzzing|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.Build.0 = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x86.ActiveCfg = Fuzzing|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|Any CPU.ActiveCfg = Debug|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|Any CPU.Build.0 = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x86.ActiveCfg = Fuzzing|x64 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|Any CPU.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM64.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.ActiveCfg = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.Build.0 = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.Build.0 = Debug|x86 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|Any CPU.ActiveCfg = Release|x64 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|Any CPU.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x86.ActiveCfg = Release|x86 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|Any CPU.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM64.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.Build.0 = Release|x86 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|Any CPU.ActiveCfg = Debug|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.ActiveCfg = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.Build.0 = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -476,10 +554,13 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x64.Build.0 = Debug|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x86.ActiveCfg = Debug|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x86.Build.0 = Debug|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|Any CPU.Build.0 = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|ARM.ActiveCfg = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|x64.ActiveCfg = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|x86.ActiveCfg = Release|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|Any CPU.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM.ActiveCfg = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM.Build.0 = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -488,6 +569,7 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x64.Build.0 = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.Build.0 = Release|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|Any CPU.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.ActiveCfg = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.Build.0 = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -496,6 +578,8 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x64.Build.0 = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.Build.0 = Debug|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|Any CPU.Build.0 = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM.ActiveCfg = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM.Build.0 = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 @@ -504,6 +588,7 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x64.Build.0 = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.Build.0 = Debug|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|Any CPU.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.ActiveCfg = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.Build.0 = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -512,6 +597,7 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.Build.0 = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.Build.0 = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|Any CPU.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.ActiveCfg = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.Build.0 = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -520,6 +606,8 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.Build.0 = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.Build.0 = Debug|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|Any CPU.Build.0 = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM.ActiveCfg = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM.Build.0 = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 @@ -528,6 +616,7 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x64.Build.0 = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.Build.0 = Debug|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|Any CPU.ActiveCfg = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.ActiveCfg = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.Build.0 = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -536,6 +625,64 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.Build.0 = Release|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.ActiveCfg = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.Build.0 = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.ActiveCfg = Debug|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.Build.0 = Debug|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.Build.0 = Debug|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x64.ActiveCfg = Debug|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x64.Build.0 = Debug|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.ActiveCfg = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.Build.0 = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|Any CPU.ActiveCfg = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|Any CPU.Build.0 = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM.ActiveCfg = Debug|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM.Build.0 = Debug|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM64.Build.0 = Debug|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x64.ActiveCfg = Debug|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x64.Build.0 = Debug|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x86.Build.0 = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|Any CPU.ActiveCfg = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.ActiveCfg = Release|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.Build.0 = Release|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.ActiveCfg = Release|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.Build.0 = Release|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.ActiveCfg = Release|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|Any CPU.ActiveCfg = Debug|x86 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|Any CPU.Build.0 = Debug|x86 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|ARM.ActiveCfg = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|ARM.Build.0 = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|ARM64.Build.0 = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|x64.ActiveCfg = Debug|x64 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|x64.Build.0 = Debug|x64 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|x86.ActiveCfg = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|x86.Build.0 = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|ARM.Build.0 = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|ARM64.Build.0 = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|x64.ActiveCfg = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|x64.Build.0 = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|x86.ActiveCfg = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|x86.Build.0 = Debug|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|Any CPU.ActiveCfg = Release|x64 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|Any CPU.Build.0 = Release|x64 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|ARM.ActiveCfg = Release|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|ARM.Build.0 = Release|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|ARM64.ActiveCfg = Release|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|ARM64.Build.0 = Release|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x64.ActiveCfg = Release|x64 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x64.Build.0 = Release|x64 + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x86.ActiveCfg = Release|Any CPU + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj b/src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj index 328c16546a..20d75ab75b 100644 --- a/src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj +++ b/src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj @@ -1,7 +1,7 @@  - net5.0 + net5.0-windows10.0.19041.0 $(SolutionDir)$(Platform)\$(Configuration)\AppInstallerCLIE2ETests\ false x64;x86 @@ -10,7 +10,10 @@ + + + @@ -37,8 +40,16 @@ + + + PreserveNewest + + + + + diff --git a/src/AppInstallerCLIE2ETests/ComInterfaceTests.cs b/src/AppInstallerCLIE2ETests/ComInterfaceTests.cs new file mode 100644 index 0000000000..0132961436 --- /dev/null +++ b/src/AppInstallerCLIE2ETests/ComInterfaceTests.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; + using System.IO; + using Microsoft.Management.Deployment; + + public class ComInterfaceTests : BaseCommand + { + [Test] + public void FindDefaultCatalog() + { + //int i = 0; + //while (i < 1000) + //{ + //try + //{ + PackageManager packageManager = new PackageManager(); + var catalogs = packageManager.GetPackageCatalogs(); + Assert.True(catalogs.Count > 0); + bool foundDefaultCatalog = false; + foreach (var catalog in catalogs) + { + if (catalog.Info.Name.Equals("winget")) + { + foundDefaultCatalog = true; + break; + } + } + Assert.True(foundDefaultCatalog); + //} + //catch (System.Exception) + //{ + + //} + // i++; + //} + } + } +} diff --git a/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp b/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp new file mode 100644 index 0000000000..df0caa2d02 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "CatalogPackage.h" +#include "CatalogPackage.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring CatalogPackage::Id() + { + throw hresult_not_implemented(); + } + hstring CatalogPackage::Name() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::InstalledVersion() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::Collections::IVectorView CatalogPackage::AvailableVersions() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::DefaultInstallVersion() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey) + { + UNREFERENCED_PARAMETER(versionKey); + throw hresult_not_implemented(); + } + bool CatalogPackage::IsUpdateAvailable() + { + throw hresult_not_implemented(); + } + + winrt::Microsoft::Management::Deployment::CatalogPackage CatalogPackage::GetServerPackage() + { + return m_catalogPackage; + } +} diff --git a/src/Microsoft.Management.Deployment.Client/CatalogPackage.h b/src/Microsoft.Management.Deployment.Client/CatalogPackage.h new file mode 100644 index 0000000000..bb463e9752 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/CatalogPackage.h @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "CatalogPackage.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct CatalogPackage : CatalogPackageT + { + CatalogPackage() = default; + + hstring Id(); + hstring Name(); + winrt::Microsoft::Management::Deployment::PackageVersionInfo InstalledVersion(); + winrt::Windows::Foundation::Collections::IVectorView AvailableVersions(); + winrt::Microsoft::Management::Deployment::PackageVersionInfo DefaultInstallVersion(); + winrt::Microsoft::Management::Deployment::PackageVersionInfo GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey); + bool IsUpdateAvailable(); + + winrt::Microsoft::Management::Deployment::CatalogPackage GetServerPackage(); + private: + winrt::Microsoft::Management::Deployment::CatalogPackage m_catalogPackage{ nullptr }; + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp b/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp new file mode 100644 index 0000000000..9c957d489c --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConnectResult.h" +#include "ConnectResult.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::ConnectResultStatus ConnectResult::Status() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalog ConnectResult::PackageCatalog() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/ConnectResult.h b/src/Microsoft.Management.Deployment.Client/ConnectResult.h new file mode 100644 index 0000000000..bec80cc105 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/ConnectResult.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConnectResult.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct ConnectResult : ConnectResultT + { + ConnectResult() = default; + + winrt::Microsoft::Management::Deployment::ConnectResultStatus Status(); + winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp new file mode 100644 index 0000000000..5f5855557f --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "CreateCompositePackageCatalogOptions.h" +#include "CreateCompositePackageCatalogOptions.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Windows::Foundation::Collections::IVector CreateCompositePackageCatalogOptions::Catalogs() + { + return m_createCompositePackageCatalogOptions.Catalogs(); + } + winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CreateCompositePackageCatalogOptions::CompositeSearchBehavior() + { + return m_createCompositePackageCatalogOptions.CompositeSearchBehavior(); + } + void CreateCompositePackageCatalogOptions::CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value) + { + m_createCompositePackageCatalogOptions.CompositeSearchBehavior(value); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h new file mode 100644 index 0000000000..6e1757a16e --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "CreateCompositePackageCatalogOptions.g.h" + +const CLSID CLSID_CreateCompositePackageCatalogOptions2 = { 0x6444B10D, 0xFE84, 0x430F, { 0x93, 0x2B, 0x3D, 0x4F, 0xE5, 0x19, 0x5B, 0xDF } }; //6444B10D-FE84-430F-932B-3D4FE5195BDF + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT + { + CreateCompositePackageCatalogOptions() + { + m_createCompositePackageCatalogOptions = winrt::create_instance(CLSID_CreateCompositePackageCatalogOptions2, CLSCTX_ALL); + } + + winrt::Windows::Foundation::Collections::IVector Catalogs(); + winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CompositeSearchBehavior(); + void CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value); + private: + winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions m_createCompositePackageCatalogOptions{ nullptr }; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT + { + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp new file mode 100644 index 0000000000..e814328b34 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "FindPackagesOptions.h" +#include "FindPackagesOptions.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Windows::Foundation::Collections::IVector FindPackagesOptions::Selectors() + { + return m_findPackagesOptions.Selectors(); + } + winrt::Windows::Foundation::Collections::IVector FindPackagesOptions::Filters() + { + return m_findPackagesOptions.Filters(); + } + uint32_t FindPackagesOptions::ResultLimit() + { + return m_findPackagesOptions.ResultLimit(); + } + void FindPackagesOptions::ResultLimit(uint32_t value) + { + m_findPackagesOptions.ResultLimit(value); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h new file mode 100644 index 0000000000..a248081484 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "FindPackagesOptions.g.h" + +const CLSID CLSID_FindPackagesOptions2 = { 0x2CAD6C15, 0xDF8E, 0x49DD, { 0xA7, 0x48, 0x96, 0xAD, 0xE0, 0xFE, 0x31, 0xB7 } }; //2CAD6C15-DF8E-49DD-A748-96ADE0FE31B7 + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct FindPackagesOptions : FindPackagesOptionsT + { + FindPackagesOptions() + { + m_findPackagesOptions = winrt::create_instance(CLSID_FindPackagesOptions2, CLSCTX_ALL); + } + + winrt::Windows::Foundation::Collections::IVector Selectors(); + winrt::Windows::Foundation::Collections::IVector Filters(); + uint32_t ResultLimit(); + void ResultLimit(uint32_t value); + private: + winrt::Microsoft::Management::Deployment::FindPackagesOptions m_findPackagesOptions{ nullptr }; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct FindPackagesOptions : FindPackagesOptionsT + { + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp new file mode 100644 index 0000000000..3ae321d3a2 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "FindPackagesResult.h" +#include "FindPackagesResult.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResult::Status() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::Collections::IVectorView FindPackagesResult::Matches() + { + throw hresult_not_implemented(); + } + bool FindPackagesResult::WasLimitExceeded() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h new file mode 100644 index 0000000000..28add522d0 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "FindPackagesResult.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct FindPackagesResult : FindPackagesResultT + { + FindPackagesResult() = default; + + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus Status(); + winrt::Windows::Foundation::Collections::IVectorView Matches(); + bool WasLimitExceeded(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp new file mode 100644 index 0000000000..b56413c701 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp @@ -0,0 +1,90 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "InstallOptions.h" +#include "InstallOptions.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::PackageVersionId InstallOptions::PackageVersionId() + { + throw hresult_not_implemented(); + } + void InstallOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } + hstring InstallOptions::PreferredInstallLocation() + { + throw hresult_not_implemented(); + } + void InstallOptions::PreferredInstallLocation(hstring const& value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageInstallScope InstallOptions::PackageInstallScope() + { + throw hresult_not_implemented(); + } + void InstallOptions::PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageInstallMode InstallOptions::PackageInstallMode() + { + throw hresult_not_implemented(); + } + void InstallOptions::PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const& value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } + hstring InstallOptions::LogOutputPath() + { + throw hresult_not_implemented(); + } + void InstallOptions::LogOutputPath(hstring const& value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } + bool InstallOptions::AllowHashMismatch() + { + throw hresult_not_implemented(); + } + void InstallOptions::AllowHashMismatch(bool value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } + hstring InstallOptions::ReplacementInstallerArguments() + { + throw hresult_not_implemented(); + } + void InstallOptions::ReplacementInstallerArguments(hstring const& value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } + hstring InstallOptions::CorrelationData() + { + throw hresult_not_implemented(); + } + void InstallOptions::CorrelationData(hstring const& value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } + hstring InstallOptions::AdditionalPackageCatalogArguments() + { + throw hresult_not_implemented(); + } + void InstallOptions::AdditionalPackageCatalogArguments(hstring const& value) + { + UNREFERENCED_PARAMETER(value); + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.h b/src/Microsoft.Management.Deployment.Client/InstallOptions.h new file mode 100644 index 0000000000..fb39f7d7f4 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.h @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "InstallOptions.g.h" + +const CLSID CLSID_InstallOptions2 = { 0x05F7019A, 0x8FAC, 0x4422, 0xBC, 0xD5, 0x4C, 0xB3, 0x4F, 0xFB, 0x44, 0xA8 }; //05F7019A-8FAC-4422-BCD5-4CB34FFB44A8 + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct InstallOptions : InstallOptionsT + { + InstallOptions() + { + m_installOptions = winrt::create_instance(CLSID_InstallOptions2, CLSCTX_ALL); + } + + winrt::Microsoft::Management::Deployment::PackageVersionId PackageVersionId(); + void PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value); + hstring PreferredInstallLocation(); + void PreferredInstallLocation(hstring const& value); + winrt::Microsoft::Management::Deployment::PackageInstallScope PackageInstallScope(); + void PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value); + winrt::Microsoft::Management::Deployment::PackageInstallMode PackageInstallMode(); + void PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const& value); + hstring LogOutputPath(); + void LogOutputPath(hstring const& value); + bool AllowHashMismatch(); + void AllowHashMismatch(bool value); + hstring ReplacementInstallerArguments(); + void ReplacementInstallerArguments(hstring const& value); + hstring CorrelationData(); + void CorrelationData(hstring const& value); + hstring AdditionalPackageCatalogArguments(); + void AdditionalPackageCatalogArguments(hstring const& value); + private: + winrt::Microsoft::Management::Deployment::InstallOptions m_installOptions{ nullptr }; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct InstallOptions : InstallOptionsT + { + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/InstallResult.cpp b/src/Microsoft.Management.Deployment.Client/InstallResult.cpp new file mode 100644 index 0000000000..162a0d63ba --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/InstallResult.cpp @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "InstallResult.h" +#include "InstallResult.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring InstallResult::CorrelationData() + { + throw hresult_not_implemented(); + } + bool InstallResult::RebootRequired() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::InstallResultStatus InstallResult::Status() + { + throw hresult_not_implemented(); + } + winrt::hresult InstallResult::ExtendedErrorCode() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/InstallResult.h b/src/Microsoft.Management.Deployment.Client/InstallResult.h new file mode 100644 index 0000000000..4086db3e7e --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/InstallResult.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "InstallResult.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct InstallResult : InstallResultT + { + InstallResult() = default; + + hstring CorrelationData(); + bool RebootRequired(); + winrt::Microsoft::Management::Deployment::InstallResultStatus Status(); + winrt::hresult ExtendedErrorCode(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/MatchResult.cpp b/src/Microsoft.Management.Deployment.Client/MatchResult.cpp new file mode 100644 index 0000000000..2487823282 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/MatchResult.cpp @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "MatchResult.h" +#include "MatchResult.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::CatalogPackage MatchResult::CatalogPackage() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchResult::MatchCriteria() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/MatchResult.h b/src/Microsoft.Management.Deployment.Client/MatchResult.h new file mode 100644 index 0000000000..a7fd68f9b3 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/MatchResult.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "MatchResult.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct MatchResult : MatchResultT + { + MatchResult() = default; + + winrt::Microsoft::Management::Deployment::CatalogPackage CatalogPackage(); + winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchCriteria(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj new file mode 100644 index 0000000000..d7495334d6 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj @@ -0,0 +1,195 @@ + + + + + true + true + true + true + {4bc1f40b-36c2-4bbb-8306-76e490b13bbd} + Microsoft.Management.Deployment.Client + Microsoft.Management.Deployment + en-US + 14.0 + true + Windows Store + 10.0 + 10.0.19041.0 + 10.0.17134.0 + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + DynamicLibrary + v140 + v141 + v142 + Unicode + false + + + true + true + + + false + true + false + + + + + + + + + + + + + + + + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + $(PlatformTarget)\$(Configuration)\ + $(RootNamespace) + true + false + ..\CodeAnalysis.ruleset + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + + /DWINRT_NO_MAKE_DETECTION %(AdditionalOptions) + + + _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + false + Microsoft_Management_Deployment_Client.def + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + + + + + + + + + + + + + + + PackageManager.idl + + + + + + + + + + + + + + + + + + + Create + + + PackageManager.idl + + + + + + + + + + + + + + false + + + + + + + + + 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}. + + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment.Client/Microsoft_Management_Deployment_Client.def b/src/Microsoft.Management.Deployment.Client/Microsoft_Management_Deployment_Client.def new file mode 100644 index 0000000000..24e7c1235c --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/Microsoft_Management_Deployment_Client.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp new file mode 100644 index 0000000000..0f65ae4648 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageCatalog.h" +#include "PackageCatalog.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + bool PackageCatalog::IsComposite() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalog::Info() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::IAsyncOperation PackageCatalog::FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options) + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::FindPackagesResult PackageCatalog::FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options) + { + UNREFERENCED_PARAMETER(options); + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalog.h b/src/Microsoft.Management.Deployment.Client/PackageCatalog.h new file mode 100644 index 0000000000..0299a0b45f --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalog.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageCatalog.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageCatalog : PackageCatalogT + { + PackageCatalog() = default; + + bool IsComposite(); + winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); + winrt::Windows::Foundation::IAsyncOperation FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options); + winrt::Microsoft::Management::Deployment::FindPackagesResult FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp new file mode 100644 index 0000000000..98a723b34d --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageCatalogInfo.h" +#include "PackageCatalogInfo.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring PackageCatalogInfo::Id() + { + throw hresult_not_implemented(); + } + hstring PackageCatalogInfo::Name() + { + throw hresult_not_implemented(); + } + hstring PackageCatalogInfo::Type() + { + throw hresult_not_implemented(); + } + hstring PackageCatalogInfo::Argument() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::DateTime PackageCatalogInfo::LastUpdateTime() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogOrigin PackageCatalogInfo::Origin() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel PackageCatalogInfo::TrustLevel() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.h b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.h new file mode 100644 index 0000000000..b400143ae6 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.h @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageCatalogInfo.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageCatalogInfo : PackageCatalogInfoT + { + PackageCatalogInfo() = default; + + hstring Id(); + hstring Name(); + hstring Type(); + hstring Argument(); + winrt::Windows::Foundation::DateTime LastUpdateTime(); + winrt::Microsoft::Management::Deployment::PackageCatalogOrigin Origin(); + winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel TrustLevel(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp new file mode 100644 index 0000000000..6c41a5dd91 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageCatalogReference.h" +#include "PackageCatalogReference.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + bool PackageCatalogReference::IsComposite() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalogReference::Info() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::IAsyncOperation PackageCatalogReference::ConnectAsync() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::ConnectResult PackageCatalogReference::Connect() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h new file mode 100644 index 0000000000..5d02f35e2b --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageCatalogReference.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageCatalogReference : PackageCatalogReferenceT + { + PackageCatalogReference() = default; + + bool IsComposite(); + winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); + winrt::Windows::Foundation::IAsyncOperation ConnectAsync(); + winrt::Microsoft::Management::Deployment::ConnectResult Connect(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp new file mode 100644 index 0000000000..d8b2ee5bec --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp @@ -0,0 +1,36 @@ +#include "pch.h" +#include "PackageManager.h" +#include "PackageManager.g.cpp" + + + + + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Windows::Foundation::Collections::IVectorView PackageManager::GetPackageCatalogs() + { + m_packageManager = winrt::create_instance(CLSID_PackageManager2, CLSCTX_ALL); + return m_packageManager.GetPackageCatalogs(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog) + { + return m_packageManager.GetPredefinedPackageCatalog(predefinedPackageCatalog); + } + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetLocalPackageCatalog(winrt::Microsoft::Management::Deployment::LocalPackageCatalog const& localPackageCatalog) + { + return m_packageManager.GetLocalPackageCatalog(localPackageCatalog); + } + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPackageCatalogByName(hstring const& catalogName) + { + return m_packageManager.GetPackageCatalogByName(catalogName); + } + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options) + { + return m_packageManager.CreateCompositePackageCatalog(options); + } + winrt::Windows::Foundation::IAsyncOperationWithProgress PackageManager::InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options) + { + return m_packageManager.InstallPackageAsync(package, options); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.h b/src/Microsoft.Management.Deployment.Client/PackageManager.h new file mode 100644 index 0000000000..371fd29240 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.h @@ -0,0 +1,27 @@ +#pragma once +#include "PackageManager.g.h" + +const CLSID CLSID_PackageManager2 = { 0xE65C7D5A, 0x95AF, 0x4A98, { 0xBE, 0x5F, 0xA7, 0x93, 0x02, 0x9C, 0xEB, 0x56 } }; //E65C7D5A-95AF-4A98-BE5F-A793029CEB56 + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageManager : PackageManagerT + { + PackageManager() = default; + + winrt::Windows::Foundation::Collections::IVectorView GetPackageCatalogs(); + winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog); + winrt::Microsoft::Management::Deployment::PackageCatalogReference GetLocalPackageCatalog(winrt::Microsoft::Management::Deployment::LocalPackageCatalog const& localPackageCatalog); + winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPackageCatalogByName(hstring const& catalogName); + winrt::Microsoft::Management::Deployment::PackageCatalogReference CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options); + winrt::Windows::Foundation::IAsyncOperationWithProgress InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options); + private: + winrt::Microsoft::Management::Deployment::PackageManager m_packageManager{ nullptr }; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct PackageManager : PackageManagerT + { + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.idl b/src/Microsoft.Management.Deployment.Client/PackageManager.idl new file mode 100644 index 0000000000..d81eb01279 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.idl @@ -0,0 +1,540 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +namespace Microsoft.Management.Deployment +{ + [contractversion(1)] + apicontract WindowsPackageManagerContract{}; + + /// State of the install. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PackageInstallProgressState + { + /// The install is queued but not yet active. Cancellation of the IAsyncOperationWithProgress in this + /// state will prevent the package from downloading or installing. + Queued, + /// The installer is downloading. Cancellation of the IAsyncOperationWithProgress in this state will + /// end the download and prevent the package from installing. + Downloading, + /// The install is in progress. Cancellation of the IAsyncOperationWithProgress in this state will not + /// stop the installation or the post install cleanup. + Installing, + /// The installer has completed and cleanup actions are in progress. Cancellation of the + /// IAsyncOperationWithProgress in this state will not stop cleanup or roll back the install. + PostInstall, + /// The operation has completed. + Finished, + }; + + /// Progress object for the install + /// DESIGN NOTE: percentage for the install as a whole is purposefully not included as there is no way to + /// estimate progress when the installer is running. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + struct InstallProgress + { + /// State of the install + PackageInstallProgressState State; + /// DESIGN NOTE: BytesDownloaded may only be available for downloads done by Windows Package Manager itself. + /// Number of bytes downloaded if known + UInt64 BytesDownloaded; + /// DESIGN NOTE: BytesRequired may only be available for downloads done by Windows Package Manager itself. + /// Number of bytes required if known + UInt64 BytesRequired; + /// Download percentage completed + Double DownloadProgress; + /// Install percentage if known. + Double InstallationProgress; + }; + + /// Status of the Install call + /// Implementation Note: Errors mapped from AppInstallerErrors.h + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum InstallResultStatus + { + Ok, + BlockedByPolicy, + CatalogError, + InternalError, + InvalidOptions, + DownloadError, + InstallError, + ManifestError, + NoApplicableInstallers, + }; + + /// Result of the install + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass InstallResult + { + /// Used by a caller to correlate the install with a caller's data. + String CorrelationData{ get; }; + /// Whether a restart is required to complete the install. + Boolean RebootRequired{ get; }; + + /// Batched error code, example APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED + InstallResultStatus Status{ get; }; + /// Specific error if known, from downloader or installer itself, example ERROR_INSTALL_PACKAGE_REJECTED + HRESULT ExtendedErrorCode{ get; }; + } + + /// IMPLEMENTATION NOTE: SourceOrigin from AppInstallerRepositorySource.h + /// Defines the origin of the package catalog details. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PackageCatalogOrigin + { + /// Predefined means it came as part of the Windows Package Manager package and cannot be removed. + Predefined, + /// User means it was added by the user and could be removed. + User, + }; + + /// IMPLEMENTATION NOTE: SourceTrustLevel from AppInstallerRepositorySource.h + /// Defines the trust level of the package catalog. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PackageCatalogTrustLevel + { + None, + Trusted, + }; + + /// IMPLEMENTATION NOTE: SourceDetails from AppInstallerRepositorySource.h + /// Interface for retrieving information about an package catalog without acting on it. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass PackageCatalogInfo + { + /// The package catalog's unique identifier. + /// SAMPLE VALUES: For OpenWindowsCatalog "Microsoft.Winget.Source_8wekyb3d8bbwe" + /// For contoso sample on msdn "contoso" + String Id { get; }; + /// The name of the package catalog. + /// SAMPLE VALUES: For OpenWindowsCatalog "winget". + /// For contoso sample on msdn "contoso" + String Name { get; }; + /// The type of the package catalog. + /// ALLOWED VALUES: "Microsoft.Rest", "Microsoft.PreIndexed.Package" + /// SAMPLE VALUES: For OpenWindowsCatalog "Microsoft.PreIndexed.Package". + /// For contoso sample on msdn "Microsoft.PreIndexed.Package" + String Type { get; }; + /// The argument used when adding the package catalog. + /// SAMPLE VALUES: For OpenWindowsCatalog "https://winget.azureedge.net/cache" + /// For contoso sample on msdn "https://pkgmgr-int.azureedge.net/cache" + String Argument { get; }; + /// The last time that this package catalog was updated. + Windows.Foundation.DateTime LastUpdateTime { get; }; + /// The origin of the package catalog. + PackageCatalogOrigin Origin { get; }; + /// The trust level of the package catalog + PackageCatalogTrustLevel TrustLevel { get; }; + } + + /// A metadata item of a package version. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PackageVersionMetadataField + { + /// The InstallerType of an installed package + InstallerType, + /// The Scope of an installed package + InstalledScope, + /// The system path where the package is installed + InstalledLocation, + /// The standard uninstall command; which may be interactive + StandardUninstallCommand, + /// An uninstall command that should be non-interactive + SilentUninstallCommand, + /// The publisher of the package + PublisherDisplayName, + }; + + /// IMPLEMENTATION NOTE: IPackageVersion from AppInstallerRepositorySearch.h + /// A single package version. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass PackageVersionInfo + { + /// IMPLEMENTATION NOTE: PackageVersionMetadata fields from AppInstallerRepositorySearch.h + /// Gets any metadata associated with this package version. + /// Primarily stores data on installed packages. + /// Metadata fields may have no value (e.g. packages that aren't installed will not have an InstalledLocation). + String GetMetadata(PackageVersionMetadataField metadataField); + /// IMPLEMENTATION NOTE: PackageVersionProperty fields from AppInstallerRepositorySearch.h + String Id { get; }; + String DisplayName { get; }; + String Version { get; }; + String Channel { get; }; + /// DESIGN NOTE: RelativePath from AppInstallerRepositorySearch.h is excluded as not needed. + /// String RelativePath; + + /// IMPLEMENTATION NOTE: PackageVersionMultiProperty fields from AppInstallerRepositorySearch.h + /// PackageFamilyName and ProductCode can have multiple values. + Windows.Foundation.Collections.IVectorView PackageFamilyNames { get; }; + Windows.Foundation.Collections.IVectorView ProductCodes { get; }; + + /// Gets the package catalog where this package version is from. + PackageCatalog PackageCatalog { get; }; + + /// DESIGN NOTE: + /// GetManifest from IPackageVersion in AppInstallerRepositorySearch is not implemented in V1. That class has + /// a lot of fields and no one requesting it. + /// Gets the manifest of this package version. + /// virtual Manifest::Manifest GetManifest() = 0; + } + + /// IMPLEMENTATION NOTE: PackageVersionKey from AppInstallerRepositorySearch.h + /// A key to identify a package version within a package. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass PackageVersionId + { + /// The package catalog id that this version came from. + String PackageCatalogId { get; }; + /// The version. + String Version { get; }; + /// The channel. + String Channel { get; }; + }; + + /// IMPLEMENTATION NOTE: IPackage from AppInstallerRepositorySearch.h + /// A package, potentially containing information about it's local state and the available versions. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass CatalogPackage + { + /// IMPLEMENTATION NOTE: PackageProperty fields from AppInstallerRepositorySearch.h + /// Gets a property of this package. + String Id { get; }; + String Name { get; }; + + /// Gets the installed package information if the package is installed. + PackageVersionInfo InstalledVersion{ get; }; + + /// Gets all available versions of this package. Ordering is not guaranteed. + Windows.Foundation.Collections.IVectorView AvailableVersions { get; }; + + /// Gets the version of this package that will be installed if version is not set in InstallOptions. + PackageVersionInfo DefaultInstallVersion { get; }; + + /// Gets a specific version of this package. + PackageVersionInfo GetPackageVersionInfo(PackageVersionId versionKey); + + /// Gets a value indicating whether an available version is newer than the installed version. + Boolean IsUpdateAvailable { get; }; + + /// DESIGN NOTE: + /// IsSame from IPackage in AppInstallerRepositorySearch is not implemented in V1. + /// Determines if the given IPackage refers to the same package as this one. + /// virtual bool IsSame(const IPackage*) const = 0; + } + + /// IMPLEMENTATION NOTE: CompositeSearchBehavior from AppInstallerRepositorySource.h + /// Search behavior for composite catalogs. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum CompositeSearchBehavior + { + /// Search local catalogs only + LocalCatalogs, + /// Search remote catalogs only, don't check local catalogs for InstalledVersion + RemotePackagesFromRemoteCatalogs, + /// Search remote catalogs, and check local catalogs for InstalledVersion + RemotePackagesFromAllCatalogs, + /// Search both local and remote catalogs. + AllCatalogs, + }; + + /// IMPLEMENTATION NOTE: PackageFieldMatchOption from AppInstallerRepositorySearch.h + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PackageFieldMatchOption + { + Equals, + EqualsCaseInsensitive, + StartsWithCaseInsensitive, + ContainsCaseInsensitive, + }; + + /// IMPLEMENTATION NOTE: PackageFieldMatchOption from AppInstallerRepositorySearch.h + /// The field to match on. + /// The values must be declared in order of preference in search results. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PackageMatchField + { + CatalogDefault, + Id, + Name, + Moniker, + Command, + Tag, + /// DESIGN NOTE: The following PackageFieldMatchOption from AppInstallerRepositorySearch.h are not implemented in V1. + /// PackageFamilyName, + /// ProductCode, + /// NormalizedNameAndPublisher, + }; + + /// IMPLEMENTATION NOTE: PackageMatchFilter from AppInstallerRepositorySearch.h + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass PackageMatchFilter + { + PackageMatchFilter(); + /// The type of string comparison for matching + PackageFieldMatchOption Option; + /// The field to search + PackageMatchField Field; + /// The value to match + String Value; + /// DESIGN NOTE: "Additional" from RequestMatch AppInstallerRepositorySearch.h is not implemented here. + } + + /// IMPLEMENTATION NOTE: MatchResult from AppInstallerRepositorySearch.h + /// A single result from the search. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass MatchResult + { + /// The package found by the search request. + CatalogPackage CatalogPackage { get; }; + + /// The highest order field on which the package matched the search. + PackageMatchFilter MatchCriteria { get; }; + } + + /// Status of the FindPackages call + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum FindPackagesResultStatus + { + Ok, + BlockedByPolicy, + CatalogError, + InternalError, + InvalidOptions + }; + + /// IMPLEMENTATION NOTE: SearchResult from AppInstallerRepositorySearch.h + /// Search result data returned from FindPackages + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass FindPackagesResult + { + /// Error codes + FindPackagesResultStatus Status{ get; }; + + /// The full set of results from the search. + Windows.Foundation.Collections.IVectorView Matches { get; }; + + /// If true, the results were truncated by the given ResultLimit + /// USAGE NOTE: Windows Package Manager does not support result pagination, there is no way to continue + /// getting more results. + Boolean WasLimitExceeded{ get; }; + } + + /// Options for FindPackages + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass FindPackagesOptions + { + FindPackagesOptions(); + + /// DESIGN NOTE: + /// This class maps to SearchRequest from AppInstallerRepositorySearch.h + /// That class is a container for data used to filter the available manifests in an package catalog. + /// Its properties can be thought of as: + /// (Query || Inclusions...) && Filters... + /// If Query and Inclusions are both empty, the starting data set will be the entire database. + /// Everything && Filters... + /// That has been translated in this api so that + /// Inclusions are Selectors below + /// Filters are Filters below + /// Query is PackageFieldMatchOption::PackageCatalogDefined and in the Selector list. + /// USAGE NOTE: Only one selector with PackageFieldMatchOption::PackageCatalogDefined is allowed. + + /// Selectors = you have to match at least one selector (if there are no selectors, then nothing is selected) + Windows.Foundation.Collections.IVector Selectors { get; }; + /// Filters = you have to match all filters(if there are no filters, then there is no filtering of selected items) + Windows.Foundation.Collections.IVector Filters{ get; }; + + /// Restricts the length of the returned results to the specified count. + UInt32 ResultLimit; + } + + /// IMPLEMENTATION NOTE: ISource from AppInstallerRepositorySource.h + /// A catalog for searching for packages + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass PackageCatalog + { + /// Gets a value indicating whether this package catalog is a composite of other package catalogs, + /// and thus the packages may come from disparate package catalogs as well. + Boolean IsComposite { get; }; + /// The details of the package catalog if it is not a composite. + PackageCatalogInfo Info { get; }; + + /// Searches for Packages in the catalog. + Windows.Foundation.IAsyncOperation FindPackagesAsync(FindPackagesOptions options); + FindPackagesResult FindPackages(FindPackagesOptions options); + } + + /// Status of the Connect call + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum ConnectResultStatus + { + Ok, + CatalogError, + }; + + /// Result of the Connect call + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass ConnectResult + { + /// Error codes + ConnectResultStatus Status{ get; }; + + PackageCatalog PackageCatalog { get; }; + } + + /// A reference to a catalog that callers can try to Connect. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass PackageCatalogReference + { + /// Gets a value indicating whether this package catalog is a composite of other package catalogs, + /// and thus the packages may come from disparate package catalogs as well. + Boolean IsComposite { get; }; + /// The details of the package catalog if it is not a composite. + PackageCatalogInfo Info { get; }; + + /// Opens a catalog. Required before searching. For remote catalogs (i.e. not Installed and Installing) this + /// may require downloading information from a server. + Windows.Foundation.IAsyncOperation ConnectAsync(); + ConnectResult Connect(); + } + + /// Catalogs with PackageCatalogOrigin Predefined + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PredefinedPackageCatalog + { + OpenWindowsCatalog, + }; + + /// Local Catalogs with PackageCatalogOrigin Predefined + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum LocalPackageCatalog + { + InstalledPackages, + }; + + /// Options for creating a composite catalog. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass CreateCompositePackageCatalogOptions + { + CreateCompositePackageCatalogOptions(); + + /// Create a composite catalog to allow searching a user defined or pre defined source + /// and a local source (Installed packages) together + IVector Catalogs { get; }; + /// Sets the default search behavior if the catalog is a composite catalog. + CompositeSearchBehavior CompositeSearchBehavior; + } + + /// Required install scope for the package. If the package does not have an installer that + /// supports the specified scope the Install call will fail with InstallResultStatus.NoApplicableInstallers + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PackageInstallScope + { + /// An installer with any install scope is valid. + Any, + /// Only User install scope installers are valid + User, + /// Only System installers will be valid + System, + }; + + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + enum PackageInstallMode + { + /// The default experience for the installer. Installer may show some UI. + Default, + /// Runs the installer in silent mode. This suppresses the installer's UI to the extent + /// possible (installer may still show some required UI). + Silent, + /// Runs the installer in interactive mode. + Interactive, + }; + + /// Options when installing a package. + /// Intended to allow full compatibility with the "winget install" command line interface. + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass InstallOptions + { + InstallOptions(); + + /// Optionally specifies the version from the package to install. If unspecified the version matching + /// CatalogPackage.GetLatestVersion() is used. + PackageVersionId PackageVersionId; + + /// Specifies alternate location to install package (if supported). + String PreferredInstallLocation; + /// User or Machine. + PackageInstallScope PackageInstallScope; + /// Silent, Interactive, or Default + PackageInstallMode PackageInstallMode; + /// Directs the logging to a log file. If provided, the installer must have have write access to the file + String LogOutputPath; + /// Continues the install even if the hash in the catalog does not match the linked installer. + Boolean AllowHashMismatch; + /// A string that will be passed to the installer. + /// IMPLEMENTATION NOTE: maps to "--override" in the winget cmd line + String ReplacementInstallerArguments; + + /// Used by a caller to correlate the install with a caller's data. + /// The string must be JSON encoded. + String CorrelationData; + /// A string that will be passed to the source server if using a REST source + String AdditionalPackageCatalogArguments; + } + + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] + runtimeclass PackageManager + { + PackageManager(); + + /// Get the available catalogs. Each source will have a separate catalog. + /// This does not open the catalog. These catalogs can be used individually or merged with CreateCompositePackageCatalogAsync. + /// IMPLEMENTATION NOTE: This is a list of sources returned by Windows Package Manager source list + Windows.Foundation.Collections.IVectorView GetPackageCatalogs(); + /// Get a built in catalog + PackageCatalogReference GetPredefinedPackageCatalog(PredefinedPackageCatalog predefinedPackageCatalog); + /// Get a built in catalog + PackageCatalogReference GetLocalPackageCatalog(LocalPackageCatalog localPackageCatalog); + /// Get a catalog by a known name + PackageCatalogReference GetPackageCatalogByName(String catalogName); + /// Get a composite catalog to allow searching a user defined or pre defined source and a local source + /// (Installing, Installed) together at the same time. + PackageCatalogReference CreateCompositePackageCatalog(CreateCompositePackageCatalogOptions options); + + /// Install the specified package + Windows.Foundation.IAsyncOperationWithProgress InstallPackageAsync(CatalogPackage package, InstallOptions options); + } + + /// Force midl3 to generate vector marshalling info. + declare + { + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp new file mode 100644 index 0000000000..3af5223199 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageMatchFilter.h" +#include "PackageMatchFilter.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::PackageFieldMatchOption PackageMatchFilter::Option() + { + return m_packageMatchFilter.Option(); + } + void PackageMatchFilter::Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value) + { + m_packageMatchFilter.Option(value); + } + winrt::Microsoft::Management::Deployment::PackageMatchField PackageMatchFilter::Field() + { + return m_packageMatchFilter.Field(); + } + void PackageMatchFilter::Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value) + { + m_packageMatchFilter.Field(value); + } + hstring PackageMatchFilter::Value() + { + return m_packageMatchFilter.Value(); + } + void PackageMatchFilter::Value(hstring const& value) + { + m_packageMatchFilter.Option(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h new file mode 100644 index 0000000000..746d29b548 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageMatchFilter.g.h" + +const CLSID CLSID_PackageMatchFilter2 = { 0xADBF3B4A, 0xDB8A, 0x496C, { 0xA5, 0x79, 0x62, 0xB5, 0x8F, 0x5F, 0xB1, 0x3F } }; //ADBF3B4A-DB8A-496C-A579-62B58F5FB13F + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageMatchFilter : PackageMatchFilterT + { + PackageMatchFilter() + { + m_packageMatchFilter = winrt::create_instance(CLSID_PackageMatchFilter2, CLSCTX_ALL); + } + + winrt::Microsoft::Management::Deployment::PackageFieldMatchOption Option(); + void Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value); + winrt::Microsoft::Management::Deployment::PackageMatchField Field(); + void Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value); + hstring Value(); + void Value(hstring const& value); + private: + winrt::Microsoft::Management::Deployment::PackageMatchFilter m_packageMatchFilter{ nullptr }; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct PackageMatchFilter : PackageMatchFilterT + { + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp b/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp new file mode 100644 index 0000000000..d9bad834f9 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageVersionId.h" +#include "PackageVersionId.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring PackageVersionId::PackageCatalogId() + { + throw hresult_not_implemented(); + } + hstring PackageVersionId::Version() + { + throw hresult_not_implemented(); + } + hstring PackageVersionId::Channel() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionId.h b/src/Microsoft.Management.Deployment.Client/PackageVersionId.h new file mode 100644 index 0000000000..739f7da547 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionId.h @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageVersionId.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageVersionId : PackageVersionIdT + { + PackageVersionId() = default; + + hstring PackageCatalogId(); + hstring Version(); + hstring Channel(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp new file mode 100644 index 0000000000..f7cf643de5 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageVersionInfo.h" +#include "PackageVersionInfo.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring PackageVersionInfo::GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField) + { + UNREFERENCED_PARAMETER(metadataField); + throw hresult_not_implemented(); + } + hstring PackageVersionInfo::Id() + { + throw hresult_not_implemented(); + } + hstring PackageVersionInfo::DisplayName() + { + throw hresult_not_implemented(); + } + hstring PackageVersionInfo::Version() + { + throw hresult_not_implemented(); + } + hstring PackageVersionInfo::Channel() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::Collections::IVectorView PackageVersionInfo::PackageFamilyNames() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::Collections::IVectorView PackageVersionInfo::ProductCodes() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalog PackageVersionInfo::PackageCatalog() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h new file mode 100644 index 0000000000..7eef08e22e --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageVersionInfo.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageVersionInfo : PackageVersionInfoT + { + PackageVersionInfo() = default; + + hstring GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField); + hstring Id(); + hstring DisplayName(); + hstring Version(); + hstring Channel(); + winrt::Windows::Foundation::Collections::IVectorView PackageFamilyNames(); + winrt::Windows::Foundation::Collections::IVectorView ProductCodes(); + winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PropertySheet.props b/src/Microsoft.Management.Deployment.Client/PropertySheet.props new file mode 100644 index 0000000000..e34141b019 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/PropertySheet.props @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment.Client/packages.config b/src/Microsoft.Management.Deployment.Client/packages.config new file mode 100644 index 0000000000..1a341db8e9 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment.Client/pch.cpp b/src/Microsoft.Management.Deployment.Client/pch.cpp new file mode 100644 index 0000000000..e4b1bd6915 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/pch.cpp @@ -0,0 +1,3 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" diff --git a/src/Microsoft.Management.Deployment.Client/pch.h b/src/Microsoft.Management.Deployment.Client/pch.h new file mode 100644 index 0000000000..870f275fdd --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/pch.h @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include +#include +#include +#include diff --git a/src/Microsoft.Management.Deployment.Client/readme.txt b/src/Microsoft.Management.Deployment.Client/readme.txt new file mode 100644 index 0000000000..aa0dc2f192 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/readme.txt @@ -0,0 +1,23 @@ +======================================================================== + C++/WinRT Microsoft.Management.Deployment Project Overview +======================================================================== + +This project demonstrates how to get started authoring Windows Runtime +classes directly with standard C++, using the C++/WinRT SDK component +to generate implementation headers from interface (IDL) files. The +generated Windows Runtime component binary and WinMD files should then +be bundled with the Universal Windows Platform (UWP) app consuming them. + +Steps: +1. Create an interface (IDL) file to define your Windows Runtime class, + its default interface, and any other interfaces it implements. +2. Build the project once to generate module.g.cpp, module.h.cpp, and + implementation templates under the "Generated Files" folder, as + well as skeleton class definitions under "Generated Files\sources". +3. Use the skeleton class definitions for reference to implement your + Windows Runtime classes. + +======================================================================== +Learn more about C++/WinRT here: +http://aka.ms/cppwinrt/ +======================================================================== diff --git a/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj b/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj new file mode 100644 index 0000000000..dd3e41b718 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj @@ -0,0 +1,23 @@ + + + net5.0-windows10.0.19041.0 + 10.0.19041.0 + x64;x86 + + + + + + + + + + + + Microsoft.Management.Deployment + $(OutDir) + + + TRACE;/fl + + diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index 4e2d01b169..2478dd50c2 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -532,5 +532,9 @@ namespace Microsoft.Management.Deployment interface Windows.Foundation.Collections.IVectorView; interface Windows.Foundation.Collections.IVector; interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; } } From cd2629b3da025ed6e1cd4116be24b6c1320bec76 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Tue, 3 Aug 2021 20:32:07 -0700 Subject: [PATCH 02/53] Add wrapper implementation and project --- src/AppInstallerCLI.sln | 47 ++++- .../ComInterfaceTests.cs | 42 ---- .../InstallOptions.cpp | 45 ++--- .../PackageManager.cpp | 5 - .../PackageManager.h | 5 +- .../PackageMatchFilter.cpp | 2 +- .../PackageMatchFilter.h | 2 +- ...ft.Management.Deployment.Projection.csproj | 3 +- .../Assets/LockScreenLogo.scale-200.png | Bin 0 -> 1430 bytes .../Assets/SplashScreen.scale-200.png | Bin 0 -> 7700 bytes .../Assets/Square150x150Logo.scale-200.png | Bin 0 -> 2937 bytes .../Assets/Square44x44Logo.scale-200.png | Bin 0 -> 1647 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 0 -> 1255 bytes src/PackagedTests/Assets/StoreLogo.png | Bin 0 -> 1451 bytes .../Assets/Wide310x150Logo.scale-200.png | Bin 0 -> 3204 bytes src/PackagedTests/ComInterfaceUnitTest.cs | 76 ++++++++ src/PackagedTests/Package.appxmanifest | 58 ++++++ src/PackagedTests/PackagedTests.csproj | 183 ++++++++++++++++++ src/PackagedTests/Properties/AssemblyInfo.cs | 18 ++ src/PackagedTests/Properties/Default.rd.xml | 29 +++ src/PackagedTests/UnitTestApp.xaml | 7 + src/PackagedTests/UnitTestApp.xaml.cs | 102 ++++++++++ 22 files changed, 545 insertions(+), 79 deletions(-) delete mode 100644 src/AppInstallerCLIE2ETests/ComInterfaceTests.cs create mode 100644 src/PackagedTests/Assets/LockScreenLogo.scale-200.png create mode 100644 src/PackagedTests/Assets/SplashScreen.scale-200.png create mode 100644 src/PackagedTests/Assets/Square150x150Logo.scale-200.png create mode 100644 src/PackagedTests/Assets/Square44x44Logo.scale-200.png create mode 100644 src/PackagedTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 src/PackagedTests/Assets/StoreLogo.png create mode 100644 src/PackagedTests/Assets/Wide310x150Logo.scale-200.png create mode 100644 src/PackagedTests/ComInterfaceUnitTest.cs create mode 100644 src/PackagedTests/Package.appxmanifest create mode 100644 src/PackagedTests/PackagedTests.csproj create mode 100644 src/PackagedTests/Properties/AssemblyInfo.cs create mode 100644 src/PackagedTests/Properties/Default.rd.xml create mode 100644 src/PackagedTests/UnitTestApp.xaml create mode 100644 src/PackagedTests/UnitTestApp.xaml.cs diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index 0cba406aca..cc39a2781e 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -4,7 +4,9 @@ VisualStudioVersion = 16.0.29409.12 MinimumVisualStudioVersion = 10.0.40219.1 Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "AppInstallerCLIPackage", "AppInstallerCLIPackage\AppInstallerCLIPackage.wapproj", "{6AA3791A-0713-4548-A357-87A323E7AC3A}" ProjectSection(ProjectDependencies) = postProject + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD} = {4BC1F40B-36C2-4BBB-8306-76E490B13BBD} {1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69} + {EAF57FF2-A05A-4E73-80A7-CF686CE2D340} = {EAF57FF2-A05A-4E73-80A7-CF686CE2D340} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppInstallerCLI", "AppInstallerCLI\AppInstallerCLI.vcxproj", "{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}" @@ -125,7 +127,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServe EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Management.Deployment.Projection", "Microsoft.Management.Deployment.Projection\Microsoft.Management.Deployment.Projection.csproj", "{EAF57FF2-A05A-4E73-80A7-CF686CE2D340}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Management.Deployment.Projection", "Microsoft.Management.Deployment.Projection\Microsoft.Management.Deployment.Projection.csproj", "{EAF57FF2-A05A-4E73-80A7-CF686CE2D340}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTests\PackagedTests.csproj", "{8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution @@ -683,6 +687,47 @@ Global {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x64.Build.0 = Release|x64 {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x86.ActiveCfg = Release|Any CPU {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x86.Build.0 = Release|Any CPU + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|Any CPU.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.ActiveCfg = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Build.0 = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Deploy.0 = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.Build.0 = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.ActiveCfg = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.Build.0 = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.Deploy.0 = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Build.0 = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Deploy.0 = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.Build.0 = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.Deploy.0 = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.ActiveCfg = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.Build.0 = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.Deploy.0 = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM64.Build.0 = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM64.Deploy.0 = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x64.ActiveCfg = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x64.Build.0 = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x64.Deploy.0 = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.Build.0 = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.Deploy.0 = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|Any CPU.ActiveCfg = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.ActiveCfg = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Build.0 = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Deploy.0 = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.ActiveCfg = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.Build.0 = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.Deploy.0 = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.ActiveCfg = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.Build.0 = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.Deploy.0 = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.ActiveCfg = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.Build.0 = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/AppInstallerCLIE2ETests/ComInterfaceTests.cs b/src/AppInstallerCLIE2ETests/ComInterfaceTests.cs deleted file mode 100644 index 0132961436..0000000000 --- a/src/AppInstallerCLIE2ETests/ComInterfaceTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; - using System.IO; - using Microsoft.Management.Deployment; - - public class ComInterfaceTests : BaseCommand - { - [Test] - public void FindDefaultCatalog() - { - //int i = 0; - //while (i < 1000) - //{ - //try - //{ - PackageManager packageManager = new PackageManager(); - var catalogs = packageManager.GetPackageCatalogs(); - Assert.True(catalogs.Count > 0); - bool foundDefaultCatalog = false; - foreach (var catalog in catalogs) - { - if (catalog.Info.Name.Equals("winget")) - { - foundDefaultCatalog = true; - break; - } - } - Assert.True(foundDefaultCatalog); - //} - //catch (System.Exception) - //{ - - //} - // i++; - //} - } - } -} diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp index b56413c701..1e537db030 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp @@ -8,83 +8,74 @@ namespace winrt::Microsoft::Management::Deployment::implementation { winrt::Microsoft::Management::Deployment::PackageVersionId InstallOptions::PackageVersionId() { - throw hresult_not_implemented(); + return m_installOptions.PackageVersionId(); } void InstallOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.PackageVersionId(value); } hstring InstallOptions::PreferredInstallLocation() { - throw hresult_not_implemented(); + return m_installOptions.PreferredInstallLocation(); } void InstallOptions::PreferredInstallLocation(hstring const& value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.PreferredInstallLocation(value); } winrt::Microsoft::Management::Deployment::PackageInstallScope InstallOptions::PackageInstallScope() { - throw hresult_not_implemented(); + return m_installOptions.PackageInstallScope(); } void InstallOptions::PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.PackageInstallScope(value); } winrt::Microsoft::Management::Deployment::PackageInstallMode InstallOptions::PackageInstallMode() { - throw hresult_not_implemented(); + return m_installOptions.PackageInstallMode(); } void InstallOptions::PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const& value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.PackageInstallMode(value); } hstring InstallOptions::LogOutputPath() { - throw hresult_not_implemented(); + return m_installOptions.LogOutputPath(); } void InstallOptions::LogOutputPath(hstring const& value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.LogOutputPath(value); } bool InstallOptions::AllowHashMismatch() { - throw hresult_not_implemented(); + return m_installOptions.AllowHashMismatch(); } void InstallOptions::AllowHashMismatch(bool value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.AllowHashMismatch(value); } hstring InstallOptions::ReplacementInstallerArguments() { - throw hresult_not_implemented(); + return m_installOptions.ReplacementInstallerArguments(); } void InstallOptions::ReplacementInstallerArguments(hstring const& value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.ReplacementInstallerArguments(value); } hstring InstallOptions::CorrelationData() { - throw hresult_not_implemented(); + return m_installOptions.CorrelationData(); } void InstallOptions::CorrelationData(hstring const& value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.CorrelationData(value); } hstring InstallOptions::AdditionalPackageCatalogArguments() { - throw hresult_not_implemented(); + return m_installOptions.AdditionalPackageCatalogArguments(); } void InstallOptions::AdditionalPackageCatalogArguments(hstring const& value) { - UNREFERENCED_PARAMETER(value); - throw hresult_not_implemented(); + return m_installOptions.AdditionalPackageCatalogArguments(value); } } diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp index d8b2ee5bec..caaef1f95c 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp @@ -2,15 +2,10 @@ #include "PackageManager.h" #include "PackageManager.g.cpp" - - - - namespace winrt::Microsoft::Management::Deployment::implementation { winrt::Windows::Foundation::Collections::IVectorView PackageManager::GetPackageCatalogs() { - m_packageManager = winrt::create_instance(CLSID_PackageManager2, CLSCTX_ALL); return m_packageManager.GetPackageCatalogs(); } winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog) diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.h b/src/Microsoft.Management.Deployment.Client/PackageManager.h index 371fd29240..eac430757a 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.h +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.h @@ -7,7 +7,10 @@ namespace winrt::Microsoft::Management::Deployment::implementation { struct PackageManager : PackageManagerT { - PackageManager() = default; + PackageManager() + { + return m_packageManager = winrt::create_instance(CLSID_PackageManager2, CLSCTX_ALL); + } winrt::Windows::Foundation::Collections::IVectorView GetPackageCatalogs(); winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog); diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp index 3af5223199..76afca043e 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp @@ -28,6 +28,6 @@ namespace winrt::Microsoft::Management::Deployment::implementation } void PackageMatchFilter::Value(hstring const& value) { - m_packageMatchFilter.Option(); + m_packageMatchFilter.Value(value); } } diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h index 746d29b548..003bb363a5 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h @@ -3,7 +3,7 @@ #pragma once #include "PackageMatchFilter.g.h" -const CLSID CLSID_PackageMatchFilter2 = { 0xADBF3B4A, 0xDB8A, 0x496C, { 0xA5, 0x79, 0x62, 0xB5, 0x8F, 0x5F, 0xB1, 0x3F } }; //ADBF3B4A-DB8A-496C-A579-62B58F5FB13F +const CLSID CLSID_PackageMatchFilter2 = { 0xADBF3B4A, 0xDB8A, 0x496C, { 0xA5, 0x79, 0x62, 0xB5, 0x8F, 0x5F, 0xB1, 0x30 } }; //ADBF3B4A-DB8A-496C-A579-62B58F5FB13F namespace winrt::Microsoft::Management::Deployment::implementation { diff --git a/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj b/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj index dd3e41b718..d1d09b46f7 100644 --- a/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj +++ b/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj @@ -15,9 +15,10 @@ Microsoft.Management.Deployment + $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\Microsoft.Management.Deployment.Projection\ $(OutDir) - TRACE;/fl + TRACE;fl diff --git a/src/PackagedTests/Assets/LockScreenLogo.scale-200.png b/src/PackagedTests/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..735f57adb5dfc01886d137b4e493d7e97cf13af3 GIT binary patch literal 1430 zcmaJ>TTC2P7~aKltDttVHYH6u8Io4i*}3fO&d$gd*bA_<3j~&e7%8(eXJLfhS!M@! zKrliY>>6yT4+Kr95$!DoD(Qn-5TP|{V_KS`k~E6(LGS@#`v$hQo&^^BKsw3HIsZBT z_y6C2n`lK@apunKojRQ^(_P}Mgewt$(^BBKCTZ;*xa?J3wQ7~@S0lUvbcLeq1Bg4o zH-bvQi|wt~L7q$~a-gDFP!{&TQfc3fX*6=uHv* zT&1&U(-)L%Xp^djI2?~eBF2cxC@YOP$+9d?P&h?lPy-9M2UT9fg5jKm1t$m#iWE{M zIf%q9@;fyT?0UP>tcw-bLkz;s2LlKl2qeP0w zECS7Ate+Awk|KQ+DOk;fl}Xsy4o^CY=pwq%QAAKKl628_yNPsK>?A>%D8fQG6IgdJ ztnxttBz#NI_a@fk7SU`WtrpsfZsNs9^0(2a z@C3#YO3>k~w7?2hipBf{#b6`}Xw1hlG$yi?;1dDs7k~xDAw@jiI*+tc;t2Lflg&bM)0!Y;0_@=w%`LW^8DsYpS#-bLOklX9r?Ei}TScw|4DbpW%+7 zFgAI)f51s}{y-eWb|vrU-Ya!GuYKP)J7z#*V_k^Xo>4!1Yqj*m)x&0L^tg3GJbVAJ zJ-Pl$R=NAabouV=^z_t;^K*0AvFs!vYU>_<|I^#c?>>CR<(T?=%{;U=aI*SbZADLH z&(f2wz_Y0??Tf|g;?|1Znw6}6U43Q#qNRwv1vp9uFn1)V#*4p&%$mP9x&15^OaBiDS(XppT|z^>;B{PLVEbS3IFYV yGvCsSX*m literal 0 HcmV?d00001 diff --git a/src/PackagedTests/Assets/SplashScreen.scale-200.png b/src/PackagedTests/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..023e7f1feda78d5100569825acedfd213a0d84e9 GIT binary patch literal 7700 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 literal 0 HcmV?d00001 diff --git a/src/PackagedTests/Assets/Square150x150Logo.scale-200.png b/src/PackagedTests/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..af49fec1a5484db1d52a7f9b5ec90a27c7030186 GIT binary patch literal 2937 zcma)84OCO-8BSud5)jwMLRVKgX(S?$n?Ld|vrsm<$CF7)&zTbyy1FE5bU`Q17MRv`9ue$;R(@8kR;#vJ*IM0>cJIAOte!d7oRgdH zd%ySjdB6L9=gX^A6)VzH7p2l@v~3zJAMw|DFy#^)F@@F*`mqUn=Il>l)8_+ab;nOW{%+iPx z+s{Eu|&pIs)Z7{La9~?xKfyl z#43?gjEL15d4WbOZo#SiP%>DB^+BcnJ=7dHEe;r#G=tuw|ka z%q@}##Uh7;tc%L_64m(kHtw74ty%BJMb)_1)#S0j`)F8_1jF7vScpsnH=0V19bO8y zR`0SjIdCUo&=>JwMQF8KHA<{ODHTiQh}0^@5QRmCA?gOH6_H3K^-_sNB^RrdNuK-R zOO*vOrKCVvDwgUck`kF(E7j{I#iiN;b*ZdCt4m@HPA`EuEqGGf4%!K<;(=I=&Vyrw z%TwcWtxa}8mCZ%Cyf&ActJ6_$ox5z6-D!0-dvnRx6t7y3d+h6QYpKWO;8OdnvERo7 zuEf>ih5`wqY)~o@OeVt-wM?Q!>QzdGRj!bz6fzYrfw$hZfAKzr2-M+D+R>}~oT574c;_3zquHcElqKIsryILt3g8n3jcMb+j?i?-L3FpZJ z2WRVBRdDPc+G5aaYg#5hpE+6nQ|(VSoxT3|biF;BUq#==-27Xi=gihDPYP$7?=9cP zYKE$jeQ|3~_L0VG-(F~2ZPyD0=k{J4Q~h(t__{-mz_w8{JDY9{`1ouzz!Vr5!ECdE z6U~O1k8c}24V7~zzXWTV-Pe4)y}wQJS&q%H5`Fo_f_JvIU489aCX$;P`u#!I-=^4ijC2{&9!O&h>mi?9oYD=GC#%)6{GzN6nQYw+Fal50!#x^asjBBR50i`+mho*ttoqV)ubM2KD9S~k7+FR4>{29?6 z{!l6kDdyTN0YJ9LgkPWeXm|gyi@zM3?0@{&pXT12w|78&W-q!RRF)&iLCEZVH<|fR zN0fr2^t8H(>L?>K#>^+jWROLral(Qy-xoBq1U7A&DV||wClb)Otd9?(gZ|8znMF}D zf<1haWz^s0qgecz;RFGt0C-B4g`jNGHsFU+;{<%t65v^sjk^h$lmWn#B0#_)9ij&d z-~lc`A)YYExi^7sBuPM^Y|wA2g*5?`K?#7tzELQYNxGo$UB$4J8RJp1k(8Jj+~hMT zlN~>M@KTTh^--8y3PK_NZ@AC!{PT=CziBzGd+wTJ^@icH!Bd}%)g8V)%K?|c&WTUk zy}qv1C%(fjRoZ4ozC3{O%@5?)XzH35zHns$pgU*Q?fj4v?fp1Qbm+j;3l;9jam9Da zXVcKjPlQ73x78QPu|Ffm6x?`~e3oD=gl=4kYK?={kD5j~QCXU)`HSdduNNENzA*2$ zOm3PzF!lN5e*06-f1Uot67wY#{o-S1!KZ7E=!~7ynnk9_iJR#kFoNbAOT#^2Gd17F zMmvU6>lndZQGd|ax9kUoXXO+$N?|j@6qpsF&_j7YXvwo_C{JpmLw5&#e6k>atv%es z5)7r*Wvv_JkUpT}M!_o!nVlEk1Zbl=a*2hQ*<|%*K1Glj^FcF`6kTzGQ3lz~2tCc@ z&x|tj;aH&1&9HwcJBcT`;{?a+pnej;M1HO(6Z{#J!cZA04hnFl;NXA+&`=7bjW_^o zfC40u3LMG?NdPtwGl>Tq6u}*QG)}-y;)lu-_>ee3kibW(69n0$0Zy!}9rQz%*v1iO zT9_H>99yIrSPYVy6^);rR}7Yo=J_T@hi+qhTZXnVWyf;JDYm5#eYLTxr*?kiNn!+Y zQ+LUkBafNJ#rH#C(?d5^;gw9o#%daEI{mA*LHPIHPU`#|H$hD zwm>0&+kahQ)E#%~k>&5@&#Vg82H?s%71=)(soi@174pi9--2{w{1$}Sz4zGn3Du&x bht0Iza^2ykEt4(epJ78uh5nDlX8(TxzDYwP literal 0 HcmV?d00001 diff --git a/src/PackagedTests/Assets/Square44x44Logo.scale-200.png b/src/PackagedTests/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..ce342a2ec8a61291ba76c54604aea7e9d20af11b GIT binary patch literal 1647 zcmaJ?eM}Q)7(e+G1Q(|`V9JhTI2>MkceK4;p;PR&$Pi?ejk3YQ_3o`S&|W_dsOZ8# zWPTt69g`t$ab`0cj-Y0yiBSOqmd)tG7G(}M5aP0_%&9TijB#&)I{zSE^4@#z^FF`l z`8{8`o%wlL(UI|y2!cdsuVamHH~H86F!*-15em4)NqUpCQM5?aoC_eCf@lV4wvF2a zjDQn1JBL69f&@2M3rvzJcfE!eZ8FZUBlFlC5RD)it33{mF9#B82AiyQE%w)`vlwa> zv{<1sm&kSKK$&%2jSFn7$t&P%%6Ue>R=EAnG8N7fqynWG8L3p!4801a;8{+nliO(qd(jNJ_?+9W3#hLIDLoT6~3fx9=`CC-D}-AMrpEO7HK zt3$GicGPc?GmDjy7K2P@La;eu4!$zWCZ`ym{Z$b zu-O6RM&K4JT|BIZB`E-gxqG%FzanI#+2FFmqHqXG7yxWB=w55RGOM)$xMb(>kSNR z2w=1AZi%z=AmG~yea~XaXJR!v7vLn(RUnELfiB1|6D84ICOS}^Zo2AdN}<&*h}G_u z{xZ!(%>tLT3J3<5XhWy-tg+6)0nmUUENLW8TWA{R6bgVd3X;anYFZ^IRis*_P-C-r z;i>%1^eL3UI2-{w8nuFFcs0e~7J{O2k^~Ce%+Ly4U?|=!0LH=t6()xi<^I-rs+9sF z*q{E-CxZbGPeu#a;XJwE;9S1?#R&uns>^0G3p`hEUF*v`M?@h%T%J%RChmD|EVydq zmHWh*_=S%emRC*mhxaVLzT@>Z2SX0u9v*DIJ@WC^kLVdlGV6LpK$KIrlJqc zpJ921)+3JJdTx|<`G&kXpKkjGJv=76R`yYIQ{#c-`%+`#V(7}Q;&@6U8!Td1`d;?N z_9mnI#?AA}4J!r)LN4!E-@H5eXauuB7TOawS>Y|{-P?NNx-lq+z1W-+y(;39P&&LP zL{N80?&=C*qKmdA^moMZRuPcD!B<*mq$ch=0Cnlitw#txRWhb3%TQvPqjkC`F69G4b! ze7z9MZ#+;_#l?H37UqUhDFb^l&s2{oM$3I0o^Q!yx;;V)QmCMo)Tb_ui|mit8MS?U zm##6$sZZ1$@|s%?l@>4Z<*Q}sRBSKMhb4I{e5LdEhsHIHTe8Bod5c>6QtT>$XgUBz z6MK`kO$=jmt@FqggOhJ5j~e@ygRbG;<{Vu)*+nn9aQeo0;$#j;|MS=S$&L?BeV25z xs3B`@=#`5TF{^6(A1rvdY@|-RtQ|iS5{tyX+wH?;n8E)G$kykv-D^wh{{!TZT%7;_ literal 0 HcmV?d00001 diff --git a/src/PackagedTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/src/PackagedTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000000000000000000000000000000000000..f6c02ce97e0a802b85f6021e822c89f8bf57d5cd GIT binary patch literal 1255 zcmaJ>TWs4@7*5+{G#S+&C!qC#> zf>5N3P6jO*Cz>ug*(_DmW=)kea&m$gZ^+nyiF`;j%w@}y8)>p*SH}C`m?DXeieF2U zyQHecc_L%Gh!7GMt+hG06y;+|p4>m~}PjA}rKViGiEnn7G0ZO<>G|7q;2?NwGCM3s?eued6%hd$B+ z*kQJ{#~$S=DFE(%=E+UkmlEI*%3llUf~8Ja9YU1Vui0IbGBkW_gHB%Rd&!!ioX zs40O?i9I{};kle7GMvE7(rk`la=gTI)47=>%?q@^iL-nUo3}h4S}N-KHn8t5mVP8w z&bSErwp+37 zNJJ8?a|{r5Q3R0Z5s-LB1WHOwYC@7pCHWND#cL1cZ?{kJ368_*(UDWUDyb<}0y@o# zfMF016iMWPCb6obAxT$JlB6(2DrlXDTB&!0`!m??4F(qWMhjVZo?JXQmz`1*58Z=& zcDmB|S-E@j?BoFGix0flckqdS4jsPNzhfWyWIM98GxcLs89C(~dw%$_t;JjX-SD}E zfiGV;{8Q%8r}w9x>EEigW81>`kvnU@pK)4+xk9@+bNj9L!AAZ@SZ@q|)&BmY3+HZx zul~BeG4|}-;L%cHViQGQX?^zFfO0&#cHwel=d`lH9sJ-@Sl@n*(8J2>%Ac`IxyY?Q z{=GhWvC#gu-~Ia7*n{=+;qM?Ul_wy1+u7ho;=`>EwP^g~R@{unBds`!#@}tluZQpS zm)M~nYEifJWJGx?_6DcTy>#uh%>!H9=hb^(v`=m3F1{L>db=<5_tm+_&knAQ2EU$s Mu9UqpbNZeC0BbUo^Z)<= literal 0 HcmV?d00001 diff --git a/src/PackagedTests/Assets/StoreLogo.png b/src/PackagedTests/Assets/StoreLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..7385b56c0e4d3c6b0efe3324aa1194157d837826 GIT binary patch literal 1451 zcmaJ>eN5D57_Z|bH;{0+1#mbl)eTU3{h)Wf7EZV?;HD@XL@{B`Ui%(2aMxQ~xdXSv z5nzWi(LW)U2=Vc-cY@s7nPt{i0hc6!7xN4NNHI#EQl>YNBy8l4%x9gr_W-j zEZMQmmTIy(>;lblRfh`dIyTgc9W5d!VP$L4(kKrN1c5G~(O_#xG zAJCNTstD^5SeXFB+&$h=ToJP2H>xr$iqPs-#O*;4(!Fjw25-!gEb*)mU}=)J;Iu>w zxK(5XoD0wrPSKQ~rbL^Cw6O_03*l*}i=ydbu7adJ6y;%@tjFeXIXT+ms30pmbOP%Q zX}S;+LBh8Tea~TSkHzvX6$rYb)+n&{kSbIqh|c7hmlxmwSiq5iVhU#iEQ<>a18|O^Sln-8t&+t`*{qBWo5M?wFM(JuimAOb5!K#D}XbslM@#1ZVz_;!9U zpfEpLAOz=0g@bd6Xj_ILi-x^!M}73h^o@}hM$1jflTs|Yuj9AL@A3<-?MV4!^4q`e z)fO@A;{9K^?W?DbnesnPr6kK>$zaKo&;FhFd(GYFCIU^T+OIMb%Tqo+P%oq(IdX7S zf6+HLO?7o0m+p>~Tp5UrXWh!UH!wZ5kv!E`_w)PTpI(#Iw{AS`gH4^b(bm^ZCq^FZ zY9DD7bH}rq9mg88+KgA$Zp!iWncuU2n1AuIa@=sWvUR-s`Qb{R*kk(SPU^`$6BXz8 zn#7yaFOIK%qGxyi`dYtm#&qqox0$h=pNi#u=M8zUG@bpiZ=3sT=1}Trr}39cC)H|v zbL?W)=&s4zrh)7>L(|cc%$1#!zfL?HjpeP%T+x_a+jZ16b^iKOHxFEX$7d|8${H-* zIrOJ5w&i$>*D>AKaIoYg`;{L@jM((Kt?$N$5OnuPqVvq**Nm}(f0wwOF%iX_Pba;V z;m@wxX&NcV3?<1+u?A{y_DIj7#m3Af1rCE)o`D&Y3}0%7E;iX1yMDiS)sh0wKi!36 zL!Wmq?P^Ku&rK~HJd97KkLTRl>ScGFYZNlYytWnhmuu|)L&ND8_PmkayQb{HOY640 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x literal 0 HcmV?d00001 diff --git a/src/PackagedTests/Assets/Wide310x150Logo.scale-200.png b/src/PackagedTests/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..288995b397fdbef1fb7e85afd71445d5de1952c5 GIT binary patch literal 3204 zcmbVPeQXow8NYmBd90>}0NP?GhXW~VaeThm=a0tV#EwJMI!)6M3}|c4_Bl3=Kd>G0 z(GHx1wl<7(tP?FsOQkTilSo*iIvF%uArExJ73~P zSv1xEy!U(Wd4A9D`FQV@W3@F^qJ@PEF$@z`Z!*BbFsS(^?B zyiAzJ+q})bkgiQHWqEb*jJD-coHYr1^iocg)l!Qa{Xqs-l~6J}p-|##ZHYofskQ3$ zI0;xzXyhazBeXhIsg5A=%ufo@f)1yy&ScKS0;HF^!r_2UE^lpZEom(+@duma3awTv zCrCL-%D_SvYWIcdHkmI}#50(fkUi)Qgx!80ju>g1za^}ff>JI8Z@^-iCiaCgg@TgF z+vtE?Q9{VQUX&MW9SYYmGcxA14%N2@7FwBTD4N<(2{nWgV8$e3?-F=L^&FrtWn~(U_Q~~^uYiyeY6-KoTnfh9AWz@ zIKje0)u!_Lw)E}G!#kEfwKVdNt(UAf9*f>tEL_(=xco-T%jTi@7YlC3hs2ik%Le0H ztj}RTeCF(5mwvi3_56>-yB?l;J>-1%!9~=fs|QcNG3J~a@JCu`4SB460s0ZO+##4fFUSGLcj_ja^fL4&BKALfb#$6$O?>P@qx2Agl^x0i&ugt zsy5Pyu=()`7HRMG3IB7F1@`_ z+-!J%#i6e^U$e#+C%Q>_qVRzWRsG^W_n+@OcX@vzI&z;mzHNb!GQ?LWA(wtpqHqTM z1OFw_{Zn?fD)p)`c`kOgv{de=v@suGRqY{N^U7gI1VF3*F=obwaXI6ob5__Yn zVTguS!%(NI09J8x#AO_aW!9W7k*UvB;IWDFC3srwftr{kHj%g)fvnAm;&h_dnl~

MY- zf+K}sCe8qU6Ujs`3ua{U0Of$R_gVQBuUA za0v=mu#vIOqiiAZOr&h*$WyOw&k-xr$;G4Ixa!#TJNr>95(h>l%)PUy4p+^SgR(uR zta%k*?ny-+nAr8spEk1fo{J4i!b^Fia`N{_F6@zidA2ZTTrjl#^5Z-2KfB@Cu}l9s z(*|Z2jc?p~vn2f)3y9i*7zJV1L{$?|&q)4oaT;uXi6>1GkRXVTOzAz(RHEmr=eFIi z`}<>-Q?K0GN8!IYxeP1XKXO+jsJbp~o^);Bc;%b7Flpe7;1`Ny@3r7ZR;?R)aJt8C ziNlEC<@3f_lIV4TwV}&e;D!Ee5_|e#g0LUh=5vmYWYm7&2h*M>QPKvGh9-)wfMMW3 z8J9b%1k7dzPzO0_NGQy92BZ^FR6R~6;^6?lqO;-QUP4BY%cG%3vEhbm#>4vIhPBh3 z-+pZGjh$x%Hp{?=FHsMp0&wNPlj00us{&`1ZOZTqs8%4X&xH=UDr*xyBW(Zp&Em94 zf)ZSfn#yg0N)>!1kWdkqJ^S*z0FF5|fj&qcE#Na|%OY0$uO>!&hP+1ywfD_WXk@4J(?MBftK7>$Nvqh@tDuarN%PrTLQ2Uzysx>UV=V zk^RrDSvdQ?0;=hY67EgII-f4`t=+i*yS=Y~!XlqIy_4x&%+OdfbKOFPXS2X5%4R{N z$SQMX^AK6(fA catalogs = packageManager.GetPackageCatalogs(); + Assert.IsTrue(catalogs.Count > 0); + bool foundDefaultCatalog = false; + for(int i = 0; i < catalogs.Count; i++) + { + if (catalogs[i].Info.Name.Equals("winget")) + { + foundDefaultCatalog = true; + break; + } + } + // TODO: Investigate why casting fails here. + /*foreach (var catalog in catalogs) + { + if (catalog.Info.Name.Equals("winget"))e + { + foundDefaultCatalog = true; + break; + } + }*/ + Assert.IsTrue(foundDefaultCatalog); + } + + [TestMethod] + public void OpenPredefinedStoreCatalog() + { + PackageManager packageManager = new PackageManager(); + PackageCatalogReference catalogRef = packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog.OpenWindowsCatalog); + Assert.IsTrue(catalogRef.Info.Name.Equals("winget")); + IReadOnlyList catalogs = packageManager.GetPackageCatalogs(); + Assert.IsTrue(catalogs.Count > 0); + bool foundDefaultCatalog = false; + for (int i = 0; i < catalogs.Count; i++) + { + if (catalogs[i].Info.Name.Equals("winget")) + { + foundDefaultCatalog = true; + break; + } + } + // TODO: Investigate why casting fails here. + /*foreach (var catalog in catalogs) + { + if (catalog.Info.Name.Equals("winget"))e + { + foundDefaultCatalog = true; + break; + } + }*/ + Assert.IsTrue(foundDefaultCatalog); + } + + public void PopulateInstallOptions() + { + InstallOptions installOptions = new InstallOptions(); + //Assert.IsTrue(foundDefaultCatalog); + } + } +} diff --git a/src/PackagedTests/Package.appxmanifest b/src/PackagedTests/Package.appxmanifest new file mode 100644 index 0000000000..d8c34a8b5f --- /dev/null +++ b/src/PackagedTests/Package.appxmanifest @@ -0,0 +1,58 @@ + + + + + + + + + PackagedUnitTests + sreading + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + Microsoft.Management.Deployment.dll + + + + + + + + + \ No newline at end of file diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj new file mode 100644 index 0000000000..9485af49e3 --- /dev/null +++ b/src/PackagedTests/PackagedTests.csproj @@ -0,0 +1,183 @@ + + + + + Debug + x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568} + AppContainerExe + Properties + PackagedUnitTests + PackagedUnitTests + en-US + UAP + 10.0.19041.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(VisualStudioVersion) + false + False + True + True + Always + x64 + 0 + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + true + true + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + true + true + + + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM64 + false + prompt + true + true + + + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM64 + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + PackageReference + + + + + + + + UnitTestApp.xaml + + + + + + MSBuild:Compile + Designer + + + + + Designer + + + + + + + + + + + + + + + 6.2.12 + + + 2.2.3 + + + 2.2.3 + + + + + {4bc1f40b-36c2-4bbb-8306-76e490b13bbd} + Microsoft.Management.Deployment.Client + + + + 14.0 + + + + \ No newline at end of file diff --git a/src/PackagedTests/Properties/AssemblyInfo.cs b/src/PackagedTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..8d2eca9a02 --- /dev/null +++ b/src/PackagedTests/Properties/AssemblyInfo.cs @@ -0,0 +1,18 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("PackagedUnitTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("HP Inc.")] +[assembly: AssemblyProduct("PackagedUnitTests")] +[assembly: AssemblyCopyright("Copyright © HP Inc. 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyMetadata("TargetPlatform","UAP")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/src/PackagedTests/Properties/Default.rd.xml b/src/PackagedTests/Properties/Default.rd.xml new file mode 100644 index 0000000000..e019b9308c --- /dev/null +++ b/src/PackagedTests/Properties/Default.rd.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/PackagedTests/UnitTestApp.xaml b/src/PackagedTests/UnitTestApp.xaml new file mode 100644 index 0000000000..d3311c10d1 --- /dev/null +++ b/src/PackagedTests/UnitTestApp.xaml @@ -0,0 +1,7 @@ + + + diff --git a/src/PackagedTests/UnitTestApp.xaml.cs b/src/PackagedTests/UnitTestApp.xaml.cs new file mode 100644 index 0000000000..17b374b022 --- /dev/null +++ b/src/PackagedTests/UnitTestApp.xaml.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.ApplicationModel; +using Windows.ApplicationModel.Activation; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +namespace PackagedUnitTests +{ + ///

+ /// Provides application-specific behavior to supplement the default Application class. + /// + sealed partial class App : Application + { + /// + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). + /// + public App() + { + this.InitializeComponent(); + this.Suspending += OnSuspending; + } + + /// + /// Invoked when the application is launched normally by the end user. Other entry points + /// will be used such as when the application is launched to open a specific file. + /// + /// Details about the launch request and process. + protected override void OnLaunched(LaunchActivatedEventArgs e) + { + +#if DEBUG + if (System.Diagnostics.Debugger.IsAttached) + { + this.DebugSettings.EnableFrameRateCounter = true; + } +#endif + + Frame rootFrame = Window.Current.Content as Frame; + + // Do not repeat app initialization when the Window already has content, + // just ensure that the window is active + if (rootFrame == null) + { + // Create a Frame to act as the navigation context and navigate to the first page + rootFrame = new Frame(); + + rootFrame.NavigationFailed += OnNavigationFailed; + + if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) + { + //TODO: Load state from previously suspended application + } + + // Place the frame in the current Window + Window.Current.Content = rootFrame; + } + + Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI(); + + // Ensure the current window is active + Window.Current.Activate(); + + Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(e.Arguments); + } + + /// + /// Invoked when Navigation to a certain page fails + /// + /// The Frame which failed navigation + /// Details about the navigation failure + void OnNavigationFailed(object sender, NavigationFailedEventArgs e) + { + throw new Exception("Failed to load Page " + e.SourcePageType.FullName); + } + + /// + /// Invoked when application execution is being suspended. Application state is saved + /// without knowing whether the application will be terminated or resumed with the contents + /// of memory still intact. + /// + /// The source of the suspend request. + /// Details about the suspend request. + private void OnSuspending(object sender, SuspendingEventArgs e) + { + var deferral = e.SuspendingOperation.GetDeferral(); + //TODO: Save application state and stop any background activity + deferral.Complete(); + } + } +} From 214f6b83a47e1fc1122c242c8bad7bc80f59820a Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Sat, 14 Aug 2021 19:07:30 -0700 Subject: [PATCH 03/53] Override factory to return objects. --- .../CatalogPackage.cpp | 80 +++++++++--------- .../CatalogPackage.h | 4 - .../ConnectResult.cpp | 34 ++++---- .../ConnectResult.h | 30 +++---- .../CreateCompositePackageCatalogOptions.cpp | 6 +- .../CreateCompositePackageCatalogOptions.h | 11 ++- .../FindPackagesOptions.cpp | 8 +- .../FindPackagesOptions.h | 11 ++- .../FindPackagesResult.cpp | 42 +++++----- .../FindPackagesResult.h | 32 +++---- .../InstallOptions.cpp | 52 ++++++------ .../InstallOptions.h | 11 ++- .../PackageCatalog.cpp | 51 ++++++------ .../PackageCatalog.h | 34 ++++---- .../PackageCatalogInfo.cpp | 74 ++++++++--------- .../PackageCatalogReference.cpp | 50 +++++------ .../PackageCatalogReference.h | 34 ++++---- .../PackageManager.cpp | 22 ++--- .../PackageManager.h | 11 ++- .../PackageMatchFilter.cpp | 18 ++-- .../PackageMatchFilter.h | 11 ++- .../PackageVersionId.cpp | 42 +++++----- .../PackageVersionId.h | 32 +++---- .../PackageVersionInfo.cpp | 83 +++++++++---------- .../PackageVersionInfo.h | 42 +++++----- 25 files changed, 404 insertions(+), 421 deletions(-) diff --git a/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp b/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp index df0caa2d02..b89293c930 100644 --- a/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp +++ b/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp @@ -1,43 +1,37 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "CatalogPackage.h" -#include "CatalogPackage.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring CatalogPackage::Id() - { - throw hresult_not_implemented(); - } - hstring CatalogPackage::Name() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::InstalledVersion() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::Collections::IVectorView CatalogPackage::AvailableVersions() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::DefaultInstallVersion() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey) - { - UNREFERENCED_PARAMETER(versionKey); - throw hresult_not_implemented(); - } - bool CatalogPackage::IsUpdateAvailable() - { - throw hresult_not_implemented(); - } - - winrt::Microsoft::Management::Deployment::CatalogPackage CatalogPackage::GetServerPackage() - { - return m_catalogPackage; - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "CatalogPackage.h" +#include "CatalogPackage.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring CatalogPackage::Id() + { + throw hresult_not_implemented(); + } + hstring CatalogPackage::Name() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::InstalledVersion() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::Collections::IVectorView CatalogPackage::AvailableVersions() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::DefaultInstallVersion() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const&) + { + throw hresult_not_implemented(); + } + bool CatalogPackage::IsUpdateAvailable() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/CatalogPackage.h b/src/Microsoft.Management.Deployment.Client/CatalogPackage.h index bb463e9752..79738d946d 100644 --- a/src/Microsoft.Management.Deployment.Client/CatalogPackage.h +++ b/src/Microsoft.Management.Deployment.Client/CatalogPackage.h @@ -16,9 +16,5 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Microsoft::Management::Deployment::PackageVersionInfo DefaultInstallVersion(); winrt::Microsoft::Management::Deployment::PackageVersionInfo GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey); bool IsUpdateAvailable(); - - winrt::Microsoft::Management::Deployment::CatalogPackage GetServerPackage(); - private: - winrt::Microsoft::Management::Deployment::CatalogPackage m_catalogPackage{ nullptr }; }; } diff --git a/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp b/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp index 9c957d489c..40dd27204a 100644 --- a/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp +++ b/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp @@ -1,17 +1,17 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "ConnectResult.h" -#include "ConnectResult.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - winrt::Microsoft::Management::Deployment::ConnectResultStatus ConnectResult::Status() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalog ConnectResult::PackageCatalog() - { - throw hresult_not_implemented(); - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConnectResult.h" +#include "ConnectResult.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::ConnectResultStatus ConnectResult::Status() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalog ConnectResult::PackageCatalog() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/ConnectResult.h b/src/Microsoft.Management.Deployment.Client/ConnectResult.h index bec80cc105..b0ff6b47e3 100644 --- a/src/Microsoft.Management.Deployment.Client/ConnectResult.h +++ b/src/Microsoft.Management.Deployment.Client/ConnectResult.h @@ -1,15 +1,15 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "ConnectResult.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct ConnectResult : ConnectResultT - { - ConnectResult() = default; - - winrt::Microsoft::Management::Deployment::ConnectResultStatus Status(); - winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); - }; -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConnectResult.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct ConnectResult : ConnectResultT + { + ConnectResult() = default; + + winrt::Microsoft::Management::Deployment::ConnectResultStatus Status(); + winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp index 5f5855557f..d732a70564 100644 --- a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp @@ -8,14 +8,14 @@ namespace winrt::Microsoft::Management::Deployment::implementation { winrt::Windows::Foundation::Collections::IVector CreateCompositePackageCatalogOptions::Catalogs() { - return m_createCompositePackageCatalogOptions.Catalogs(); + throw hresult_not_implemented(); } winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CreateCompositePackageCatalogOptions::CompositeSearchBehavior() { - return m_createCompositePackageCatalogOptions.CompositeSearchBehavior(); + throw hresult_not_implemented(); } void CreateCompositePackageCatalogOptions::CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value) { - m_createCompositePackageCatalogOptions.CompositeSearchBehavior(value); + throw hresult_not_implemented(); } } diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h index 6e1757a16e..0a4befcdbb 100644 --- a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h +++ b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h @@ -9,21 +9,20 @@ namespace winrt::Microsoft::Management::Deployment::implementation { struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT { - CreateCompositePackageCatalogOptions() - { - m_createCompositePackageCatalogOptions = winrt::create_instance(CLSID_CreateCompositePackageCatalogOptions2, CLSCTX_ALL); - } + CreateCompositePackageCatalogOptions() = default; winrt::Windows::Foundation::Collections::IVector Catalogs(); winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CompositeSearchBehavior(); void CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value); - private: - winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions m_createCompositePackageCatalogOptions{ nullptr }; }; } namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT { + auto ActivateInstance() const + { + return winrt::create_instance(CLSID_CreateCompositePackageCatalogOptions2, CLSCTX_ALL); + } }; } diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp index e814328b34..37180ed522 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp @@ -8,18 +8,18 @@ namespace winrt::Microsoft::Management::Deployment::implementation { winrt::Windows::Foundation::Collections::IVector FindPackagesOptions::Selectors() { - return m_findPackagesOptions.Selectors(); + throw hresult_not_implemented(); } winrt::Windows::Foundation::Collections::IVector FindPackagesOptions::Filters() { - return m_findPackagesOptions.Filters(); + throw hresult_not_implemented(); } uint32_t FindPackagesOptions::ResultLimit() { - return m_findPackagesOptions.ResultLimit(); + throw hresult_not_implemented(); } void FindPackagesOptions::ResultLimit(uint32_t value) { - m_findPackagesOptions.ResultLimit(value); + throw hresult_not_implemented(); } } diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h index a248081484..4401c4d7fe 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h @@ -9,22 +9,21 @@ namespace winrt::Microsoft::Management::Deployment::implementation { struct FindPackagesOptions : FindPackagesOptionsT { - FindPackagesOptions() - { - m_findPackagesOptions = winrt::create_instance(CLSID_FindPackagesOptions2, CLSCTX_ALL); - } + FindPackagesOptions() = default; winrt::Windows::Foundation::Collections::IVector Selectors(); winrt::Windows::Foundation::Collections::IVector Filters(); uint32_t ResultLimit(); void ResultLimit(uint32_t value); - private: - winrt::Microsoft::Management::Deployment::FindPackagesOptions m_findPackagesOptions{ nullptr }; }; } namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct FindPackagesOptions : FindPackagesOptionsT { + auto ActivateInstance() const + { + return winrt::create_instance(CLSID_FindPackagesOptions2, CLSCTX_ALL); + } }; } diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp index 3ae321d3a2..75fc89335f 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp @@ -1,21 +1,21 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "FindPackagesResult.h" -#include "FindPackagesResult.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResult::Status() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::Collections::IVectorView FindPackagesResult::Matches() - { - throw hresult_not_implemented(); - } - bool FindPackagesResult::WasLimitExceeded() - { - throw hresult_not_implemented(); - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "FindPackagesResult.h" +#include "FindPackagesResult.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResult::Status() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::Collections::IVectorView FindPackagesResult::Matches() + { + throw hresult_not_implemented(); + } + bool FindPackagesResult::WasLimitExceeded() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h index 28add522d0..83dafaff84 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h @@ -1,16 +1,16 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "FindPackagesResult.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct FindPackagesResult : FindPackagesResultT - { - FindPackagesResult() = default; - - winrt::Microsoft::Management::Deployment::FindPackagesResultStatus Status(); - winrt::Windows::Foundation::Collections::IVectorView Matches(); - bool WasLimitExceeded(); - }; -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "FindPackagesResult.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct FindPackagesResult : FindPackagesResultT + { + FindPackagesResult() = default; + + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus Status(); + winrt::Windows::Foundation::Collections::IVectorView Matches(); + bool WasLimitExceeded(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp index 1e537db030..33a034d376 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp @@ -8,74 +8,74 @@ namespace winrt::Microsoft::Management::Deployment::implementation { winrt::Microsoft::Management::Deployment::PackageVersionId InstallOptions::PackageVersionId() { - return m_installOptions.PackageVersionId(); + throw hresult_not_implemented(); } - void InstallOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value) + void InstallOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const&) { - return m_installOptions.PackageVersionId(value); + throw hresult_not_implemented(); } hstring InstallOptions::PreferredInstallLocation() { - return m_installOptions.PreferredInstallLocation(); + throw hresult_not_implemented(); } void InstallOptions::PreferredInstallLocation(hstring const& value) { - return m_installOptions.PreferredInstallLocation(value); + throw hresult_not_implemented(); } winrt::Microsoft::Management::Deployment::PackageInstallScope InstallOptions::PackageInstallScope() { - return m_installOptions.PackageInstallScope(); + throw hresult_not_implemented(); } - void InstallOptions::PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value) + void InstallOptions::PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const&) { - return m_installOptions.PackageInstallScope(value); + throw hresult_not_implemented(); } winrt::Microsoft::Management::Deployment::PackageInstallMode InstallOptions::PackageInstallMode() { - return m_installOptions.PackageInstallMode(); + throw hresult_not_implemented(); } - void InstallOptions::PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const& value) + void InstallOptions::PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const&) { - return m_installOptions.PackageInstallMode(value); + throw hresult_not_implemented(); } hstring InstallOptions::LogOutputPath() { - return m_installOptions.LogOutputPath(); + throw hresult_not_implemented(); } - void InstallOptions::LogOutputPath(hstring const& value) + void InstallOptions::LogOutputPath(hstring const&) { - return m_installOptions.LogOutputPath(value); + throw hresult_not_implemented(); } bool InstallOptions::AllowHashMismatch() { - return m_installOptions.AllowHashMismatch(); + throw hresult_not_implemented(); } - void InstallOptions::AllowHashMismatch(bool value) + void InstallOptions::AllowHashMismatch(bool) { - return m_installOptions.AllowHashMismatch(value); + throw hresult_not_implemented(); } hstring InstallOptions::ReplacementInstallerArguments() { - return m_installOptions.ReplacementInstallerArguments(); + throw hresult_not_implemented(); } - void InstallOptions::ReplacementInstallerArguments(hstring const& value) + void InstallOptions::ReplacementInstallerArguments(hstring const&) { - return m_installOptions.ReplacementInstallerArguments(value); + throw hresult_not_implemented(); } hstring InstallOptions::CorrelationData() { - return m_installOptions.CorrelationData(); + throw hresult_not_implemented(); } - void InstallOptions::CorrelationData(hstring const& value) + void InstallOptions::CorrelationData(hstring const&) { - return m_installOptions.CorrelationData(value); + throw hresult_not_implemented(); } hstring InstallOptions::AdditionalPackageCatalogArguments() { - return m_installOptions.AdditionalPackageCatalogArguments(); + throw hresult_not_implemented(); } - void InstallOptions::AdditionalPackageCatalogArguments(hstring const& value) + void InstallOptions::AdditionalPackageCatalogArguments(hstring const&) { - return m_installOptions.AdditionalPackageCatalogArguments(value); + throw hresult_not_implemented(); } } diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.h b/src/Microsoft.Management.Deployment.Client/InstallOptions.h index fb39f7d7f4..2116f6a6f8 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.h +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.h @@ -9,10 +9,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation { struct InstallOptions : InstallOptionsT { - InstallOptions() - { - m_installOptions = winrt::create_instance(CLSID_InstallOptions2, CLSCTX_ALL); - } + InstallOptions() = default; winrt::Microsoft::Management::Deployment::PackageVersionId PackageVersionId(); void PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value); @@ -32,13 +29,15 @@ namespace winrt::Microsoft::Management::Deployment::implementation void CorrelationData(hstring const& value); hstring AdditionalPackageCatalogArguments(); void AdditionalPackageCatalogArguments(hstring const& value); - private: - winrt::Microsoft::Management::Deployment::InstallOptions m_installOptions{ nullptr }; }; } namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct InstallOptions : InstallOptionsT { + auto ActivateInstance() const + { + return winrt::create_instance(CLSID_InstallOptions2, CLSCTX_ALL); + } }; } diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp index 0f65ae4648..948a159d40 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp @@ -1,26 +1,25 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "PackageCatalog.h" -#include "PackageCatalog.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - bool PackageCatalog::IsComposite() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalog::Info() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::IAsyncOperation PackageCatalog::FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options) - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::FindPackagesResult PackageCatalog::FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options) - { - UNREFERENCED_PARAMETER(options); - throw hresult_not_implemented(); - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageCatalog.h" +#include "PackageCatalog.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + bool PackageCatalog::IsComposite() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalog::Info() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::IAsyncOperation PackageCatalog::FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions) + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::FindPackagesResult PackageCatalog::FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const&) + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalog.h b/src/Microsoft.Management.Deployment.Client/PackageCatalog.h index 0299a0b45f..648d6ca7a1 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalog.h +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalog.h @@ -1,17 +1,17 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageCatalog.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageCatalog : PackageCatalogT - { - PackageCatalog() = default; - - bool IsComposite(); - winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); - winrt::Windows::Foundation::IAsyncOperation FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options); - winrt::Microsoft::Management::Deployment::FindPackagesResult FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options); - }; -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageCatalog.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageCatalog : PackageCatalogT + { + PackageCatalog() = default; + + bool IsComposite(); + winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); + winrt::Windows::Foundation::IAsyncOperation FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options); + winrt::Microsoft::Management::Deployment::FindPackagesResult FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp index 98a723b34d..56b197726b 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp @@ -1,37 +1,37 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "PackageCatalogInfo.h" -#include "PackageCatalogInfo.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring PackageCatalogInfo::Id() - { - throw hresult_not_implemented(); - } - hstring PackageCatalogInfo::Name() - { - throw hresult_not_implemented(); - } - hstring PackageCatalogInfo::Type() - { - throw hresult_not_implemented(); - } - hstring PackageCatalogInfo::Argument() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::DateTime PackageCatalogInfo::LastUpdateTime() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalogOrigin PackageCatalogInfo::Origin() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel PackageCatalogInfo::TrustLevel() - { - throw hresult_not_implemented(); - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageCatalogInfo.h" +#include "PackageCatalogInfo.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring PackageCatalogInfo::Id() + { + throw hresult_not_implemented(); + } + hstring PackageCatalogInfo::Name() + { + throw hresult_not_implemented(); + } + hstring PackageCatalogInfo::Type() + { + throw hresult_not_implemented(); + } + hstring PackageCatalogInfo::Argument() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::DateTime PackageCatalogInfo::LastUpdateTime() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogOrigin PackageCatalogInfo::Origin() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel PackageCatalogInfo::TrustLevel() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp index 6c41a5dd91..3fe12edd6d 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp @@ -1,25 +1,25 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "PackageCatalogReference.h" -#include "PackageCatalogReference.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - bool PackageCatalogReference::IsComposite() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalogReference::Info() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::IAsyncOperation PackageCatalogReference::ConnectAsync() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::ConnectResult PackageCatalogReference::Connect() - { - throw hresult_not_implemented(); - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageCatalogReference.h" +#include "PackageCatalogReference.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + bool PackageCatalogReference::IsComposite() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalogReference::Info() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::IAsyncOperation PackageCatalogReference::ConnectAsync() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::ConnectResult PackageCatalogReference::Connect() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h index 5d02f35e2b..2c76518841 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h @@ -1,17 +1,17 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageCatalogReference.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageCatalogReference : PackageCatalogReferenceT - { - PackageCatalogReference() = default; - - bool IsComposite(); - winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); - winrt::Windows::Foundation::IAsyncOperation ConnectAsync(); - winrt::Microsoft::Management::Deployment::ConnectResult Connect(); - }; -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageCatalogReference.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageCatalogReference : PackageCatalogReferenceT + { + PackageCatalogReference() = default; + + bool IsComposite(); + winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); + winrt::Windows::Foundation::IAsyncOperation ConnectAsync(); + winrt::Microsoft::Management::Deployment::ConnectResult Connect(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp index caaef1f95c..d7b816db96 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp @@ -6,26 +6,26 @@ namespace winrt::Microsoft::Management::Deployment::implementation { winrt::Windows::Foundation::Collections::IVectorView PackageManager::GetPackageCatalogs() { - return m_packageManager.GetPackageCatalogs(); + throw hresult_not_implemented(); } - winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog) + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const&) { - return m_packageManager.GetPredefinedPackageCatalog(predefinedPackageCatalog); + throw hresult_not_implemented(); } - winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetLocalPackageCatalog(winrt::Microsoft::Management::Deployment::LocalPackageCatalog const& localPackageCatalog) + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetLocalPackageCatalog(winrt::Microsoft::Management::Deployment::LocalPackageCatalog const&) { - return m_packageManager.GetLocalPackageCatalog(localPackageCatalog); + throw hresult_not_implemented(); } - winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPackageCatalogByName(hstring const& catalogName) + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPackageCatalogByName(hstring const&) { - return m_packageManager.GetPackageCatalogByName(catalogName); + throw hresult_not_implemented(); } - winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options) + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const&) { - return m_packageManager.CreateCompositePackageCatalog(options); + throw hresult_not_implemented(); } - winrt::Windows::Foundation::IAsyncOperationWithProgress PackageManager::InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options) + winrt::Windows::Foundation::IAsyncOperationWithProgress PackageManager::InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions) { - return m_packageManager.InstallPackageAsync(package, options); + throw hresult_not_implemented(); } } diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.h b/src/Microsoft.Management.Deployment.Client/PackageManager.h index eac430757a..00ccdc2bb3 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.h +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.h @@ -7,10 +7,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation { struct PackageManager : PackageManagerT { - PackageManager() - { - return m_packageManager = winrt::create_instance(CLSID_PackageManager2, CLSCTX_ALL); - } + PackageManager() = default; winrt::Windows::Foundation::Collections::IVectorView GetPackageCatalogs(); winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog); @@ -18,13 +15,15 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPackageCatalogByName(hstring const& catalogName); winrt::Microsoft::Management::Deployment::PackageCatalogReference CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options); winrt::Windows::Foundation::IAsyncOperationWithProgress InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options); - private: - winrt::Microsoft::Management::Deployment::PackageManager m_packageManager{ nullptr }; }; } namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct PackageManager : PackageManagerT { + auto ActivateInstance() const + { + return winrt::create_instance(CLSID_PackageManager2, CLSCTX_ALL); + } }; } diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp index 76afca043e..028270abd2 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp @@ -8,26 +8,26 @@ namespace winrt::Microsoft::Management::Deployment::implementation { winrt::Microsoft::Management::Deployment::PackageFieldMatchOption PackageMatchFilter::Option() { - return m_packageMatchFilter.Option(); + throw hresult_not_implemented();; } - void PackageMatchFilter::Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value) + void PackageMatchFilter::Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const&) { - m_packageMatchFilter.Option(value); + throw hresult_not_implemented(); } winrt::Microsoft::Management::Deployment::PackageMatchField PackageMatchFilter::Field() { - return m_packageMatchFilter.Field(); + throw hresult_not_implemented(); } - void PackageMatchFilter::Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value) + void PackageMatchFilter::Field(winrt::Microsoft::Management::Deployment::PackageMatchField const&) { - m_packageMatchFilter.Field(value); + throw hresult_not_implemented(); } hstring PackageMatchFilter::Value() { - return m_packageMatchFilter.Value(); + throw hresult_not_implemented(); } - void PackageMatchFilter::Value(hstring const& value) + void PackageMatchFilter::Value(hstring const&) { - m_packageMatchFilter.Value(value); + throw hresult_not_implemented(); } } diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h index 003bb363a5..4a6fdb5a69 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h @@ -9,10 +9,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation { struct PackageMatchFilter : PackageMatchFilterT { - PackageMatchFilter() - { - m_packageMatchFilter = winrt::create_instance(CLSID_PackageMatchFilter2, CLSCTX_ALL); - } + PackageMatchFilter() = default; winrt::Microsoft::Management::Deployment::PackageFieldMatchOption Option(); void Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value); @@ -20,13 +17,15 @@ namespace winrt::Microsoft::Management::Deployment::implementation void Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value); hstring Value(); void Value(hstring const& value); - private: - winrt::Microsoft::Management::Deployment::PackageMatchFilter m_packageMatchFilter{ nullptr }; }; } namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct PackageMatchFilter : PackageMatchFilterT { + auto ActivateInstance() const + { + return winrt::create_instance(CLSID_PackageMatchFilter2, CLSCTX_ALL); + } }; } diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp b/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp index d9bad834f9..e5e3f8708d 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp @@ -1,21 +1,21 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "PackageVersionId.h" -#include "PackageVersionId.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring PackageVersionId::PackageCatalogId() - { - throw hresult_not_implemented(); - } - hstring PackageVersionId::Version() - { - throw hresult_not_implemented(); - } - hstring PackageVersionId::Channel() - { - throw hresult_not_implemented(); - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageVersionId.h" +#include "PackageVersionId.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring PackageVersionId::PackageCatalogId() + { + throw hresult_not_implemented(); + } + hstring PackageVersionId::Version() + { + throw hresult_not_implemented(); + } + hstring PackageVersionId::Channel() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionId.h b/src/Microsoft.Management.Deployment.Client/PackageVersionId.h index 739f7da547..57518126a0 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionId.h +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionId.h @@ -1,16 +1,16 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageVersionId.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageVersionId : PackageVersionIdT - { - PackageVersionId() = default; - - hstring PackageCatalogId(); - hstring Version(); - hstring Channel(); - }; -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageVersionId.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageVersionId : PackageVersionIdT + { + PackageVersionId() = default; + + hstring PackageCatalogId(); + hstring Version(); + hstring Channel(); + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp index f7cf643de5..401e62722b 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp @@ -1,42 +1,41 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "PackageVersionInfo.h" -#include "PackageVersionInfo.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring PackageVersionInfo::GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField) - { - UNREFERENCED_PARAMETER(metadataField); - throw hresult_not_implemented(); - } - hstring PackageVersionInfo::Id() - { - throw hresult_not_implemented(); - } - hstring PackageVersionInfo::DisplayName() - { - throw hresult_not_implemented(); - } - hstring PackageVersionInfo::Version() - { - throw hresult_not_implemented(); - } - hstring PackageVersionInfo::Channel() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::Collections::IVectorView PackageVersionInfo::PackageFamilyNames() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::Collections::IVectorView PackageVersionInfo::ProductCodes() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalog PackageVersionInfo::PackageCatalog() - { - throw hresult_not_implemented(); - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "PackageVersionInfo.h" +#include "PackageVersionInfo.g.cpp" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + hstring PackageVersionInfo::GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const&) + { + throw hresult_not_implemented(); + } + hstring PackageVersionInfo::Id() + { + throw hresult_not_implemented(); + } + hstring PackageVersionInfo::DisplayName() + { + throw hresult_not_implemented(); + } + hstring PackageVersionInfo::Version() + { + throw hresult_not_implemented(); + } + hstring PackageVersionInfo::Channel() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::Collections::IVectorView PackageVersionInfo::PackageFamilyNames() + { + throw hresult_not_implemented(); + } + winrt::Windows::Foundation::Collections::IVectorView PackageVersionInfo::ProductCodes() + { + throw hresult_not_implemented(); + } + winrt::Microsoft::Management::Deployment::PackageCatalog PackageVersionInfo::PackageCatalog() + { + throw hresult_not_implemented(); + } +} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h index 7eef08e22e..f17ac1ffb6 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h @@ -1,21 +1,21 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageVersionInfo.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageVersionInfo : PackageVersionInfoT - { - PackageVersionInfo() = default; - - hstring GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField); - hstring Id(); - hstring DisplayName(); - hstring Version(); - hstring Channel(); - winrt::Windows::Foundation::Collections::IVectorView PackageFamilyNames(); - winrt::Windows::Foundation::Collections::IVectorView ProductCodes(); - winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); - }; -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageVersionInfo.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct PackageVersionInfo : PackageVersionInfoT + { + PackageVersionInfo() = default; + + hstring GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField); + hstring Id(); + hstring DisplayName(); + hstring Version(); + hstring Channel(); + winrt::Windows::Foundation::Collections::IVectorView PackageFamilyNames(); + winrt::Windows::Foundation::Collections::IVectorView ProductCodes(); + winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); + }; +} From b1af5364d9cf316229f219fb9c34d387c02f03bf Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Sat, 14 Aug 2021 19:17:51 -0700 Subject: [PATCH 04/53] Fix unreferenced parameters. --- .../CreateCompositePackageCatalogOptions.cpp | 2 +- .../FindPackagesOptions.cpp | 2 +- .../InstallOptions.cpp | 2 +- .../PackageManager.idl | 1 + src/PackagedTests/ComInterfaceUnitTest.cs | 40 +------------------ 5 files changed, 6 insertions(+), 41 deletions(-) diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp index d732a70564..c8f60de369 100644 --- a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp @@ -14,7 +14,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation { throw hresult_not_implemented(); } - void CreateCompositePackageCatalogOptions::CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value) + void CreateCompositePackageCatalogOptions::CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const&) { throw hresult_not_implemented(); } diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp index 37180ed522..749e98268b 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp @@ -18,7 +18,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation { throw hresult_not_implemented(); } - void FindPackagesOptions::ResultLimit(uint32_t value) + void FindPackagesOptions::ResultLimit(uint32_t) { throw hresult_not_implemented(); } diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp index 33a034d376..7ee258963c 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp @@ -18,7 +18,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation { throw hresult_not_implemented(); } - void InstallOptions::PreferredInstallLocation(hstring const& value) + void InstallOptions::PreferredInstallLocation(hstring const&) { throw hresult_not_implemented(); } diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.idl b/src/Microsoft.Management.Deployment.Client/PackageManager.idl index d81eb01279..2b85fce4b6 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.idl +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.idl @@ -401,6 +401,7 @@ namespace Microsoft.Management.Deployment enum PredefinedPackageCatalog { OpenWindowsCatalog, + MicrosoftStore, }; /// Local Catalogs with PackageCatalogOrigin Predefined diff --git a/src/PackagedTests/ComInterfaceUnitTest.cs b/src/PackagedTests/ComInterfaceUnitTest.cs index bc39a10876..31807e88e9 100644 --- a/src/PackagedTests/ComInterfaceUnitTest.cs +++ b/src/PackagedTests/ComInterfaceUnitTest.cs @@ -26,15 +26,6 @@ public void OpenPredefinedCatalog() break; } } - // TODO: Investigate why casting fails here. - /*foreach (var catalog in catalogs) - { - if (catalog.Info.Name.Equals("winget"))e - { - foundDefaultCatalog = true; - break; - } - }*/ Assert.IsTrue(foundDefaultCatalog); } @@ -42,35 +33,8 @@ public void OpenPredefinedCatalog() public void OpenPredefinedStoreCatalog() { PackageManager packageManager = new PackageManager(); - PackageCatalogReference catalogRef = packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog.OpenWindowsCatalog); - Assert.IsTrue(catalogRef.Info.Name.Equals("winget")); - IReadOnlyList catalogs = packageManager.GetPackageCatalogs(); - Assert.IsTrue(catalogs.Count > 0); - bool foundDefaultCatalog = false; - for (int i = 0; i < catalogs.Count; i++) - { - if (catalogs[i].Info.Name.Equals("winget")) - { - foundDefaultCatalog = true; - break; - } - } - // TODO: Investigate why casting fails here. - /*foreach (var catalog in catalogs) - { - if (catalog.Info.Name.Equals("winget"))e - { - foundDefaultCatalog = true; - break; - } - }*/ - Assert.IsTrue(foundDefaultCatalog); - } - - public void PopulateInstallOptions() - { - InstallOptions installOptions = new InstallOptions(); - //Assert.IsTrue(foundDefaultCatalog); + PackageCatalogReference catalogRef = packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog.MicrosoftStore); + Assert.IsTrue(catalogRef.Info.Name.Equals("storepreview")); } } } From e9afd2322333a954cabc3818bb125298c714a332 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Mon, 16 Aug 2021 10:59:08 -0700 Subject: [PATCH 05/53] Guid name updates. --- .../CreateCompositePackageCatalogOptions.h | 4 ++-- .../FindPackagesOptions.h | 4 ++-- src/Microsoft.Management.Deployment.Client/InstallOptions.h | 4 ++-- src/Microsoft.Management.Deployment.Client/PackageManager.h | 4 ++-- .../PackageMatchFilter.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h index 0a4befcdbb..dec3e02d46 100644 --- a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h +++ b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h @@ -3,7 +3,7 @@ #pragma once #include "CreateCompositePackageCatalogOptions.g.h" -const CLSID CLSID_CreateCompositePackageCatalogOptions2 = { 0x6444B10D, 0xFE84, 0x430F, { 0x93, 0x2B, 0x3D, 0x4F, 0xE5, 0x19, 0x5B, 0xDF } }; //6444B10D-FE84-430F-932B-3D4FE5195BDF +const CLSID CLSID_CreateCompositePackageCatalogOptions = { 0x6444B10D, 0xFE84, 0x430F, { 0x93, 0x2B, 0x3D, 0x4F, 0xE5, 0x19, 0x5B, 0xDF } }; //6444B10D-FE84-430F-932B-3D4FE5195BDF namespace winrt::Microsoft::Management::Deployment::implementation { @@ -22,7 +22,7 @@ namespace winrt::Microsoft::Management::Deployment::factory_implementation { auto ActivateInstance() const { - return winrt::create_instance(CLSID_CreateCompositePackageCatalogOptions2, CLSCTX_ALL); + return winrt::create_instance(CLSID_CreateCompositePackageCatalogOptions, CLSCTX_ALL); } }; } diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h index 4401c4d7fe..ea8b5b612e 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h @@ -3,7 +3,7 @@ #pragma once #include "FindPackagesOptions.g.h" -const CLSID CLSID_FindPackagesOptions2 = { 0x2CAD6C15, 0xDF8E, 0x49DD, { 0xA7, 0x48, 0x96, 0xAD, 0xE0, 0xFE, 0x31, 0xB7 } }; //2CAD6C15-DF8E-49DD-A748-96ADE0FE31B7 +const CLSID CLSID_FindPackagesOptions = { 0x2CAD6C15, 0xDF8E, 0x49DD, { 0xA7, 0x48, 0x96, 0xAD, 0xE0, 0xFE, 0x31, 0xB7 } }; //2CAD6C15-DF8E-49DD-A748-96ADE0FE31B7 namespace winrt::Microsoft::Management::Deployment::implementation { @@ -23,7 +23,7 @@ namespace winrt::Microsoft::Management::Deployment::factory_implementation { auto ActivateInstance() const { - return winrt::create_instance(CLSID_FindPackagesOptions2, CLSCTX_ALL); + return winrt::create_instance(CLSID_FindPackagesOptions, CLSCTX_ALL); } }; } diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.h b/src/Microsoft.Management.Deployment.Client/InstallOptions.h index 2116f6a6f8..148beaae16 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.h +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.h @@ -3,7 +3,7 @@ #pragma once #include "InstallOptions.g.h" -const CLSID CLSID_InstallOptions2 = { 0x05F7019A, 0x8FAC, 0x4422, 0xBC, 0xD5, 0x4C, 0xB3, 0x4F, 0xFB, 0x44, 0xA8 }; //05F7019A-8FAC-4422-BCD5-4CB34FFB44A8 +const CLSID CLSID_InstallOptions = { 0x05F7019A, 0x8FAC, 0x4422, 0xBC, 0xD5, 0x4C, 0xB3, 0x4F, 0xFB, 0x44, 0xA8 }; //05F7019A-8FAC-4422-BCD5-4CB34FFB44A8 namespace winrt::Microsoft::Management::Deployment::implementation { @@ -37,7 +37,7 @@ namespace winrt::Microsoft::Management::Deployment::factory_implementation { auto ActivateInstance() const { - return winrt::create_instance(CLSID_InstallOptions2, CLSCTX_ALL); + return winrt::create_instance(CLSID_InstallOptions, CLSCTX_ALL); } }; } diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.h b/src/Microsoft.Management.Deployment.Client/PackageManager.h index 00ccdc2bb3..c81ea112da 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.h +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.h @@ -1,7 +1,7 @@ #pragma once #include "PackageManager.g.h" -const CLSID CLSID_PackageManager2 = { 0xE65C7D5A, 0x95AF, 0x4A98, { 0xBE, 0x5F, 0xA7, 0x93, 0x02, 0x9C, 0xEB, 0x56 } }; //E65C7D5A-95AF-4A98-BE5F-A793029CEB56 +const CLSID CLSID_PackageManager = { 0xE65C7D5A, 0x95AF, 0x4A98, { 0xBE, 0x5F, 0xA7, 0x93, 0x02, 0x9C, 0xEB, 0x56 } }; //E65C7D5A-95AF-4A98-BE5F-A793029CEB56 namespace winrt::Microsoft::Management::Deployment::implementation { @@ -23,7 +23,7 @@ namespace winrt::Microsoft::Management::Deployment::factory_implementation { auto ActivateInstance() const { - return winrt::create_instance(CLSID_PackageManager2, CLSCTX_ALL); + return winrt::create_instance(CLSID_PackageManager, CLSCTX_ALL); } }; } diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h index 4a6fdb5a69..7a83afa9c7 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h @@ -3,7 +3,7 @@ #pragma once #include "PackageMatchFilter.g.h" -const CLSID CLSID_PackageMatchFilter2 = { 0xADBF3B4A, 0xDB8A, 0x496C, { 0xA5, 0x79, 0x62, 0xB5, 0x8F, 0x5F, 0xB1, 0x30 } }; //ADBF3B4A-DB8A-496C-A579-62B58F5FB13F +const CLSID CLSID_PackageMatchFilter = { 0xADBF3B4A, 0xDB8A, 0x496C, { 0xA5, 0x79, 0x62, 0xB5, 0x8F, 0x5F, 0xB1, 0x30 } }; //ADBF3B4A-DB8A-496C-A579-62B58F5FB13F namespace winrt::Microsoft::Management::Deployment::implementation { @@ -25,7 +25,7 @@ namespace winrt::Microsoft::Management::Deployment::factory_implementation { auto ActivateInstance() const { - return winrt::create_instance(CLSID_PackageMatchFilter2, CLSCTX_ALL); + return winrt::create_instance(CLSID_PackageMatchFilter, CLSCTX_ALL); } }; } From 8c312265180f6375f8c24d2f6a45b4765f735fd4 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Mon, 16 Aug 2021 12:31:16 -0700 Subject: [PATCH 06/53] Undo unneccessary changes. --- .../AppInstallerCLIE2ETests.csproj | 13 +------------ .../PackageManager.idl | 4 ---- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj b/src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj index 20d75ab75b..328c16546a 100644 --- a/src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj +++ b/src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj @@ -1,7 +1,7 @@  - net5.0-windows10.0.19041.0 + net5.0 $(SolutionDir)$(Platform)\$(Configuration)\AppInstallerCLIE2ETests\ false x64;x86 @@ -10,10 +10,7 @@ - - - @@ -40,16 +37,8 @@ - - - PreserveNewest - - - - - diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index bc0263fa79..6f34e9aa99 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -533,9 +533,5 @@ namespace Microsoft.Management.Deployment interface Windows.Foundation.Collections.IVectorView; interface Windows.Foundation.Collections.IVector; interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; } } From b3d3a07a47b1831ed73a0eb88f627297dc3a68b1 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:29:58 -0700 Subject: [PATCH 07/53] Remove projection. --- src/AppInstallerCLI.sln | 33 ------------------- ...ft.Management.Deployment.Projection.csproj | 24 -------------- 2 files changed, 57 deletions(-) delete mode 100644 src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index cc39a2781e..cfff2a2bc8 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -6,7 +6,6 @@ Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "AppInstallerCLIPackage", "A ProjectSection(ProjectDependencies) = postProject {4BC1F40B-36C2-4BBB-8306-76E490B13BBD} = {4BC1F40B-36C2-4BBB-8306-76E490B13BBD} {1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69} - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340} = {EAF57FF2-A05A-4E73-80A7-CF686CE2D340} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppInstallerCLI", "AppInstallerCLI\AppInstallerCLI.vcxproj", "{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}" @@ -127,8 +126,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServe EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Management.Deployment.Projection", "Microsoft.Management.Deployment.Projection\Microsoft.Management.Deployment.Projection.csproj", "{EAF57FF2-A05A-4E73-80A7-CF686CE2D340}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTests\PackagedTests.csproj", "{8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}" EndProject Global @@ -657,36 +654,6 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|Any CPU.ActiveCfg = Debug|x86 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|Any CPU.Build.0 = Debug|x86 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|ARM.ActiveCfg = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|ARM.Build.0 = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|ARM64.Build.0 = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|x64.ActiveCfg = Debug|x64 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|x64.Build.0 = Debug|x64 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|x86.ActiveCfg = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Debug|x86.Build.0 = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|ARM.Build.0 = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|ARM64.Build.0 = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|x64.ActiveCfg = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|x64.Build.0 = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|x86.ActiveCfg = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Fuzzing|x86.Build.0 = Debug|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|Any CPU.ActiveCfg = Release|x64 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|Any CPU.Build.0 = Release|x64 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|ARM.ActiveCfg = Release|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|ARM.Build.0 = Release|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|ARM64.ActiveCfg = Release|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|ARM64.Build.0 = Release|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x64.ActiveCfg = Release|x64 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x64.Build.0 = Release|x64 - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x86.ActiveCfg = Release|Any CPU - {EAF57FF2-A05A-4E73-80A7-CF686CE2D340}.Release|x86.Build.0 = Release|Any CPU {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|Any CPU.ActiveCfg = Debug|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.ActiveCfg = Debug|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Build.0 = Debug|ARM diff --git a/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj b/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj deleted file mode 100644 index d1d09b46f7..0000000000 --- a/src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - net5.0-windows10.0.19041.0 - 10.0.19041.0 - x64;x86 - - - - - - - - - - - - Microsoft.Management.Deployment - $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\Microsoft.Management.Deployment.Projection\ - $(OutDir) - - - TRACE;fl - - From dc2d71e4cc062a1c396778d879f8cc10834de615 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:40:36 -0700 Subject: [PATCH 08/53] Spelling changes. --- .github/actions/spelling/allow.txt | 7 +++++++ .github/actions/spelling/expect.txt | 5 +++++ src/PackagedTests/Package.appxmanifest | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index f7838c493d..e1083854ee 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -4,6 +4,7 @@ addmanifest addstore admins alloc +altform anonymize api appdata @@ -123,6 +124,7 @@ ETW EVENTTAG exe executables +executionengine exeenus exeinteractive exelog @@ -306,6 +308,7 @@ PBYTE pch PCWSTR pdb +pdbonly PEVENT pfp PGP @@ -444,6 +447,7 @@ TARG TARGETDIR targetentrypoint targetnametoken +targetsize tdbuild tdd tellg @@ -459,6 +463,7 @@ there're Timeline todo tolower +Toolchain toupper towlower TRACELOGGING @@ -529,6 +534,7 @@ wcsicmp webpage wekyb wil +wildcards WINAPI WINEVENT winget @@ -553,6 +559,7 @@ wstring wstringstream www xamarin +xaml XElement xlang xml diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index ac1d97a1c6..02c1b73687 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -1,4 +1,5 @@ abcd +activatable adml admx affle @@ -72,6 +73,7 @@ contractversion count'th countryregion createmanifestmetadata +CSharp cstdint ctc Ctx @@ -147,6 +149,7 @@ inor installshield IPackage IPersist +IRead IService ISettings ishelp @@ -213,6 +216,7 @@ mylog mysilent mysilentwithprogress mytool +NETFX netlify Newtonsoft NOEXPAND @@ -333,6 +337,7 @@ VERSI VERSIE vns vscode +vstest vy wcslen webpages diff --git a/src/PackagedTests/Package.appxmanifest b/src/PackagedTests/Package.appxmanifest index d8c34a8b5f..c9be52023f 100644 --- a/src/PackagedTests/Package.appxmanifest +++ b/src/PackagedTests/Package.appxmanifest @@ -6,14 +6,14 @@ IgnorableNamespaces="uap mp"> PackagedUnitTests - sreading + Microsoft Corporation Assets\StoreLogo.png From eb31f6e17d989454f2c7c5d05f4059e9a29414cf Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 20 Aug 2021 16:32:33 -0700 Subject: [PATCH 09/53] Simplify packaged test csproj file. --- src/PackagedTests/PackagedTests.csproj | 91 ++++---------------------- 1 file changed, 13 insertions(+), 78 deletions(-) diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 9485af49e3..6f51bb2b3e 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -24,99 +24,34 @@ Always x64 0 - - - true - bin\x86\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + bin\$(Platform)\$(Configuration)\ ;2008 - full - x86 - false prompt - true - - - bin\x86\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - x86 false - prompt true true + TRACE;NETFX_CORE;WINDOWS_UWP - - true - bin\ARM\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - ARM - false - prompt - true + + x86 - - bin\ARM\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - ARM - false - prompt - true - true + + x64 - - true - bin\ARM64\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - ARM64 - false - prompt - true - true + + ARM - - bin\ARM64\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly + ARM64 - false - prompt - true - true - + + DEBUG true - bin\x64\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 full - x64 - false - prompt - true - - bin\x64\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 + pdbonly - x64 - false - prompt - true - true + true PackageReference From 5d041fd2a6358a619cf8b71149b652b0f33212a4 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 20 Aug 2021 18:35:52 -0700 Subject: [PATCH 10/53] Update guids\packagereference versions. --- .../CreateCompositePackageCatalogOptions.h | 2 +- .../FindPackagesOptions.h | 2 +- .../InstallOptions.h | 2 +- .../PackageManager.h | 2 +- .../PackageMatchFilter.h | 2 +- src/PackagedTests/PackagedTests.csproj | 7 +++++-- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h index dec3e02d46..1bda0b1f62 100644 --- a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h +++ b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h @@ -3,7 +3,7 @@ #pragma once #include "CreateCompositePackageCatalogOptions.g.h" -const CLSID CLSID_CreateCompositePackageCatalogOptions = { 0x6444B10D, 0xFE84, 0x430F, { 0x93, 0x2B, 0x3D, 0x4F, 0xE5, 0x19, 0x5B, 0xDF } }; //6444B10D-FE84-430F-932B-3D4FE5195BDF +const CLSID CLSID_CreateCompositePackageCatalogOptions = { 0xEE160901, 0xB317, 0x4EA7, { 0x9C, 0xC6, 0x53, 0x55, 0xC6, 0xD7, 0xD8, 0xA7 } }; //EE160901-B317-4EA7-9CC6-5355C6D7D8A7 namespace winrt::Microsoft::Management::Deployment::implementation { diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h index ea8b5b612e..854b529b41 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h @@ -3,7 +3,7 @@ #pragma once #include "FindPackagesOptions.g.h" -const CLSID CLSID_FindPackagesOptions = { 0x2CAD6C15, 0xDF8E, 0x49DD, { 0xA7, 0x48, 0x96, 0xAD, 0xE0, 0xFE, 0x31, 0xB7 } }; //2CAD6C15-DF8E-49DD-A748-96ADE0FE31B7 +const CLSID CLSID_FindPackagesOptions = { 0x1BD8FF3A, 0xEC50, 0x4F69, { 0xAE, 0xEE, 0xDF, 0x4C, 0x9D, 0x3B, 0xAA, 0x96 } }; //1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96 namespace winrt::Microsoft::Management::Deployment::implementation { diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.h b/src/Microsoft.Management.Deployment.Client/InstallOptions.h index 148beaae16..db97f1b6b9 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.h +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.h @@ -3,7 +3,7 @@ #pragma once #include "InstallOptions.g.h" -const CLSID CLSID_InstallOptions = { 0x05F7019A, 0x8FAC, 0x4422, 0xBC, 0xD5, 0x4C, 0xB3, 0x4F, 0xFB, 0x44, 0xA8 }; //05F7019A-8FAC-4422-BCD5-4CB34FFB44A8 +const CLSID CLSID_InstallOptions = { 0x44FE0580, 0x62F7, 0x44D4, 0x9E, 0x91, 0xAA, 0x96, 0x14, 0xAB, 0x3E, 0x86 }; //44FE0580-62F7-44D4-9E91-AA9614AB3E86 namespace winrt::Microsoft::Management::Deployment::implementation { diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.h b/src/Microsoft.Management.Deployment.Client/PackageManager.h index c81ea112da..51c9c69211 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.h +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.h @@ -1,7 +1,7 @@ #pragma once #include "PackageManager.g.h" -const CLSID CLSID_PackageManager = { 0xE65C7D5A, 0x95AF, 0x4A98, { 0xBE, 0x5F, 0xA7, 0x93, 0x02, 0x9C, 0xEB, 0x56 } }; //E65C7D5A-95AF-4A98-BE5F-A793029CEB56 +const CLSID CLSID_PackageManager = { 0x74CB3139, 0xB7C5, 0x4B9E, { 0x93, 0x88, 0xE6, 0x61, 0x6D, 0xEA, 0x28, 0x8C } }; //74CB3139-B7C5-4B9E-9388-E6616DEA288C namespace winrt::Microsoft::Management::Deployment::implementation { diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h index 7a83afa9c7..483afc1766 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h @@ -3,7 +3,7 @@ #pragma once #include "PackageMatchFilter.g.h" -const CLSID CLSID_PackageMatchFilter = { 0xADBF3B4A, 0xDB8A, 0x496C, { 0xA5, 0x79, 0x62, 0xB5, 0x8F, 0x5F, 0xB1, 0x30 } }; //ADBF3B4A-DB8A-496C-A579-62B58F5FB13F +const CLSID CLSID_PackageMatchFilter = { 0x3F85B9F4, 0x487A, 0x4C48, { 0x90, 0x35, 0x29, 0x03, 0xF8, 0xA6, 0xD9, 0xE8 } }; //3F85B9F4-487A-4C48-9035-2903F8A6D9E8 namespace winrt::Microsoft::Management::Deployment::implementation { diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 6f51bb2b3e..41d91b4dc6 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -91,11 +91,14 @@ 6.2.12 + + 16.11.0 + - 2.2.3 + 2.2.5 - 2.2.3 + 2.2.5 From 732e33082b32d168106a8e17c48075ed6ddafd3e Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 25 Aug 2021 00:22:59 -0700 Subject: [PATCH 11/53] Remove anycpu --- src/AppInstallerCLI.sln | 94 ------------------- .../readme.txt | 23 ----- 2 files changed, 117 deletions(-) delete mode 100644 src/Microsoft.Management.Deployment.Client/readme.txt diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index cfff2a2bc8..36f9683fcd 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -150,26 +150,20 @@ Global ManifestSchema\ManifestSchema.vcxitems*{fb313532-38b0-4676-9303-ab200aa13576}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU Debug|ARM = Debug|ARM Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 - Fuzzing|Any CPU = Fuzzing|Any CPU Fuzzing|ARM = Fuzzing|ARM Fuzzing|ARM64 = Fuzzing|ARM64 Fuzzing|x64 = Fuzzing|x64 Fuzzing|x86 = Fuzzing|x86 - Release|Any CPU = Release|Any CPU Release|ARM = Release|ARM Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.ActiveCfg = Debug|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.Build.0 = Debug|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.Deploy.0 = Debug|ARM @@ -182,16 +176,10 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.ActiveCfg = Debug|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Build.0 = Debug|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Deploy.0 = Debug|x86 - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.Build.0 = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x64.ActiveCfg = Release|x64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x86.ActiveCfg = Release|x86 - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.Build.0 = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.Deploy.0 = Release|Any CPU {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.Build.0 = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.Deploy.0 = Release|ARM @@ -204,7 +192,6 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.ActiveCfg = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Build.0 = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Deploy.0 = Release|x86 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.ActiveCfg = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.Build.0 = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -213,13 +200,10 @@ Global {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x64.Build.0 = Debug|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.ActiveCfg = Debug|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.Build.0 = Debug|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|Any CPU.Build.0 = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x64.ActiveCfg = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x86.ActiveCfg = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|Any CPU.ActiveCfg = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM.Build.0 = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -228,7 +212,6 @@ Global {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x64.Build.0 = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.ActiveCfg = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.Build.0 = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|Any CPU.ActiveCfg = Debug|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.ActiveCfg = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.Build.0 = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -237,13 +220,10 @@ Global {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x64.Build.0 = Debug|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.ActiveCfg = Debug|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.Build.0 = Debug|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|Any CPU.Build.0 = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM.ActiveCfg = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x64.ActiveCfg = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x86.ActiveCfg = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|Any CPU.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM.ActiveCfg = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM.Build.0 = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -252,7 +232,6 @@ Global {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x64.Build.0 = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.Build.0 = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.ActiveCfg = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.Build.0 = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -261,13 +240,10 @@ Global {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x64.Build.0 = Debug|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.ActiveCfg = Debug|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.Build.0 = Debug|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|Any CPU.Build.0 = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM.ActiveCfg = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x64.ActiveCfg = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x86.ActiveCfg = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|Any CPU.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM.ActiveCfg = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM.Build.0 = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -276,27 +252,22 @@ Global {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x64.Build.0 = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.Build.0 = Release|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|Any CPU.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM64.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.ActiveCfg = Debug|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.Build.0 = Debug|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.Build.0 = Debug|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|Any CPU.ActiveCfg = Release|x64 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|Any CPU.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM64.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x86.ActiveCfg = Release|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|Any CPU.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM64.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.Build.0 = Release|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|Any CPU.ActiveCfg = Debug|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.ActiveCfg = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.Build.0 = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -305,13 +276,11 @@ Global {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x64.Build.0 = Debug|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x86.ActiveCfg = Debug|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x86.Build.0 = Debug|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|ARM.ActiveCfg = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x64.Build.0 = Fuzzing|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x86.ActiveCfg = Release|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|Any CPU.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM.ActiveCfg = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM.Build.0 = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -320,7 +289,6 @@ Global {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x64.Build.0 = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.Build.0 = Release|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|Any CPU.ActiveCfg = Debug|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.ActiveCfg = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.Build.0 = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -329,13 +297,11 @@ Global {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x64.Build.0 = Debug|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.ActiveCfg = Debug|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.Build.0 = Debug|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM.ActiveCfg = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.Build.0 = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x86.ActiveCfg = Release|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|Any CPU.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM.ActiveCfg = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM.Build.0 = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -344,7 +310,6 @@ Global {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x64.Build.0 = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.Build.0 = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Debug|Any CPU.ActiveCfg = Debug|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.ActiveCfg = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.Build.0 = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -353,13 +318,10 @@ Global {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x64.Build.0 = Debug|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.ActiveCfg = Debug|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.Build.0 = Debug|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|Any CPU.Build.0 = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x64.ActiveCfg = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x86.ActiveCfg = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Release|Any CPU.ActiveCfg = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM.Build.0 = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -368,7 +330,6 @@ Global {FB313532-38B0-4676-9303-AB200AA13576}.Release|x64.Build.0 = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.ActiveCfg = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.Build.0 = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|Any CPU.ActiveCfg = Debug|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.ActiveCfg = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.Build.0 = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -377,13 +338,10 @@ Global {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x64.Build.0 = Debug|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.ActiveCfg = Debug|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.Build.0 = Debug|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|Any CPU.Build.0 = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x64.ActiveCfg = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x86.ActiveCfg = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|Any CPU.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM.Build.0 = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -392,29 +350,22 @@ Global {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x64.Build.0 = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.Build.0 = Release|Win32 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|Any CPU.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM64.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.ActiveCfg = Debug|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.Build.0 = Debug|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.Build.0 = Debug|x86 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|Any CPU.ActiveCfg = Release|x64 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|Any CPU.Build.0 = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x86.ActiveCfg = Release|x86 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|Any CPU.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM64.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.Build.0 = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.Build.0 = Release|x86 - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.ActiveCfg = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Build.0 = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Deploy.0 = Debug|ARM @@ -427,16 +378,10 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.ActiveCfg = Debug|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Build.0 = Debug|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Deploy.0 = Debug|x86 - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.Build.0 = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x64.ActiveCfg = Release|x64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x86.ActiveCfg = Release|x86 - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.Build.0 = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.Deploy.0 = Release|Any CPU {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.Build.0 = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.Deploy.0 = Release|ARM @@ -449,42 +394,34 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.ActiveCfg = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Build.0 = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Deploy.0 = Release|x86 - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|Any CPU.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x86.ActiveCfg = Debug - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|Any CPU.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x86.ActiveCfg = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|Any CPU.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x86.ActiveCfg = Release - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|Any CPU.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM64.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.ActiveCfg = Debug|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.Build.0 = Debug|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.Build.0 = Debug|x86 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|Any CPU.ActiveCfg = Release|x64 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|Any CPU.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x86.ActiveCfg = Release|x86 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|Any CPU.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM64.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.Build.0 = Release|x86 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|Any CPU.ActiveCfg = Debug|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.ActiveCfg = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.Build.0 = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -493,13 +430,11 @@ Global {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x64.Build.0 = Debug|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x86.ActiveCfg = Debug|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x86.Build.0 = Debug|Win32 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|ARM.ActiveCfg = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x64.Build.0 = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x86.ActiveCfg = Release|Win32 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|Any CPU.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM.ActiveCfg = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM.Build.0 = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -508,45 +443,36 @@ Global {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x64.Build.0 = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.Build.0 = Release|Win32 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|Any CPU.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.Build.0 = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x86.ActiveCfg = Fuzzing|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.Build.0 = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x86.ActiveCfg = Fuzzing|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|Any CPU.ActiveCfg = Debug|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|Any CPU.Build.0 = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x86.ActiveCfg = Fuzzing|x64 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|Any CPU.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM64.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.ActiveCfg = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.Build.0 = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.Build.0 = Debug|x86 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|Any CPU.ActiveCfg = Release|x64 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|Any CPU.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x86.ActiveCfg = Release|x86 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|Any CPU.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM64.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.Build.0 = Release|x86 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|Any CPU.ActiveCfg = Debug|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.ActiveCfg = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.Build.0 = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -555,13 +481,10 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x64.Build.0 = Debug|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x86.ActiveCfg = Debug|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x86.Build.0 = Debug|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|Any CPU.Build.0 = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|ARM.ActiveCfg = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|x64.ActiveCfg = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|x86.ActiveCfg = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|Any CPU.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM.ActiveCfg = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM.Build.0 = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -570,7 +493,6 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x64.Build.0 = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.Build.0 = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|Any CPU.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.ActiveCfg = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.Build.0 = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -579,8 +501,6 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x64.Build.0 = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.Build.0 = Debug|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|Any CPU.Build.0 = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM.ActiveCfg = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM.Build.0 = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 @@ -589,7 +509,6 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x64.Build.0 = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.Build.0 = Debug|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|Any CPU.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.ActiveCfg = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.Build.0 = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -598,7 +517,6 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.Build.0 = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.Build.0 = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|Any CPU.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.ActiveCfg = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.Build.0 = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -607,8 +525,6 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.Build.0 = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.Build.0 = Debug|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|Any CPU.Build.0 = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM.ActiveCfg = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM.Build.0 = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 @@ -617,7 +533,6 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x64.Build.0 = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.Build.0 = Debug|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|Any CPU.ActiveCfg = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.ActiveCfg = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.Build.0 = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -626,7 +541,6 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.Build.0 = Release|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.ActiveCfg = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.Build.0 = Release|Win32 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|Any CPU.ActiveCfg = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.ActiveCfg = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.Build.0 = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -635,8 +549,6 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x64.Build.0 = Debug|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.ActiveCfg = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.Build.0 = Debug|Win32 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|Any CPU.ActiveCfg = Debug|Win32 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|Any CPU.Build.0 = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM.ActiveCfg = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM.Build.0 = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 @@ -645,7 +557,6 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x64.Build.0 = Debug|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x86.ActiveCfg = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x86.Build.0 = Debug|Win32 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|Any CPU.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.ActiveCfg = Release|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.Build.0 = Release|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -654,7 +565,6 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|Any CPU.ActiveCfg = Debug|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.ActiveCfg = Debug|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Build.0 = Debug|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Deploy.0 = Debug|ARM @@ -667,9 +577,6 @@ Global {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.ActiveCfg = Debug|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Build.0 = Debug|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Deploy.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.ActiveCfg = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.Build.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|Any CPU.Deploy.0 = Debug|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.ActiveCfg = Debug|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.Build.0 = Debug|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.Deploy.0 = Debug|ARM @@ -682,7 +589,6 @@ Global {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.ActiveCfg = Debug|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.Build.0 = Debug|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.Deploy.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|Any CPU.ActiveCfg = Release|x86 {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.ActiveCfg = Release|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Build.0 = Release|ARM {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Deploy.0 = Release|ARM diff --git a/src/Microsoft.Management.Deployment.Client/readme.txt b/src/Microsoft.Management.Deployment.Client/readme.txt deleted file mode 100644 index aa0dc2f192..0000000000 --- a/src/Microsoft.Management.Deployment.Client/readme.txt +++ /dev/null @@ -1,23 +0,0 @@ -======================================================================== - C++/WinRT Microsoft.Management.Deployment Project Overview -======================================================================== - -This project demonstrates how to get started authoring Windows Runtime -classes directly with standard C++, using the C++/WinRT SDK component -to generate implementation headers from interface (IDL) files. The -generated Windows Runtime component binary and WinMD files should then -be bundled with the Universal Windows Platform (UWP) app consuming them. - -Steps: -1. Create an interface (IDL) file to define your Windows Runtime class, - its default interface, and any other interfaces it implements. -2. Build the project once to generate module.g.cpp, module.h.cpp, and - implementation templates under the "Generated Files" folder, as - well as skeleton class definitions under "Generated Files\sources". -3. Use the skeleton class definitions for reference to implement your - Windows Runtime classes. - -======================================================================== -Learn more about C++/WinRT here: -http://aka.ms/cppwinrt/ -======================================================================== From 48669bde68a7ce08ddd20d9825218c20460c4708 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 25 Aug 2021 02:32:03 -0700 Subject: [PATCH 12/53] Append defines instead of overriding. --- src/PackagedTests/PackagedTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 41d91b4dc6..3718a22966 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -45,7 +45,7 @@ ARM64 - DEBUG + DEBUG;$(DefineConstants) true full From 40d62a94b8376e7d5d557ecd9a5ee85a84bca2f8 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 25 Aug 2021 14:20:08 -0700 Subject: [PATCH 13/53] Attempt switch to packages.config for nuget --- src/PackagedTests/PackagedTests.csproj | 22 +++------------------- src/PackagedTests/packages.config | 7 +++++++ 2 files changed, 10 insertions(+), 19 deletions(-) create mode 100644 src/PackagedTests/packages.config diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 3718a22966..9df6aedd4f 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -1,5 +1,5 @@  - + Debug @@ -14,6 +14,7 @@ 10.0.19041.0 10.0.17763.0 14 + true 512 {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(VisualStudioVersion) @@ -29,7 +30,6 @@ prompt false true - true TRACE;NETFX_CORE;WINDOWS_UWP @@ -52,9 +52,7 @@ pdbonly true - - - PackageReference + true @@ -87,20 +85,6 @@ - - - 6.2.12 - - - 16.11.0 - - - 2.2.5 - - - 2.2.5 - - {4bc1f40b-36c2-4bbb-8306-76e490b13bbd} diff --git a/src/PackagedTests/packages.config b/src/PackagedTests/packages.config new file mode 100644 index 0000000000..122a87d91c --- /dev/null +++ b/src/PackagedTests/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 84d7982b95eae210a5d4cb982e145adfd64a6228 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 25 Aug 2021 15:27:26 -0700 Subject: [PATCH 14/53] Add packagereference back. --- src/PackagedTests/PackagedTests.csproj | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 9df6aedd4f..2492164015 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -85,6 +85,20 @@ + + + 6.2.12 + + + 16.11.0 + + + 2.2.5 + + + 2.2.5 + + {4bc1f40b-36c2-4bbb-8306-76e490b13bbd} From 95c024d47242ade6ca9e11c14168c66a7e4fb6e4 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 25 Aug 2021 16:29:19 -0700 Subject: [PATCH 15/53] Try packages.config again. --- src/PackagedTests/PackagedTests.csproj | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 2492164015..dbca0fa3f5 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -85,26 +85,15 @@ - - - 6.2.12 - - - 16.11.0 - - - 2.2.5 - - - 2.2.5 - - {4bc1f40b-36c2-4bbb-8306-76e490b13bbd} Microsoft.Management.Deployment.Client + + + 14.0 From 763f2e1eb9d862080ce03fa447000a7ed0c2d2f8 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:21:11 -0700 Subject: [PATCH 16/53] Try direct restore of csproj --- azure-pipelines.yml | 5 +++++ src/PackagedTests/PackagedTests.csproj | 17 ++++++++++++++--- src/PackagedTests/packages.config | 7 ------- 3 files changed, 19 insertions(+), 10 deletions(-) delete mode 100644 src/PackagedTests/packages.config diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b74287981e..49e334c4af 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -65,6 +65,11 @@ jobs: displayName: Restore AppInstallerTestMsixInstaller inputs: restoreSolution: 'src\AppInstallerTestMsixInstaller\AppInstallerTestMsixInstaller.wapproj' + + - task: NuGetCommand@2 + displayName: Restore PackagedTests + inputs: + restoreSolution: 'src\PackagedTests\PackagedTests.csproj' # Restores only .NET core projects, but is still necessary, as without this the IndexCreationTool and LocalhostWebServer projects fail to build - task: DotNetCoreCLI@2 diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index dbca0fa3f5..2492164015 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -85,15 +85,26 @@ + + + 6.2.12 + + + 16.11.0 + + + 2.2.5 + + + 2.2.5 + + {4bc1f40b-36c2-4bbb-8306-76e490b13bbd} Microsoft.Management.Deployment.Client - - - 14.0 diff --git a/src/PackagedTests/packages.config b/src/PackagedTests/packages.config deleted file mode 100644 index 122a87d91c..0000000000 --- a/src/PackagedTests/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file From 20e11a51f91a0e51cd3c0522fd76e76dac32afe4 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:45:32 -0700 Subject: [PATCH 17/53] Try workaround solutiondir issue --- .../Microsoft.Management.Deployment.Client.vcxproj | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj index d7495334d6..e9cd4ec4e9 100644 --- a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj +++ b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj @@ -1,6 +1,6 @@ - + true true @@ -59,6 +59,7 @@ v142 Unicode false + true true @@ -183,13 +184,13 @@ - + 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}. - - + + \ No newline at end of file From 40ad2dbd6d8ae1de416880968a638c327292057c Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 26 Aug 2021 01:05:25 -0700 Subject: [PATCH 18/53] Try fix bundleplatforms. --- .../Microsoft.Management.Deployment.Client.vcxproj | 1 - src/PackagedTests/PackagedTests.csproj | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj index e9cd4ec4e9..041a2524de 100644 --- a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj +++ b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj @@ -82,7 +82,6 @@ - $(VC_IncludePath);$(WindowsSDK_IncludePath); $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 2492164015..8b734a37af 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -22,8 +22,6 @@ False True True - Always - x64 0 bin\$(Platform)\$(Configuration)\ ;2008 From 83bd27265356a8b9287aa7160a0774bd041ca13e Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 26 Aug 2021 02:42:19 -0700 Subject: [PATCH 19/53] Change outputpath --- src/PackagedTests/PackagedTests.csproj | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 8b734a37af..ff2442475e 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -23,7 +23,6 @@ True True 0 - bin\$(Platform)\$(Configuration)\ ;2008 prompt false @@ -52,6 +51,10 @@ true true + + $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + From d6ddc0831248fcc564cec738f3b3fd520bbe0d68 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 27 Aug 2021 15:22:55 -0700 Subject: [PATCH 20/53] Remove output path --- src/PackagedTests/PackagedTests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index ff2442475e..d9ae9fc9c1 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -52,7 +52,6 @@ true - $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ From 94dba4b0f4be2bb284b660050e9ae412a1b884e2 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 27 Aug 2021 19:24:33 -0700 Subject: [PATCH 21/53] Make client and server have separate lib names. --- .../Microsoft.Management.Deployment.vcxproj | 3 ++- src/WinGetServer/WinGetServer.vcxproj | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj index d3fba05a4c..d9c12c8f6d 100644 --- a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj +++ b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj @@ -14,7 +14,7 @@ 10.0 10.0.18362.0 10.0.17763.0 - -lib Microsoft_Management_Deployment + -lib @@ -85,6 +85,7 @@ $(VC_IncludePath);$(WindowsSDK_IncludePath); $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ $(PlatformTarget)\$(Configuration)\ + $(RootNamespace).Server true false ..\CodeAnalysis.ruleset diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index 8239fe8105..020ed245a7 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -106,7 +106,7 @@ Windows false $(OutDir)..\Microsoft.Management.Deployment;$(OutDir)..\AppInstallerCLICore;$(OutDir)..\JsonCppLib;$(OutDir)..\AppInstallerRepositoryCore;$(OutDir)..\YamlCppLib;$(OutDir)..\AppInstallerCommonCore;$(OutDir)..\cpprestsdk;%(AdditionalLibraryDirectories) - Microsoft.Management.Deployment.lib;AppInstallerCLICore.lib;AppInstallerCommonCore.lib;AppInstallerRepositoryCore.lib;JsonCppLib.lib;YamlCppLib.lib;cpprestsdk.lib;wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;%(AdditionalDependencies) + Microsoft.Management.Deployment.Server.lib;AppInstallerCLICore.lib;AppInstallerCommonCore.lib;AppInstallerRepositoryCore.lib;JsonCppLib.lib;YamlCppLib.lib;cpprestsdk.lib;wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;%(AdditionalDependencies) From 76c83efa30384fa88204c2d8658bd981f87ce918 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 27 Aug 2021 19:24:52 -0700 Subject: [PATCH 22/53] Add output path back. --- src/PackagedTests/PackagedTests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index d9ae9fc9c1..ff2442475e 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -52,6 +52,7 @@ true + $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ From 2903f189810af408528a4116a3f88d48a76d691a Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 27 Aug 2021 19:59:33 -0700 Subject: [PATCH 23/53] Merge build break fix to allow pipeline run. --- src/AppInstallerRepositoryCore/RepositorySource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppInstallerRepositoryCore/RepositorySource.cpp b/src/AppInstallerRepositoryCore/RepositorySource.cpp index 70b41c0224..81341653e2 100644 --- a/src/AppInstallerRepositoryCore/RepositorySource.cpp +++ b/src/AppInstallerRepositoryCore/RepositorySource.cpp @@ -969,7 +969,7 @@ namespace AppInstaller::Repository // Check for a non-user tombstone; hidden source data that we don't want to collide. // TODO: Refactor the source interface so that we don't do this - auto tombstoneSource = sourceList.GetSource(name); + auto tombstoneSource = sourceList.GetSource(sourceDetails.Name); THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS, tombstoneSource && tombstoneSource->Origin != SourceOrigin::User); // Check sources allowed by group policy From 8325d9df66adb5f0940548f25a620b0d6472cb9a Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Mon, 30 Aug 2021 11:35:31 -0700 Subject: [PATCH 24/53] Move test package to its own solution. --- azure-pipelines.yml | 3 +- src/AppInstallerCLI.sln | 39 +---------------------- src/PackagedTests.sln | 69 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 39 deletions(-) create mode 100644 src/PackagedTests.sln diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 49e334c4af..592561ff71 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -86,11 +86,12 @@ jobs: arguments: '-TargetFile binver\binver\version.h -BuildVersion $(BuildVer)' workingDirectory: 'src' + # Build all solutions in the root directory. - task: VSBuild@1 displayName: Build Solution inputs: platform: 'x86' - solution: '$(solution)' + solution: 'src\*.sln' configuration: '$(buildConfiguration)' msbuildArgs: '/p:AppxBundlePlatforms="$(buildPlatform)" /p:AppxPackageDir="$(appxPackageDir)" diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index 36f9683fcd..c9da292a79 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -6,6 +6,7 @@ Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "AppInstallerCLIPackage", "A ProjectSection(ProjectDependencies) = postProject {4BC1F40B-36C2-4BBB-8306-76E490B13BBD} = {4BC1F40B-36C2-4BBB-8306-76E490B13BBD} {1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69} + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777} = {5B6F90DF-FD19-4BAE-83D9-24DAD128E777} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppInstallerCLI", "AppInstallerCLI\AppInstallerCLI.vcxproj", "{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}" @@ -126,8 +127,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServe EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTests\PackagedTests.csproj", "{8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}" -EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ManifestSchema\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4 @@ -565,42 +564,6 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.ActiveCfg = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Build.0 = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Deploy.0 = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.Build.0 = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.ActiveCfg = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.Build.0 = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.Deploy.0 = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.ActiveCfg = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Build.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Deploy.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.ActiveCfg = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.Build.0 = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.Deploy.0 = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM64.Build.0 = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM64.Deploy.0 = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x64.ActiveCfg = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x64.Build.0 = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x64.Deploy.0 = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.ActiveCfg = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.Build.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.Deploy.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.ActiveCfg = Release|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Build.0 = Release|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Deploy.0 = Release|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.ActiveCfg = Release|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.Build.0 = Release|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.Deploy.0 = Release|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.ActiveCfg = Release|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.Build.0 = Release|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.Deploy.0 = Release|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.ActiveCfg = Release|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.Build.0 = Release|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/PackagedTests.sln b/src/PackagedTests.sln new file mode 100644 index 0000000000..42e13aa9e3 --- /dev/null +++ b/src/PackagedTests.sln @@ -0,0 +1,69 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31424.327 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTests\PackagedTests.csproj", "{8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.ActiveCfg = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Build.0 = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Deploy.0 = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.Build.0 = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.ActiveCfg = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.Build.0 = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.Deploy.0 = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Build.0 = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Deploy.0 = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.ActiveCfg = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Build.0 = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Deploy.0 = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.ActiveCfg = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.Build.0 = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.Deploy.0 = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.ActiveCfg = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.Build.0 = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.Deploy.0 = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.ActiveCfg = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.Build.0 = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.Deploy.0 = Release|x86 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.ActiveCfg = Debug|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.Build.0 = Debug|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.Build.0 = Debug|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x64.ActiveCfg = Debug|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x64.Build.0 = Debug|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.ActiveCfg = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.Build.0 = Debug|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.ActiveCfg = Release|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.Build.0 = Release|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.ActiveCfg = Release|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.Build.0 = Release|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.ActiveCfg = Release|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {00EA47F7-6564-49A1-8CE7-E44A81373CC8} + EndGlobalSection +EndGlobal From d8ac3dae29876984031a5301e138b1c4638f4747 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Tue, 31 Aug 2021 12:23:29 -0700 Subject: [PATCH 25/53] Microsoft.Management.Deployment.Client buildchange --- .../CatalogPackage.cpp | 2 +- .../CatalogPackage.h | 20 - ...ent.CreateCompositePackageCatalogOptions.h | 15 + .../Client.FindPackagesOptions.h | 15 + .../Client.InstallOptions.h | 15 + .../Client.PackageManager.h | 13 + .../Client.PackageMatchFilter.h | 15 + .../ConnectResult.cpp | 2 +- .../ConnectResult.h | 15 - .../CreateCompositePackageCatalogOptions.cpp | 6 +- .../CreateCompositePackageCatalogOptions.h | 28 - .../FindPackagesOptions.cpp | 6 +- .../FindPackagesOptions.h | 29 - .../FindPackagesResult.cpp | 2 +- .../FindPackagesResult.h | 16 - .../InstallOptions.cpp | 14 +- .../InstallOptions.h | 43 -- .../InstallResult.cpp | 2 +- .../InstallResult.h | 17 - .../MatchResult.cpp | 2 +- .../MatchResult.h | 15 - ...osoft.Management.Deployment.Client.vcxproj | 32 +- .../PackageCatalog.cpp | 2 +- .../PackageCatalog.h | 17 - .../PackageCatalogInfo.cpp | 2 +- .../PackageCatalogInfo.h | 20 - .../PackageCatalogReference.cpp | 2 +- .../PackageCatalogReference.h | 17 - .../PackageManager.cpp | 11 +- .../PackageManager.h | 29 - .../PackageManager.idl | 541 ------------------ .../PackageMatchFilter.cpp | 6 +- .../PackageMatchFilter.h | 31 - .../PackageVersionId.cpp | 2 +- .../PackageVersionId.h | 16 - .../PackageVersionInfo.cpp | 6 +- .../PackageVersionInfo.h | 21 - .../CatalogPackage.h | 6 + .../ConnectResult.h | 8 +- .../CreateCompositePackageCatalogOptions.h | 6 + .../FindPackagesOptions.h | 6 + .../FindPackagesResult.h | 5 + .../InstallOptions.h | 6 + .../InstallResult.h | 6 + .../MatchResult.h | 3 + .../PackageCatalog.h | 7 +- .../PackageCatalogInfo.h | 6 + .../PackageCatalogReference.h | 6 + .../PackageManager.h | 3 + .../PackageMatchFilter.h | 9 + .../PackageVersionId.h | 6 + .../PackageVersionInfo.cpp | 4 + .../PackageVersionInfo.h | 8 +- 53 files changed, 226 insertions(+), 916 deletions(-) delete mode 100644 src/Microsoft.Management.Deployment.Client/CatalogPackage.h create mode 100644 src/Microsoft.Management.Deployment.Client/Client.CreateCompositePackageCatalogOptions.h create mode 100644 src/Microsoft.Management.Deployment.Client/Client.FindPackagesOptions.h create mode 100644 src/Microsoft.Management.Deployment.Client/Client.InstallOptions.h create mode 100644 src/Microsoft.Management.Deployment.Client/Client.PackageManager.h create mode 100644 src/Microsoft.Management.Deployment.Client/Client.PackageMatchFilter.h delete mode 100644 src/Microsoft.Management.Deployment.Client/ConnectResult.h delete mode 100644 src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h delete mode 100644 src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h delete mode 100644 src/Microsoft.Management.Deployment.Client/FindPackagesResult.h delete mode 100644 src/Microsoft.Management.Deployment.Client/InstallOptions.h delete mode 100644 src/Microsoft.Management.Deployment.Client/InstallResult.h delete mode 100644 src/Microsoft.Management.Deployment.Client/MatchResult.h delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalog.h delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.h delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageManager.h delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageManager.idl delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageVersionId.h delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h diff --git a/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp b/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp index b89293c930..8146ef966b 100644 --- a/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp +++ b/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "CatalogPackage.h" +#include #include "CatalogPackage.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/CatalogPackage.h b/src/Microsoft.Management.Deployment.Client/CatalogPackage.h deleted file mode 100644 index 79738d946d..0000000000 --- a/src/Microsoft.Management.Deployment.Client/CatalogPackage.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "CatalogPackage.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct CatalogPackage : CatalogPackageT - { - CatalogPackage() = default; - - hstring Id(); - hstring Name(); - winrt::Microsoft::Management::Deployment::PackageVersionInfo InstalledVersion(); - winrt::Windows::Foundation::Collections::IVectorView AvailableVersions(); - winrt::Microsoft::Management::Deployment::PackageVersionInfo DefaultInstallVersion(); - winrt::Microsoft::Management::Deployment::PackageVersionInfo GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey); - bool IsUpdateAvailable(); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/Client.CreateCompositePackageCatalogOptions.h b/src/Microsoft.Management.Deployment.Client/Client.CreateCompositePackageCatalogOptions.h new file mode 100644 index 0000000000..5d7f687546 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/Client.CreateCompositePackageCatalogOptions.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "CreateCompositePackageCatalogOptions.g.h" + +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT + { + auto ActivateInstance() const + { + return winrt::create_instance(__uuidof(implementation::CreateCompositePackageCatalogOptions), CLSCTX_ALL); + } + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/Client.FindPackagesOptions.h b/src/Microsoft.Management.Deployment.Client/Client.FindPackagesOptions.h new file mode 100644 index 0000000000..ad032e19da --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/Client.FindPackagesOptions.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "FindPackagesOptions.g.h" + +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct FindPackagesOptions : FindPackagesOptionsT + { + auto ActivateInstance() const + { + return winrt::create_instance(__uuidof(implementation::FindPackagesOptions), CLSCTX_ALL); + } + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/Client.InstallOptions.h b/src/Microsoft.Management.Deployment.Client/Client.InstallOptions.h new file mode 100644 index 0000000000..3b36822c35 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/Client.InstallOptions.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "InstallOptions.g.h" + +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct InstallOptions : InstallOptionsT + { + auto ActivateInstance() const + { + return winrt::create_instance(__uuidof(implementation::InstallOptions), CLSCTX_ALL); + } + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h b/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h new file mode 100644 index 0000000000..2fb60f0a39 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h @@ -0,0 +1,13 @@ +#pragma once +#include "PackageManager.g.h" + +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct PackageManager : PackageManagerT + { + auto ActivateInstance() const + { + return winrt::create_instance(__uuidof(implementation::PackageManager), CLSCTX_ALL); + } + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/Client.PackageMatchFilter.h b/src/Microsoft.Management.Deployment.Client/Client.PackageMatchFilter.h new file mode 100644 index 0000000000..c6fb8c536a --- /dev/null +++ b/src/Microsoft.Management.Deployment.Client/Client.PackageMatchFilter.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageMatchFilter.g.h" + +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct PackageMatchFilter : PackageMatchFilterT + { + auto ActivateInstance() const + { + return winrt::create_instance(__uuidof(implementation::PackageMatchFilter), CLSCTX_ALL); + } + }; +} diff --git a/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp b/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp index 40dd27204a..68bffbba01 100644 --- a/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp +++ b/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "ConnectResult.h" +#include #include "ConnectResult.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/ConnectResult.h b/src/Microsoft.Management.Deployment.Client/ConnectResult.h deleted file mode 100644 index b0ff6b47e3..0000000000 --- a/src/Microsoft.Management.Deployment.Client/ConnectResult.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "ConnectResult.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct ConnectResult : ConnectResultT - { - ConnectResult() = default; - - winrt::Microsoft::Management::Deployment::ConnectResultStatus Status(); - winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp index c8f60de369..b7eb360224 100644 --- a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.cpp @@ -1,7 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "CreateCompositePackageCatalogOptions.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +#include +#include +#pragma warning( pop ) #include "CreateCompositePackageCatalogOptions.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h b/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h deleted file mode 100644 index 1bda0b1f62..0000000000 --- a/src/Microsoft.Management.Deployment.Client/CreateCompositePackageCatalogOptions.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "CreateCompositePackageCatalogOptions.g.h" - -const CLSID CLSID_CreateCompositePackageCatalogOptions = { 0xEE160901, 0xB317, 0x4EA7, { 0x9C, 0xC6, 0x53, 0x55, 0xC6, 0xD7, 0xD8, 0xA7 } }; //EE160901-B317-4EA7-9CC6-5355C6D7D8A7 - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT - { - CreateCompositePackageCatalogOptions() = default; - - winrt::Windows::Foundation::Collections::IVector Catalogs(); - winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CompositeSearchBehavior(); - void CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value); - }; -} -namespace winrt::Microsoft::Management::Deployment::factory_implementation -{ - struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT - { - auto ActivateInstance() const - { - return winrt::create_instance(CLSID_CreateCompositePackageCatalogOptions, CLSCTX_ALL); - } - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp index 749e98268b..041f8a7491 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.cpp @@ -1,7 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "FindPackagesOptions.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +#include +#include +#pragma warning( pop ) #include "FindPackagesOptions.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h b/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h deleted file mode 100644 index 854b529b41..0000000000 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesOptions.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "FindPackagesOptions.g.h" - -const CLSID CLSID_FindPackagesOptions = { 0x1BD8FF3A, 0xEC50, 0x4F69, { 0xAE, 0xEE, 0xDF, 0x4C, 0x9D, 0x3B, 0xAA, 0x96 } }; //1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96 - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct FindPackagesOptions : FindPackagesOptionsT - { - FindPackagesOptions() = default; - - winrt::Windows::Foundation::Collections::IVector Selectors(); - winrt::Windows::Foundation::Collections::IVector Filters(); - uint32_t ResultLimit(); - void ResultLimit(uint32_t value); - }; -} -namespace winrt::Microsoft::Management::Deployment::factory_implementation -{ - struct FindPackagesOptions : FindPackagesOptionsT - { - auto ActivateInstance() const - { - return winrt::create_instance(CLSID_FindPackagesOptions, CLSCTX_ALL); - } - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp index 75fc89335f..8a674b87a9 100644 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp +++ b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "FindPackagesResult.h" +#include #include "FindPackagesResult.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h deleted file mode 100644 index 83dafaff84..0000000000 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "FindPackagesResult.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct FindPackagesResult : FindPackagesResultT - { - FindPackagesResult() = default; - - winrt::Microsoft::Management::Deployment::FindPackagesResultStatus Status(); - winrt::Windows::Foundation::Collections::IVectorView Matches(); - bool WasLimitExceeded(); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp index 7ee258963c..e0d18b843c 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp @@ -1,11 +1,19 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "InstallOptions.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +#include +#include +#pragma warning( pop ) #include "InstallOptions.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation { + InstallOptions::InstallOptions() + { + throw hresult_not_implemented(); + } winrt::Microsoft::Management::Deployment::PackageVersionId InstallOptions::PackageVersionId() { throw hresult_not_implemented(); @@ -78,4 +86,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation { throw hresult_not_implemented(); } + winrt::Windows::Foundation::Collections::IVector InstallOptions::AllowedArchitectures() + { + throw hresult_not_implemented(); + } } diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.h b/src/Microsoft.Management.Deployment.Client/InstallOptions.h deleted file mode 100644 index db97f1b6b9..0000000000 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "InstallOptions.g.h" - -const CLSID CLSID_InstallOptions = { 0x44FE0580, 0x62F7, 0x44D4, 0x9E, 0x91, 0xAA, 0x96, 0x14, 0xAB, 0x3E, 0x86 }; //44FE0580-62F7-44D4-9E91-AA9614AB3E86 - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct InstallOptions : InstallOptionsT - { - InstallOptions() = default; - - winrt::Microsoft::Management::Deployment::PackageVersionId PackageVersionId(); - void PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value); - hstring PreferredInstallLocation(); - void PreferredInstallLocation(hstring const& value); - winrt::Microsoft::Management::Deployment::PackageInstallScope PackageInstallScope(); - void PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value); - winrt::Microsoft::Management::Deployment::PackageInstallMode PackageInstallMode(); - void PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const& value); - hstring LogOutputPath(); - void LogOutputPath(hstring const& value); - bool AllowHashMismatch(); - void AllowHashMismatch(bool value); - hstring ReplacementInstallerArguments(); - void ReplacementInstallerArguments(hstring const& value); - hstring CorrelationData(); - void CorrelationData(hstring const& value); - hstring AdditionalPackageCatalogArguments(); - void AdditionalPackageCatalogArguments(hstring const& value); - }; -} -namespace winrt::Microsoft::Management::Deployment::factory_implementation -{ - struct InstallOptions : InstallOptionsT - { - auto ActivateInstance() const - { - return winrt::create_instance(CLSID_InstallOptions, CLSCTX_ALL); - } - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/InstallResult.cpp b/src/Microsoft.Management.Deployment.Client/InstallResult.cpp index 162a0d63ba..18b06b4e5c 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallResult.cpp +++ b/src/Microsoft.Management.Deployment.Client/InstallResult.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "InstallResult.h" +#include #include "InstallResult.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/InstallResult.h b/src/Microsoft.Management.Deployment.Client/InstallResult.h deleted file mode 100644 index 4086db3e7e..0000000000 --- a/src/Microsoft.Management.Deployment.Client/InstallResult.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "InstallResult.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct InstallResult : InstallResultT - { - InstallResult() = default; - - hstring CorrelationData(); - bool RebootRequired(); - winrt::Microsoft::Management::Deployment::InstallResultStatus Status(); - winrt::hresult ExtendedErrorCode(); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/MatchResult.cpp b/src/Microsoft.Management.Deployment.Client/MatchResult.cpp index 2487823282..cf514c00c9 100644 --- a/src/Microsoft.Management.Deployment.Client/MatchResult.cpp +++ b/src/Microsoft.Management.Deployment.Client/MatchResult.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "MatchResult.h" +#include #include "MatchResult.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/MatchResult.h b/src/Microsoft.Management.Deployment.Client/MatchResult.h deleted file mode 100644 index a7fd68f9b3..0000000000 --- a/src/Microsoft.Management.Deployment.Client/MatchResult.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "MatchResult.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct MatchResult : MatchResultT - { - MatchResult() = default; - - winrt::Microsoft::Management::Deployment::CatalogPackage CatalogPackage(); - winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchCriteria(); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj index 041a2524de..9edd61d1ca 100644 --- a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj +++ b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj @@ -83,7 +83,7 @@ - $(VC_IncludePath);$(WindowsSDK_IncludePath); + ..\Microsoft.Management.Deployment;$(VC_IncludePath);$(WindowsSDK_IncludePath); $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ $(PlatformTarget)\$(Configuration)\ $(RootNamespace) @@ -102,7 +102,7 @@ /DWINRT_NO_MAKE_DETECTION %(AdditionalOptions) - _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + INCLUDE_ONLY_INTERFACE_METHODS;_WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) @@ -126,24 +126,12 @@ - - - - - - - - - - - - - - - - PackageManager.idl - + + + + + @@ -163,13 +151,11 @@ Create - - PackageManager.idl - + - + diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp index 948a159d40..aa7adf22d1 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "PackageCatalog.h" +#include #include "PackageCatalog.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalog.h b/src/Microsoft.Management.Deployment.Client/PackageCatalog.h deleted file mode 100644 index 648d6ca7a1..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalog.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageCatalog.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageCatalog : PackageCatalogT - { - PackageCatalog() = default; - - bool IsComposite(); - winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); - winrt::Windows::Foundation::IAsyncOperation FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options); - winrt::Microsoft::Management::Deployment::FindPackagesResult FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp index 56b197726b..11beb2415b 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "PackageCatalogInfo.h" +#include #include "PackageCatalogInfo.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.h b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.h deleted file mode 100644 index b400143ae6..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageCatalogInfo.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageCatalogInfo : PackageCatalogInfoT - { - PackageCatalogInfo() = default; - - hstring Id(); - hstring Name(); - hstring Type(); - hstring Argument(); - winrt::Windows::Foundation::DateTime LastUpdateTime(); - winrt::Microsoft::Management::Deployment::PackageCatalogOrigin Origin(); - winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel TrustLevel(); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp index 3fe12edd6d..62447e1ca9 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "PackageCatalogReference.h" +#include #include "PackageCatalogReference.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h deleted file mode 100644 index 2c76518841..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageCatalogReference.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageCatalogReference : PackageCatalogReferenceT - { - PackageCatalogReference() = default; - - bool IsComposite(); - winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); - winrt::Windows::Foundation::IAsyncOperation ConnectAsync(); - winrt::Microsoft::Management::Deployment::ConnectResult Connect(); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp index d7b816db96..e70a45d444 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp @@ -1,5 +1,9 @@ #include "pch.h" -#include "PackageManager.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +#include +#include +#pragma warning( pop ) #include "PackageManager.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation @@ -28,4 +32,9 @@ namespace winrt::Microsoft::Management::Deployment::implementation { throw hresult_not_implemented(); } + winrt::Windows::Foundation::IAsyncOperationWithProgress PackageManager::GetInstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo) + { + throw hresult_not_implemented(); + } + } diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.h b/src/Microsoft.Management.Deployment.Client/PackageManager.h deleted file mode 100644 index 51c9c69211..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include "PackageManager.g.h" - -const CLSID CLSID_PackageManager = { 0x74CB3139, 0xB7C5, 0x4B9E, { 0x93, 0x88, 0xE6, 0x61, 0x6D, 0xEA, 0x28, 0x8C } }; //74CB3139-B7C5-4B9E-9388-E6616DEA288C - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageManager : PackageManagerT - { - PackageManager() = default; - - winrt::Windows::Foundation::Collections::IVectorView GetPackageCatalogs(); - winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog); - winrt::Microsoft::Management::Deployment::PackageCatalogReference GetLocalPackageCatalog(winrt::Microsoft::Management::Deployment::LocalPackageCatalog const& localPackageCatalog); - winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPackageCatalogByName(hstring const& catalogName); - winrt::Microsoft::Management::Deployment::PackageCatalogReference CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options); - winrt::Windows::Foundation::IAsyncOperationWithProgress InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options); - }; -} -namespace winrt::Microsoft::Management::Deployment::factory_implementation -{ - struct PackageManager : PackageManagerT - { - auto ActivateInstance() const - { - return winrt::create_instance(CLSID_PackageManager, CLSCTX_ALL); - } - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.idl b/src/Microsoft.Management.Deployment.Client/PackageManager.idl deleted file mode 100644 index 2b85fce4b6..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.idl +++ /dev/null @@ -1,541 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -namespace Microsoft.Management.Deployment -{ - [contractversion(1)] - apicontract WindowsPackageManagerContract{}; - - /// State of the install. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PackageInstallProgressState - { - /// The install is queued but not yet active. Cancellation of the IAsyncOperationWithProgress in this - /// state will prevent the package from downloading or installing. - Queued, - /// The installer is downloading. Cancellation of the IAsyncOperationWithProgress in this state will - /// end the download and prevent the package from installing. - Downloading, - /// The install is in progress. Cancellation of the IAsyncOperationWithProgress in this state will not - /// stop the installation or the post install cleanup. - Installing, - /// The installer has completed and cleanup actions are in progress. Cancellation of the - /// IAsyncOperationWithProgress in this state will not stop cleanup or roll back the install. - PostInstall, - /// The operation has completed. - Finished, - }; - - /// Progress object for the install - /// DESIGN NOTE: percentage for the install as a whole is purposefully not included as there is no way to - /// estimate progress when the installer is running. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - struct InstallProgress - { - /// State of the install - PackageInstallProgressState State; - /// DESIGN NOTE: BytesDownloaded may only be available for downloads done by Windows Package Manager itself. - /// Number of bytes downloaded if known - UInt64 BytesDownloaded; - /// DESIGN NOTE: BytesRequired may only be available for downloads done by Windows Package Manager itself. - /// Number of bytes required if known - UInt64 BytesRequired; - /// Download percentage completed - Double DownloadProgress; - /// Install percentage if known. - Double InstallationProgress; - }; - - /// Status of the Install call - /// Implementation Note: Errors mapped from AppInstallerErrors.h - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum InstallResultStatus - { - Ok, - BlockedByPolicy, - CatalogError, - InternalError, - InvalidOptions, - DownloadError, - InstallError, - ManifestError, - NoApplicableInstallers, - }; - - /// Result of the install - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass InstallResult - { - /// Used by a caller to correlate the install with a caller's data. - String CorrelationData{ get; }; - /// Whether a restart is required to complete the install. - Boolean RebootRequired{ get; }; - - /// Batched error code, example APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED - InstallResultStatus Status{ get; }; - /// Specific error if known, from downloader or installer itself, example ERROR_INSTALL_PACKAGE_REJECTED - HRESULT ExtendedErrorCode{ get; }; - } - - /// IMPLEMENTATION NOTE: SourceOrigin from AppInstallerRepositorySource.h - /// Defines the origin of the package catalog details. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PackageCatalogOrigin - { - /// Predefined means it came as part of the Windows Package Manager package and cannot be removed. - Predefined, - /// User means it was added by the user and could be removed. - User, - }; - - /// IMPLEMENTATION NOTE: SourceTrustLevel from AppInstallerRepositorySource.h - /// Defines the trust level of the package catalog. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PackageCatalogTrustLevel - { - None, - Trusted, - }; - - /// IMPLEMENTATION NOTE: SourceDetails from AppInstallerRepositorySource.h - /// Interface for retrieving information about an package catalog without acting on it. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass PackageCatalogInfo - { - /// The package catalog's unique identifier. - /// SAMPLE VALUES: For OpenWindowsCatalog "Microsoft.Winget.Source_8wekyb3d8bbwe" - /// For contoso sample on msdn "contoso" - String Id { get; }; - /// The name of the package catalog. - /// SAMPLE VALUES: For OpenWindowsCatalog "winget". - /// For contoso sample on msdn "contoso" - String Name { get; }; - /// The type of the package catalog. - /// ALLOWED VALUES: "Microsoft.Rest", "Microsoft.PreIndexed.Package" - /// SAMPLE VALUES: For OpenWindowsCatalog "Microsoft.PreIndexed.Package". - /// For contoso sample on msdn "Microsoft.PreIndexed.Package" - String Type { get; }; - /// The argument used when adding the package catalog. - /// SAMPLE VALUES: For OpenWindowsCatalog "https://winget.azureedge.net/cache" - /// For contoso sample on msdn "https://pkgmgr-int.azureedge.net/cache" - String Argument { get; }; - /// The last time that this package catalog was updated. - Windows.Foundation.DateTime LastUpdateTime { get; }; - /// The origin of the package catalog. - PackageCatalogOrigin Origin { get; }; - /// The trust level of the package catalog - PackageCatalogTrustLevel TrustLevel { get; }; - } - - /// A metadata item of a package version. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PackageVersionMetadataField - { - /// The InstallerType of an installed package - InstallerType, - /// The Scope of an installed package - InstalledScope, - /// The system path where the package is installed - InstalledLocation, - /// The standard uninstall command; which may be interactive - StandardUninstallCommand, - /// An uninstall command that should be non-interactive - SilentUninstallCommand, - /// The publisher of the package - PublisherDisplayName, - }; - - /// IMPLEMENTATION NOTE: IPackageVersion from AppInstallerRepositorySearch.h - /// A single package version. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass PackageVersionInfo - { - /// IMPLEMENTATION NOTE: PackageVersionMetadata fields from AppInstallerRepositorySearch.h - /// Gets any metadata associated with this package version. - /// Primarily stores data on installed packages. - /// Metadata fields may have no value (e.g. packages that aren't installed will not have an InstalledLocation). - String GetMetadata(PackageVersionMetadataField metadataField); - /// IMPLEMENTATION NOTE: PackageVersionProperty fields from AppInstallerRepositorySearch.h - String Id { get; }; - String DisplayName { get; }; - String Version { get; }; - String Channel { get; }; - /// DESIGN NOTE: RelativePath from AppInstallerRepositorySearch.h is excluded as not needed. - /// String RelativePath; - - /// IMPLEMENTATION NOTE: PackageVersionMultiProperty fields from AppInstallerRepositorySearch.h - /// PackageFamilyName and ProductCode can have multiple values. - Windows.Foundation.Collections.IVectorView PackageFamilyNames { get; }; - Windows.Foundation.Collections.IVectorView ProductCodes { get; }; - - /// Gets the package catalog where this package version is from. - PackageCatalog PackageCatalog { get; }; - - /// DESIGN NOTE: - /// GetManifest from IPackageVersion in AppInstallerRepositorySearch is not implemented in V1. That class has - /// a lot of fields and no one requesting it. - /// Gets the manifest of this package version. - /// virtual Manifest::Manifest GetManifest() = 0; - } - - /// IMPLEMENTATION NOTE: PackageVersionKey from AppInstallerRepositorySearch.h - /// A key to identify a package version within a package. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass PackageVersionId - { - /// The package catalog id that this version came from. - String PackageCatalogId { get; }; - /// The version. - String Version { get; }; - /// The channel. - String Channel { get; }; - }; - - /// IMPLEMENTATION NOTE: IPackage from AppInstallerRepositorySearch.h - /// A package, potentially containing information about it's local state and the available versions. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass CatalogPackage - { - /// IMPLEMENTATION NOTE: PackageProperty fields from AppInstallerRepositorySearch.h - /// Gets a property of this package. - String Id { get; }; - String Name { get; }; - - /// Gets the installed package information if the package is installed. - PackageVersionInfo InstalledVersion{ get; }; - - /// Gets all available versions of this package. Ordering is not guaranteed. - Windows.Foundation.Collections.IVectorView AvailableVersions { get; }; - - /// Gets the version of this package that will be installed if version is not set in InstallOptions. - PackageVersionInfo DefaultInstallVersion { get; }; - - /// Gets a specific version of this package. - PackageVersionInfo GetPackageVersionInfo(PackageVersionId versionKey); - - /// Gets a value indicating whether an available version is newer than the installed version. - Boolean IsUpdateAvailable { get; }; - - /// DESIGN NOTE: - /// IsSame from IPackage in AppInstallerRepositorySearch is not implemented in V1. - /// Determines if the given IPackage refers to the same package as this one. - /// virtual bool IsSame(const IPackage*) const = 0; - } - - /// IMPLEMENTATION NOTE: CompositeSearchBehavior from AppInstallerRepositorySource.h - /// Search behavior for composite catalogs. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum CompositeSearchBehavior - { - /// Search local catalogs only - LocalCatalogs, - /// Search remote catalogs only, don't check local catalogs for InstalledVersion - RemotePackagesFromRemoteCatalogs, - /// Search remote catalogs, and check local catalogs for InstalledVersion - RemotePackagesFromAllCatalogs, - /// Search both local and remote catalogs. - AllCatalogs, - }; - - /// IMPLEMENTATION NOTE: PackageFieldMatchOption from AppInstallerRepositorySearch.h - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PackageFieldMatchOption - { - Equals, - EqualsCaseInsensitive, - StartsWithCaseInsensitive, - ContainsCaseInsensitive, - }; - - /// IMPLEMENTATION NOTE: PackageFieldMatchOption from AppInstallerRepositorySearch.h - /// The field to match on. - /// The values must be declared in order of preference in search results. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PackageMatchField - { - CatalogDefault, - Id, - Name, - Moniker, - Command, - Tag, - /// DESIGN NOTE: The following PackageFieldMatchOption from AppInstallerRepositorySearch.h are not implemented in V1. - /// PackageFamilyName, - /// ProductCode, - /// NormalizedNameAndPublisher, - }; - - /// IMPLEMENTATION NOTE: PackageMatchFilter from AppInstallerRepositorySearch.h - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass PackageMatchFilter - { - PackageMatchFilter(); - /// The type of string comparison for matching - PackageFieldMatchOption Option; - /// The field to search - PackageMatchField Field; - /// The value to match - String Value; - /// DESIGN NOTE: "Additional" from RequestMatch AppInstallerRepositorySearch.h is not implemented here. - } - - /// IMPLEMENTATION NOTE: MatchResult from AppInstallerRepositorySearch.h - /// A single result from the search. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass MatchResult - { - /// The package found by the search request. - CatalogPackage CatalogPackage { get; }; - - /// The highest order field on which the package matched the search. - PackageMatchFilter MatchCriteria { get; }; - } - - /// Status of the FindPackages call - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum FindPackagesResultStatus - { - Ok, - BlockedByPolicy, - CatalogError, - InternalError, - InvalidOptions - }; - - /// IMPLEMENTATION NOTE: SearchResult from AppInstallerRepositorySearch.h - /// Search result data returned from FindPackages - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass FindPackagesResult - { - /// Error codes - FindPackagesResultStatus Status{ get; }; - - /// The full set of results from the search. - Windows.Foundation.Collections.IVectorView Matches { get; }; - - /// If true, the results were truncated by the given ResultLimit - /// USAGE NOTE: Windows Package Manager does not support result pagination, there is no way to continue - /// getting more results. - Boolean WasLimitExceeded{ get; }; - } - - /// Options for FindPackages - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass FindPackagesOptions - { - FindPackagesOptions(); - - /// DESIGN NOTE: - /// This class maps to SearchRequest from AppInstallerRepositorySearch.h - /// That class is a container for data used to filter the available manifests in an package catalog. - /// Its properties can be thought of as: - /// (Query || Inclusions...) && Filters... - /// If Query and Inclusions are both empty, the starting data set will be the entire database. - /// Everything && Filters... - /// That has been translated in this api so that - /// Inclusions are Selectors below - /// Filters are Filters below - /// Query is PackageFieldMatchOption::PackageCatalogDefined and in the Selector list. - /// USAGE NOTE: Only one selector with PackageFieldMatchOption::PackageCatalogDefined is allowed. - - /// Selectors = you have to match at least one selector (if there are no selectors, then nothing is selected) - Windows.Foundation.Collections.IVector Selectors { get; }; - /// Filters = you have to match all filters(if there are no filters, then there is no filtering of selected items) - Windows.Foundation.Collections.IVector Filters{ get; }; - - /// Restricts the length of the returned results to the specified count. - UInt32 ResultLimit; - } - - /// IMPLEMENTATION NOTE: ISource from AppInstallerRepositorySource.h - /// A catalog for searching for packages - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass PackageCatalog - { - /// Gets a value indicating whether this package catalog is a composite of other package catalogs, - /// and thus the packages may come from disparate package catalogs as well. - Boolean IsComposite { get; }; - /// The details of the package catalog if it is not a composite. - PackageCatalogInfo Info { get; }; - - /// Searches for Packages in the catalog. - Windows.Foundation.IAsyncOperation FindPackagesAsync(FindPackagesOptions options); - FindPackagesResult FindPackages(FindPackagesOptions options); - } - - /// Status of the Connect call - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum ConnectResultStatus - { - Ok, - CatalogError, - }; - - /// Result of the Connect call - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass ConnectResult - { - /// Error codes - ConnectResultStatus Status{ get; }; - - PackageCatalog PackageCatalog { get; }; - } - - /// A reference to a catalog that callers can try to Connect. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass PackageCatalogReference - { - /// Gets a value indicating whether this package catalog is a composite of other package catalogs, - /// and thus the packages may come from disparate package catalogs as well. - Boolean IsComposite { get; }; - /// The details of the package catalog if it is not a composite. - PackageCatalogInfo Info { get; }; - - /// Opens a catalog. Required before searching. For remote catalogs (i.e. not Installed and Installing) this - /// may require downloading information from a server. - Windows.Foundation.IAsyncOperation ConnectAsync(); - ConnectResult Connect(); - } - - /// Catalogs with PackageCatalogOrigin Predefined - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PredefinedPackageCatalog - { - OpenWindowsCatalog, - MicrosoftStore, - }; - - /// Local Catalogs with PackageCatalogOrigin Predefined - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum LocalPackageCatalog - { - InstalledPackages, - }; - - /// Options for creating a composite catalog. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass CreateCompositePackageCatalogOptions - { - CreateCompositePackageCatalogOptions(); - - /// Create a composite catalog to allow searching a user defined or pre defined source - /// and a local source (Installed packages) together - IVector Catalogs { get; }; - /// Sets the default search behavior if the catalog is a composite catalog. - CompositeSearchBehavior CompositeSearchBehavior; - } - - /// Required install scope for the package. If the package does not have an installer that - /// supports the specified scope the Install call will fail with InstallResultStatus.NoApplicableInstallers - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PackageInstallScope - { - /// An installer with any install scope is valid. - Any, - /// Only User install scope installers are valid - User, - /// Only System installers will be valid - System, - }; - - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - enum PackageInstallMode - { - /// The default experience for the installer. Installer may show some UI. - Default, - /// Runs the installer in silent mode. This suppresses the installer's UI to the extent - /// possible (installer may still show some required UI). - Silent, - /// Runs the installer in interactive mode. - Interactive, - }; - - /// Options when installing a package. - /// Intended to allow full compatibility with the "winget install" command line interface. - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass InstallOptions - { - InstallOptions(); - - /// Optionally specifies the version from the package to install. If unspecified the version matching - /// CatalogPackage.GetLatestVersion() is used. - PackageVersionId PackageVersionId; - - /// Specifies alternate location to install package (if supported). - String PreferredInstallLocation; - /// User or Machine. - PackageInstallScope PackageInstallScope; - /// Silent, Interactive, or Default - PackageInstallMode PackageInstallMode; - /// Directs the logging to a log file. If provided, the installer must have have write access to the file - String LogOutputPath; - /// Continues the install even if the hash in the catalog does not match the linked installer. - Boolean AllowHashMismatch; - /// A string that will be passed to the installer. - /// IMPLEMENTATION NOTE: maps to "--override" in the winget cmd line - String ReplacementInstallerArguments; - - /// Used by a caller to correlate the install with a caller's data. - /// The string must be JSON encoded. - String CorrelationData; - /// A string that will be passed to the source server if using a REST source - String AdditionalPackageCatalogArguments; - } - - [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] - runtimeclass PackageManager - { - PackageManager(); - - /// Get the available catalogs. Each source will have a separate catalog. - /// This does not open the catalog. These catalogs can be used individually or merged with CreateCompositePackageCatalogAsync. - /// IMPLEMENTATION NOTE: This is a list of sources returned by Windows Package Manager source list - Windows.Foundation.Collections.IVectorView GetPackageCatalogs(); - /// Get a built in catalog - PackageCatalogReference GetPredefinedPackageCatalog(PredefinedPackageCatalog predefinedPackageCatalog); - /// Get a built in catalog - PackageCatalogReference GetLocalPackageCatalog(LocalPackageCatalog localPackageCatalog); - /// Get a catalog by a known name - PackageCatalogReference GetPackageCatalogByName(String catalogName); - /// Get a composite catalog to allow searching a user defined or pre defined source and a local source - /// (Installing, Installed) together at the same time. - PackageCatalogReference CreateCompositePackageCatalog(CreateCompositePackageCatalogOptions options); - - /// Install the specified package - Windows.Foundation.IAsyncOperationWithProgress InstallPackageAsync(CatalogPackage package, InstallOptions options); - } - - /// Force midl3 to generate vector marshalling info. - declare - { - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - interface Windows.Foundation.Collections.IVector; - interface Windows.Foundation.Collections.IVectorView; - } -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp index 028270abd2..686357322f 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.cpp @@ -1,7 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "PackageMatchFilter.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +#include +#include +#pragma warning( pop ) #include "PackageMatchFilter.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h b/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h deleted file mode 100644 index 483afc1766..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageMatchFilter.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageMatchFilter.g.h" - -const CLSID CLSID_PackageMatchFilter = { 0x3F85B9F4, 0x487A, 0x4C48, { 0x90, 0x35, 0x29, 0x03, 0xF8, 0xA6, 0xD9, 0xE8 } }; //3F85B9F4-487A-4C48-9035-2903F8A6D9E8 - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageMatchFilter : PackageMatchFilterT - { - PackageMatchFilter() = default; - - winrt::Microsoft::Management::Deployment::PackageFieldMatchOption Option(); - void Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value); - winrt::Microsoft::Management::Deployment::PackageMatchField Field(); - void Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value); - hstring Value(); - void Value(hstring const& value); - }; -} -namespace winrt::Microsoft::Management::Deployment::factory_implementation -{ - struct PackageMatchFilter : PackageMatchFilterT - { - auto ActivateInstance() const - { - return winrt::create_instance(CLSID_PackageMatchFilter, CLSCTX_ALL); - } - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp b/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp index e5e3f8708d..ce887cfe29 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "PackageVersionId.h" +#include #include "PackageVersionId.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionId.h b/src/Microsoft.Management.Deployment.Client/PackageVersionId.h deleted file mode 100644 index 57518126a0..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionId.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageVersionId.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageVersionId : PackageVersionIdT - { - PackageVersionId() = default; - - hstring PackageCatalogId(); - hstring Version(); - hstring Channel(); - }; -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp index 401e62722b..3fa6e9b5b3 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "pch.h" -#include "PackageVersionInfo.h" +#include #include "PackageVersionInfo.g.cpp" namespace winrt::Microsoft::Management::Deployment::implementation @@ -38,4 +38,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation { throw hresult_not_implemented(); } + winrt::Microsoft::Management::Deployment::CompareResult PackageVersionInfo::CompareToVersion(hstring versionString) + { + throw hresult_not_implemented(); + } } diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h deleted file mode 100644 index f17ac1ffb6..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include "PackageVersionInfo.g.h" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - struct PackageVersionInfo : PackageVersionInfoT - { - PackageVersionInfo() = default; - - hstring GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField); - hstring Id(); - hstring DisplayName(); - hstring Version(); - hstring Channel(); - winrt::Windows::Foundation::Collections::IVectorView PackageFamilyNames(); - winrt::Windows::Foundation::Collections::IVectorView ProductCodes(); - winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); - }; -} diff --git a/src/Microsoft.Management.Deployment/CatalogPackage.h b/src/Microsoft.Management.Deployment/CatalogPackage.h index 6fdd3b6fbf..37f7347eb1 100644 --- a/src/Microsoft.Management.Deployment/CatalogPackage.h +++ b/src/Microsoft.Management.Deployment/CatalogPackage.h @@ -8,9 +8,12 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct CatalogPackage : CatalogPackageT { CatalogPackage() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize( std::shared_ptr source, std::shared_ptr<::AppInstaller::Repository::IPackage> package); +#endif hstring Id(); hstring Name(); @@ -19,6 +22,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Microsoft::Management::Deployment::PackageVersionInfo DefaultInstallVersion(); winrt::Microsoft::Management::Deployment::PackageVersionInfo GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey); bool IsUpdateAvailable(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: std::shared_ptr m_source; std::shared_ptr<::AppInstaller::Repository::IPackage> m_package; @@ -28,5 +33,6 @@ namespace winrt::Microsoft::Management::Deployment::implementation std::once_flag m_installedVersionOnceFlag; std::once_flag m_availableVersionsOnceFlag; std::once_flag m_defaultInstallVersionOnceFlag; +#endif }; } \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/ConnectResult.h b/src/Microsoft.Management.Deployment/ConnectResult.h index 2e969175dc..a7b59d1fb9 100644 --- a/src/Microsoft.Management.Deployment/ConnectResult.h +++ b/src/Microsoft.Management.Deployment/ConnectResult.h @@ -8,12 +8,18 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct ConnectResult : ConnectResultT { ConnectResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus status, winrt::Microsoft::Management::Deployment::PackageCatalog packageCatalog); +#endif winrt::Microsoft::Management::Deployment::ConnectResultStatus Status(); - winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); + winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: winrt::Microsoft::Management::Deployment::ConnectResultStatus m_status = winrt::Microsoft::Management::Deployment::ConnectResultStatus::Ok; winrt::Microsoft::Management::Deployment::PackageCatalog m_packageCatalog{ nullptr }; +#endif }; } diff --git a/src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.h b/src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.h index eb20c630e6..5bdfe28ab4 100644 --- a/src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.h +++ b/src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.h @@ -17,14 +17,20 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Windows::Foundation::Collections::IVector Catalogs(); winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CompositeSearchBehavior(); void CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: winrt::Windows::Foundation::Collections::IVector m_catalogs{ winrt::single_threaded_vector() }; winrt::Microsoft::Management::Deployment::CompositeSearchBehavior m_compositeSearchBehavior = winrt::Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromAllCatalogs; +#endif }; } + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT { }; } +#endif diff --git a/src/Microsoft.Management.Deployment/FindPackagesOptions.h b/src/Microsoft.Management.Deployment/FindPackagesOptions.h index 5ddb378c9f..a3cb2af30a 100644 --- a/src/Microsoft.Management.Deployment/FindPackagesOptions.h +++ b/src/Microsoft.Management.Deployment/FindPackagesOptions.h @@ -18,17 +18,23 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Windows::Foundation::Collections::IVector Filters(); uint32_t ResultLimit(); void ResultLimit(uint32_t value); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: uint32_t m_resultLimit = 0; Windows::Foundation::Collections::IVector m_selectors{ winrt::single_threaded_vector() }; Windows::Foundation::Collections::IVector m_filters{ winrt::single_threaded_vector() }; +#endif }; } + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct FindPackagesOptions : FindPackagesOptionsT { }; } +#endif diff --git a/src/Microsoft.Management.Deployment/FindPackagesResult.h b/src/Microsoft.Management.Deployment/FindPackagesResult.h index 7b5d2e0b46..fcc9117d21 100644 --- a/src/Microsoft.Management.Deployment/FindPackagesResult.h +++ b/src/Microsoft.Management.Deployment/FindPackagesResult.h @@ -8,19 +8,24 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct FindPackagesResult : FindPackagesResultT { FindPackagesResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize( winrt::Microsoft::Management::Deployment::FindPackagesResultStatus errorCode, bool wasLimitExceeded, Windows::Foundation::Collections::IVector matches); +#endif winrt::Microsoft::Management::Deployment::FindPackagesResultStatus Status(); winrt::Windows::Foundation::Collections::IVectorView Matches(); bool WasLimitExceeded(); +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: winrt::Microsoft::Management::Deployment::FindPackagesResultStatus m_status = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::Ok; Windows::Foundation::Collections::IVector m_matches{ winrt::single_threaded_vector() }; bool m_wasLimitExceeded = false; +#endif }; } diff --git a/src/Microsoft.Management.Deployment/InstallOptions.h b/src/Microsoft.Management.Deployment/InstallOptions.h index e8d3f1eb6a..6e29523907 100644 --- a/src/Microsoft.Management.Deployment/InstallOptions.h +++ b/src/Microsoft.Management.Deployment/InstallOptions.h @@ -33,6 +33,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation hstring AdditionalPackageCatalogArguments(); void AdditionalPackageCatalogArguments(hstring const& value); winrt::Windows::Foundation::Collections::IVector AllowedArchitectures(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: winrt::Microsoft::Management::Deployment::PackageVersionId m_packageVersionId{ nullptr }; std::wstring m_preferredInstallLocation = L""; @@ -45,11 +47,15 @@ namespace winrt::Microsoft::Management::Deployment::implementation std::wstring m_additionalPackageCatalogArguments = L""; Windows::Foundation::Collections::IVector m_allowedArchitectures{ winrt::single_threaded_vector() }; +#endif }; } + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct InstallOptions : InstallOptionsT { }; } +#endif diff --git a/src/Microsoft.Management.Deployment/InstallResult.h b/src/Microsoft.Management.Deployment/InstallResult.h index 1fe4cc02a6..8fc45721e4 100644 --- a/src/Microsoft.Management.Deployment/InstallResult.h +++ b/src/Microsoft.Management.Deployment/InstallResult.h @@ -8,20 +8,26 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct InstallResult : InstallResultT { InstallResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize( winrt::Microsoft::Management::Deployment::InstallResultStatus status, winrt::hresult extendedErrorCode, hstring const& correlationData, bool rebootRequired); +#endif hstring CorrelationData(); bool RebootRequired(); winrt::Microsoft::Management::Deployment::InstallResultStatus Status(); winrt::hresult ExtendedErrorCode(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: std::wstring m_correlationData = L""; bool m_rebootRequired = false; winrt::Microsoft::Management::Deployment::InstallResultStatus m_status = winrt::Microsoft::Management::Deployment::InstallResultStatus::Ok; winrt::hresult m_extendedErrorCode = S_OK; +#endif }; } diff --git a/src/Microsoft.Management.Deployment/MatchResult.h b/src/Microsoft.Management.Deployment/MatchResult.h index 03f5c3ae00..4ee4406aea 100644 --- a/src/Microsoft.Management.Deployment/MatchResult.h +++ b/src/Microsoft.Management.Deployment/MatchResult.h @@ -12,8 +12,11 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Microsoft::Management::Deployment::CatalogPackage CatalogPackage(); winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchCriteria(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: Microsoft::Management::Deployment::CatalogPackage m_catalogPackage{ nullptr }; Microsoft::Management::Deployment::PackageMatchFilter m_matchCriteria{ nullptr }; +#endif }; } diff --git a/src/Microsoft.Management.Deployment/PackageCatalog.h b/src/Microsoft.Management.Deployment/PackageCatalog.h index 1225a332e0..6a8913f3c3 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalog.h +++ b/src/Microsoft.Management.Deployment/PackageCatalog.h @@ -8,19 +8,24 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct PackageCatalog : PackageCatalogT { PackageCatalog() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize( winrt::Microsoft::Management::Deployment::PackageCatalogInfo info, std::shared_ptr source, bool isComposite); +#endif bool IsComposite(); winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); winrt::Windows::Foundation::IAsyncOperation FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options); winrt::Microsoft::Management::Deployment::FindPackagesResult FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: winrt::Microsoft::Management::Deployment::PackageCatalogInfo m_info{ nullptr }; std::shared_ptr m_source; bool m_isComposite = false; - +#endif }; } diff --git a/src/Microsoft.Management.Deployment/PackageCatalogInfo.h b/src/Microsoft.Management.Deployment/PackageCatalogInfo.h index 7b2a503934..8413253187 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalogInfo.h +++ b/src/Microsoft.Management.Deployment/PackageCatalogInfo.h @@ -8,8 +8,11 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct PackageCatalogInfo : PackageCatalogInfoT { PackageCatalogInfo() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(const ::AppInstaller::Repository::SourceDetails& sourceDetails); ::AppInstaller::Repository::SourceDetails GetSourceDetails(); +#endif hstring Id(); hstring Name(); @@ -18,7 +21,10 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Windows::Foundation::DateTime LastUpdateTime(); winrt::Microsoft::Management::Deployment::PackageCatalogOrigin Origin(); winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel TrustLevel(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: ::AppInstaller::Repository::SourceDetails m_sourceDetails{}; +#endif }; } diff --git a/src/Microsoft.Management.Deployment/PackageCatalogReference.h b/src/Microsoft.Management.Deployment/PackageCatalogReference.h index b7384fbd6b..e15669b75a 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalogReference.h +++ b/src/Microsoft.Management.Deployment/PackageCatalogReference.h @@ -8,16 +8,22 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct PackageCatalogReference : PackageCatalogReferenceT { PackageCatalogReference() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(winrt::Microsoft::Management::Deployment::PackageCatalogInfo packageCatalogInfo); void Initialize(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions options); +#endif bool IsComposite(); winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); winrt::Windows::Foundation::IAsyncOperation ConnectAsync(); winrt::Microsoft::Management::Deployment::ConnectResult Connect(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions m_compositePackageCatalogOptions{ nullptr }; winrt::Microsoft::Management::Deployment::PackageCatalogInfo m_info{ nullptr }; bool m_isComposite = false; +#endif }; } diff --git a/src/Microsoft.Management.Deployment/PackageManager.h b/src/Microsoft.Management.Deployment/PackageManager.h index 71cd645004..23a28235c1 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.h +++ b/src/Microsoft.Management.Deployment/PackageManager.h @@ -26,9 +26,12 @@ namespace winrt::Microsoft::Management::Deployment::implementation GetInstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo); }; } + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct PackageManager : PackageManagerT { }; } +#endif diff --git a/src/Microsoft.Management.Deployment/PackageMatchFilter.h b/src/Microsoft.Management.Deployment/PackageMatchFilter.h index 71cd2ba821..e6d25b602b 100644 --- a/src/Microsoft.Management.Deployment/PackageMatchFilter.h +++ b/src/Microsoft.Management.Deployment/PackageMatchFilter.h @@ -13,7 +13,10 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct PackageMatchFilter : PackageMatchFilterT { PackageMatchFilter() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(::AppInstaller::Repository::PackageMatchFilter matchFilter); +#endif winrt::Microsoft::Management::Deployment::PackageFieldMatchOption Option(); void Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value); @@ -21,15 +24,21 @@ namespace winrt::Microsoft::Management::Deployment::implementation void Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value); hstring Value(); void Value(hstring const& value); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: hstring m_value; winrt::Microsoft::Management::Deployment::PackageMatchField m_matchField = winrt::Microsoft::Management::Deployment::PackageMatchField::CatalogDefault; winrt::Microsoft::Management::Deployment::PackageFieldMatchOption m_packageFieldMatchOption = winrt::Microsoft::Management::Deployment::PackageFieldMatchOption::Equals; +#endif }; } + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) namespace winrt::Microsoft::Management::Deployment::factory_implementation { struct PackageMatchFilter : PackageMatchFilterT { }; } +#endif diff --git a/src/Microsoft.Management.Deployment/PackageVersionId.h b/src/Microsoft.Management.Deployment/PackageVersionId.h index 2645d2af92..416314ec6e 100644 --- a/src/Microsoft.Management.Deployment/PackageVersionId.h +++ b/src/Microsoft.Management.Deployment/PackageVersionId.h @@ -8,12 +8,18 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct PackageVersionId : PackageVersionIdT { PackageVersionId() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(::AppInstaller::Repository::PackageVersionKey packageVersionKey); +#endif hstring PackageCatalogId(); hstring Version(); hstring Channel(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: ::AppInstaller::Repository::PackageVersionKey m_packageVersionKey{}; +#endif }; } diff --git a/src/Microsoft.Management.Deployment/PackageVersionInfo.cpp b/src/Microsoft.Management.Deployment/PackageVersionInfo.cpp index aded967238..2f9f3c8292 100644 --- a/src/Microsoft.Management.Deployment/PackageVersionInfo.cpp +++ b/src/Microsoft.Management.Deployment/PackageVersionInfo.cpp @@ -112,4 +112,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation return CompareResult::Equal; } } + std::shared_ptr<::AppInstaller::Repository::IPackageVersion> PackageVersionInfo::GetRepositoryPackageVersion() + { + return m_packageVersion; + } } diff --git a/src/Microsoft.Management.Deployment/PackageVersionInfo.h b/src/Microsoft.Management.Deployment/PackageVersionInfo.h index d929c93e90..d646498ce1 100644 --- a/src/Microsoft.Management.Deployment/PackageVersionInfo.h +++ b/src/Microsoft.Management.Deployment/PackageVersionInfo.h @@ -8,7 +8,11 @@ namespace winrt::Microsoft::Management::Deployment::implementation struct PackageVersionInfo : PackageVersionInfoT { PackageVersionInfo() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(std::shared_ptr<::AppInstaller::Repository::IPackageVersion> packageVersion); + std::shared_ptr<::AppInstaller::Repository::IPackageVersion> GetRepositoryPackageVersion(); +#endif hstring GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField); hstring Id(); @@ -18,12 +22,14 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Windows::Foundation::Collections::IVectorView PackageFamilyNames(); winrt::Windows::Foundation::Collections::IVectorView ProductCodes(); winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); - std::shared_ptr<::AppInstaller::Repository::IPackageVersion> GetRepositoryPackageVersion() { return m_packageVersion; } winrt::Microsoft::Management::Deployment::CompareResult CompareToVersion(hstring versionString); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: winrt::Microsoft::Management::Deployment::PackageCatalog m_packageCatalog{ nullptr }; std::shared_ptr<::AppInstaller::Repository::IPackageVersion> m_packageVersion; Windows::Foundation::Collections::IVector m_packageFamilyNames{ nullptr }; Windows::Foundation::Collections::IVector m_productCodes{ nullptr }; +#endif }; } From fde3252d47049e812c7afd6c4c24938fe7ce2fea Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Tue, 31 Aug 2021 12:54:47 -0700 Subject: [PATCH 26/53] Merge local master to comtesting (#16) * Fix bad merge (#1408) * Add support for rest api 1.1 interface (#1396) Added support for market Added support for source agreements Added support for msstore type Minor changes to workflow ui Next pr will be the manifest v1.1 integration. * Remove the packagedAPI experimental feature flag (#1419) * Integrating custom header with V1.1 changes (#1422) Integrating custom header with V1.1 changes * Expose pass through header through com interface. (#1420) * Add custom header. * Update behavior for composites. * Revert line ending changes. * Add comment. * Update composite behavior. * Fix error code * Update Loggers to support multiple Win32 app installs in single process (#1399) * Update Loggers to support multi threaded processing of Win32 app install requests in WPMServer Co-authored-by: JohnMcPMS Co-authored-by: yao-msft <50888816+yao-msft@users.noreply.github.com> Co-authored-by: Ashwini Patil <47225815+ashpatil-msft@users.noreply.github.com> Co-authored-by: sachintaMSFT <80828309+sachintaMSFT@users.noreply.github.com> --- .github/actions/spelling/allow.txt | 6 + .github/actions/spelling/patterns.txt | 3 + doc/Settings.md | 8 +- .../JSON/settings/settings.schema.0.2.json | 19 +- src/AppInstallerCLI.sln | 8 - src/AppInstallerCLICore/Argument.cpp | 6 +- src/AppInstallerCLICore/COMContext.cpp | 16 +- src/AppInstallerCLICore/COMContext.h | 19 +- src/AppInstallerCLICore/Command.cpp | 18 +- .../Commands/ExportCommand.cpp | 1 + .../Commands/ImportCommand.cpp | 1 + .../Commands/InstallCommand.cpp | 1 + .../Commands/ListCommand.cpp | 1 + .../Commands/SearchCommand.cpp | 1 + .../Commands/ShowCommand.cpp | 3 +- .../Commands/SourceCommand.cpp | 22 +- .../Commands/UninstallCommand.cpp | 1 + .../Commands/UpgradeCommand.cpp | 3 +- .../ContextOrchestrator.cpp | 5 +- src/AppInstallerCLICore/ExecutionArgs.h | 1 + src/AppInstallerCLICore/ExecutionContext.cpp | 6 + src/AppInstallerCLICore/ExecutionContext.h | 7 +- src/AppInstallerCLICore/ExecutionReporter.cpp | 8 +- src/AppInstallerCLICore/ExecutionReporter.h | 1 + src/AppInstallerCLICore/Resources.h | 10 +- .../Workflows/InstallFlow.cpp | 49 ++-- .../Workflows/InstallFlow.h | 10 +- .../Workflows/SourceFlow.cpp | 30 +- .../Workflows/SourceFlow.h | 6 + .../Workflows/WorkflowBase.cpp | 114 ++++++++ .../Workflows/WorkflowBase.h | 20 ++ src/AppInstallerCLIE2ETests/Constants.cs | 7 +- .../FeaturesCommand.cs | 1 - .../Shared/Strings/en-us/winget.resw | 29 +- .../AppInstallerCLITests.vcxproj | 1 + .../AppInstallerCLITests.vcxproj.filters | 3 + src/AppInstallerCLITests/CustomHeader.cpp | 51 +++- src/AppInstallerCLITests/HttpClientHelper.cpp | 10 +- src/AppInstallerCLITests/RestClient.cpp | 144 +++++++++- .../RestInterface_1_0.cpp | 70 +++-- .../RestInterface_1_1.cpp | 270 ++++++++++++++++++ .../SearchRequestSerializer.cpp | 30 +- src/AppInstallerCLITests/WorkFlow.cpp | 118 +++++++- src/AppInstallerCLITests/YamlManifest.cpp | 6 +- src/AppInstallerCLITests/pch.h | 1 + .../AppInstallerCommonCore.vcxproj | 2 + .../AppInstallerCommonCore.vcxproj.filters | 6 + .../AppInstallerLogging.cpp | 21 +- .../AppInstallerStrings.cpp | 8 + .../AppInstallerTelemetry.cpp | 68 ++--- src/AppInstallerCommonCore/Errors.cpp | 14 +- .../ExperimentalFeature.cpp | 4 - .../Manifest/ManifestValidation.cpp | 43 ++- .../Public/AppInstallerErrors.h | 8 +- .../Public/AppInstallerLanguageUtilities.h | 2 +- .../Public/AppInstallerLogging.h | 9 +- .../Public/AppInstallerRuntime.h | 3 + .../Public/AppInstallerStrings.h | 3 + .../Public/AppInstallerTelemetry.h | 29 +- .../Public/winget/ExperimentalFeature.h | 5 +- .../Public/winget/ManifestValidation.h | 5 +- .../Public/winget/ThreadGlobals.h | 48 ++++ .../Public/winget/UserSettings.h | 2 - .../Public/winget/Yaml.h | 1 + src/AppInstallerCommonCore/Runtime.cpp | 6 + .../Telemetry/TraceLogging.cpp | 13 +- .../Telemetry/TraceLogging.h | 5 +- src/AppInstallerCommonCore/ThreadGlobals.cpp | 74 +++++ src/AppInstallerCommonCore/TraceLogger.cpp | 3 +- src/AppInstallerCommonCore/UserSettings.cpp | 1 - src/AppInstallerCommonCore/Yaml.cpp | 7 + src/AppInstallerCommonCore/pch.h | 1 + .../AppInstallerRepositoryCore.vcxproj | 23 +- ...AppInstallerRepositoryCore.vcxproj.filters | 59 ++-- .../CompositeSource.h | 3 + .../Public/AppInstallerRepositorySearch.h | 75 ++--- .../Public/AppInstallerRepositorySource.h | 57 +++- .../RepositorySource.cpp | 233 ++++++++++++++- .../Rest/RestClient.cpp | 64 +++-- .../Rest/RestClient.h | 19 +- .../Rest/RestSource.cpp | 16 +- .../Rest/RestSourceFactory.cpp | 4 +- .../Rest/Schema/1_0/Interface.h | 19 +- .../Schema/1_0/Json/CommonJsonConstants.h | 17 -- .../Json/InformationResponseDeserializer.cpp | 91 ------ .../Schema/1_0/Json/ManifestDeserializer.h | 4 +- ...lizer.cpp => ManifestDeserializer_1_0.cpp} | 162 +++++++---- .../Schema/1_0/Json/SearchRequestSerializer.h | 2 + ...er.cpp => SearchRequestSerializer_1_0.cpp} | 56 ++-- .../1_0/Json/SearchResponseDeserializer.h | 2 +- ...cpp => SearchResponseDeserializer_1_0.cpp} | 2 +- .../{Interface.cpp => RestInterface_1_0.cpp} | 85 ++++-- .../Rest/Schema/1_1/Interface.h | 35 +++ .../Schema/1_1/Json/ManifestDeserializer.h | 17 ++ .../1_1/Json/ManifestDeserializer_1_1.cpp | 42 +++ .../Schema/1_1/Json/SearchRequestSerializer.h | 15 + .../1_1/Json/SearchRequestSerializer_1_1.cpp | 17 ++ .../Rest/Schema/1_1/RestInterface_1_1.cpp | 172 +++++++++++ .../Rest/Schema/CommonRestConstants.h | 13 + .../Rest/{ => Schema}/HttpClientHelper.cpp | 22 +- .../Rest/{ => Schema}/HttpClientHelper.h | 2 +- .../Rest/Schema/IRestClient.h | 17 ++ .../InformationResponseDeserializer.cpp | 136 +++++++++ .../InformationResponseDeserializer.h | 2 +- .../Rest/Schema/RestHelper.cpp | 3 +- .../PackageCatalogInfo.cpp | 2 +- .../PackageCatalogInfo.h | 2 +- .../PackageCatalogReference.cpp | 39 ++- .../PackageCatalogReference.h | 2 + .../PackageManager.cpp | 10 +- .../PackageManager.idl | 6 + src/WinGetServer/WinMain.cpp | 7 - 112 files changed, 2452 insertions(+), 638 deletions(-) create mode 100644 src/AppInstallerCLITests/RestInterface_1_1.cpp create mode 100644 src/AppInstallerCommonCore/Public/winget/ThreadGlobals.h create mode 100644 src/AppInstallerCommonCore/ThreadGlobals.cpp delete mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/CommonJsonConstants.h delete mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/InformationResponseDeserializer.cpp rename src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/{ManifestDeserializer.cpp => ManifestDeserializer_1_0.cpp} (76%) rename src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/{SearchRequestSerializer.cpp => SearchRequestSerializer_1_0.cpp} (84%) rename src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/{SearchResponseDeserializer.cpp => SearchResponseDeserializer_1_0.cpp} (97%) rename src/AppInstallerRepositoryCore/Rest/Schema/1_0/{Interface.cpp => RestInterface_1_0.cpp} (76%) create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_1/Interface.h create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer.h create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer_1_1.cpp create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer.h create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer_1_1.cpp create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_1/RestInterface_1_1.cpp rename src/AppInstallerRepositoryCore/Rest/{ => Schema}/HttpClientHelper.cpp (78%) rename src/AppInstallerRepositoryCore/Rest/{ => Schema}/HttpClientHelper.h (94%) create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.cpp rename src/AppInstallerRepositoryCore/Rest/Schema/{1_0/Json => }/InformationResponseDeserializer.h (87%) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 1fb5a48007..e340400180 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -45,6 +45,7 @@ bytearray cdecl cer certutil +cguid chrono cin cla @@ -79,6 +80,7 @@ cref csproj CStr CURSORPOSITON +CUSTOMHEADER cwctype datatelemetry dbconn @@ -251,7 +253,9 @@ MAKEINTRESOURCE makemsix MANIFESTSCHEMA MANIFESTVERSION +MAXLENGTH MBs +MContext mday memset metadata @@ -293,6 +297,7 @@ NONAME nonexistentsetting NONINFRINGEMENT norestart +normalizednameandpublisher NOTHROW NOTIMPL NOTNULL @@ -316,6 +321,7 @@ outfile OUTOFDISKSPACE OUTOFMEMORY OWC +packagefamilyname PACKAGESSCHEMA Params params diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt index 2495065cdc..9e419885a7 100644 --- a/.github/actions/spelling/patterns.txt +++ b/.github/actions/spelling/patterns.txt @@ -47,3 +47,6 @@ REQUIRE\(RestHelper::GetRestAPIBaseUri\(".*"\) == L".*" # URL escaped characters \%[0-9A-F]{2} + +# Sample store product id for App Installer +9nblggh4nns1 \ No newline at end of file diff --git a/doc/Settings.md b/doc/Settings.md index ab5ac6fc0f..d6c2dcc409 100644 --- a/doc/Settings.md +++ b/doc/Settings.md @@ -137,13 +137,15 @@ Microsoft Store App support in WinGet is currently implemented as an experimenta }, ``` -### packagedAPI +### directMSI -Support in WinGet for packaged callers is currently implemented as an experimental feature. It allows other programs on Windows to use the Windows Package Manager. You can enable the feature as shown below. +This feature enables the Windows Package Manager to directly install MSI packages with the MSI APIs rather than through msiexec. +Note that when silent installation is used this is already in affect, as MSI packages that require elevation will fail in that scenario without it. +You can enable the feature as shown below. ```json "experimentalFeatures": { - "packagedAPI": true + "directMSI": true }, ``` ### Dependencies diff --git a/schemas/JSON/settings/settings.schema.0.2.json b/schemas/JSON/settings/settings.schema.0.2.json index a1a1342b9f..ae22f13e43 100644 --- a/schemas/JSON/settings/settings.schema.0.2.json +++ b/schemas/JSON/settings/settings.schema.0.2.json @@ -119,23 +119,8 @@ "type": "boolean", "default": false }, - "list": { - "description": "Enable the list command while it is in development", - "type": "boolean", - "default": false - }, - "upgrade": { - "description": "Enable the upgrade command while it is in development", - "type": "boolean", - "default": false - }, - "uninstall": { - "description": "Enable the uninstall command while it is in development", - "type": "boolean", - "default": false - }, - "restSource": { - "description": "Enable the rest source support while it is in development", + "directMSI": { + "description": "Enable use of MSI APIs rather than msiexec for MSI installs", "type": "boolean", "default": false } diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index c9da292a79..c82a9c06be 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -501,13 +501,9 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.Build.0 = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM.ActiveCfg = Debug|ARM - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM.Build.0 = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM64.Build.0 = Debug|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x64.ActiveCfg = Debug|x64 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x64.Build.0 = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.Build.0 = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.ActiveCfg = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.Build.0 = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -525,13 +521,9 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.Build.0 = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM.ActiveCfg = Debug|ARM - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM.Build.0 = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM64.Build.0 = Debug|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x64.ActiveCfg = Debug|x64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x64.Build.0 = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.Build.0 = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.ActiveCfg = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.Build.0 = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.ActiveCfg = Release|ARM64 diff --git a/src/AppInstallerCLICore/Argument.cpp b/src/AppInstallerCLICore/Argument.cpp index be579ddde1..71a97e9807 100644 --- a/src/AppInstallerCLICore/Argument.cpp +++ b/src/AppInstallerCLICore/Argument.cpp @@ -78,10 +78,12 @@ namespace AppInstaller::CLI return Argument{ "retro", NoAlias, Args::Type::RetroStyle, Resource::String::RetroArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden }; case Args::Type::VerboseLogs: return Argument{ "verbose-logs", NoAlias, Args::Type::VerboseLogs, Resource::String::VerboseLogsArgumentDescription, ArgumentType::Flag }; - case Args::Type::ExperimentalArg: - return Argument{ "arg", NoAlias, Args::Type::ExperimentalArg, Resource::String::ExperimentalArgumentDescription, ArgumentType::Flag, ExperimentalFeature::Feature::ExperimentalArg }; case Args::Type::CustomHeader: return Argument{ "header", NoAlias, Args::Type::CustomHeader, Resource::String::HeaderArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; + case Args::Type::AcceptSourceAgreements: + return Argument{ "accept-source-agreements", NoAlias, Args::Type::AcceptSourceAgreements, Resource::String::AcceptSourceAgreementsArgumentDescription, ArgumentType::Flag }; + case Args::Type::ExperimentalArg: + return Argument{ "arg", NoAlias, Args::Type::ExperimentalArg, Resource::String::ExperimentalArgumentDescription, ArgumentType::Flag, ExperimentalFeature::Feature::ExperimentalArg }; default: THROW_HR(E_UNEXPECTED); } diff --git a/src/AppInstallerCLICore/COMContext.cpp b/src/AppInstallerCLICore/COMContext.cpp index 63d77b7822..42f35b2b7d 100644 --- a/src/AppInstallerCLICore/COMContext.cpp +++ b/src/AppInstallerCLICore/COMContext.cpp @@ -51,14 +51,18 @@ namespace AppInstaller::CLI::Execution Logging::SetExecutionStage(static_cast(m_executionStage)); } - void COMContext::SetLoggerContext(const std::wstring_view telemetryCorrelationJson, const std::string& caller) + void COMContext::SetContextLoggers(const std::wstring_view telemetryCorrelationJson, const std::string& caller) { m_correlationData = telemetryCorrelationJson; - Logging::Telemetry().SetTelemetryCorrelationJson(telemetryCorrelationJson); - Logging::Telemetry().SetCaller(caller); - Logging::Telemetry().LogStartup(true); + + std::unique_ptr setThreadGlobalsToPreviousState = GetThreadGlobals().SetForCurrentThread(); + + SetLoggers(); + GetThreadGlobals().GetTelemetryLogger().SetTelemetryCorrelationJson(telemetryCorrelationJson); + GetThreadGlobals().GetTelemetryLogger().SetCaller(caller); + GetThreadGlobals().GetTelemetryLogger().LogStartup(true); } - + std::wstring_view COMContext::GetCorrelationJson() { return m_correlationData; @@ -66,7 +70,7 @@ namespace AppInstaller::CLI::Execution void COMContext::SetLoggers() { - Logging::Log().SetLevel(Logging::Level::Verbose); + Logging::Log().SetLevel(Logging::Level::Info); Logging::Log().EnableChannel(Logging::Channel::All); // TODO: Log to file for COM API calls only when debugging in visual studio diff --git a/src/AppInstallerCLICore/COMContext.h b/src/AppInstallerCLICore/COMContext.h index a8a91090e2..75dbf53a62 100644 --- a/src/AppInstallerCLICore/COMContext.h +++ b/src/AppInstallerCLICore/COMContext.h @@ -7,7 +7,7 @@ namespace AppInstaller::CLI::Execution { - enum class ReportType: uint32_t + enum class ReportType : uint32_t { ExecutionPhaseUpdate, BeginProgress, @@ -39,11 +39,13 @@ namespace AppInstaller::CLI::Execution COMContext() : NullStream(), CLI::Execution::Context(*m_nullOut, *m_nullIn) { Reporter.SetProgressSink(this); + SetFlags(CLI::Execution::ContextFlag::AgreementsAcceptedByCaller); } - COMContext(std::ostream& out, std::istream& in) : CLI::Execution::Context(out, in) + COMContext(std::ostream& out, std::istream& in) : CLI::Execution::Context(out, in) { Reporter.SetProgressSink(this); + SetFlags(CLI::Execution::ContextFlag::AgreementsAcceptedByCaller); } ~COMContext() = default; @@ -60,19 +62,18 @@ namespace AppInstaller::CLI::Execution void AddProgressCallbackFunction(ProgressCallBackFunction&& f); - // Set COM call context for diagnostic and telemetry loggers - // This should be called for every COMContext object instance - void SetLoggerContext(const std::wstring_view telemetryCorrelationJson, const std::string& caller); - - std::wstring_view GetCorrelationJson(); - // Set Diagnostic and Telemetry loggers, Wil failure callback // This should be called only once per COM Server instance static void SetLoggers(); + // Set COM call context for diagnostic and telemetry loggers + // This should be called for every COMContext object instance + void SetContextLoggers(const std::wstring_view telemetryCorrelationJson, const std::string& caller); + + std::wstring_view GetCorrelationJson(); + private: void FireCallbacks(ReportType reportType, uint64_t current, uint64_t maximum, ProgressType progressType, ::AppInstaller::CLI::Workflow::ExecutionStage executionPhase); - std::vector GetCallbacks(); CLI::Workflow::ExecutionStage m_executionStage = CLI::Workflow::ExecutionStage::Initial; std::vector m_comProgressCallbacks; diff --git a/src/AppInstallerCLICore/Command.cpp b/src/AppInstallerCLICore/Command.cpp index bdb6cd4a7f..f6dd421b57 100644 --- a/src/AppInstallerCLICore/Command.cpp +++ b/src/AppInstallerCLICore/Command.cpp @@ -12,26 +12,12 @@ using namespace AppInstaller::Settings; namespace AppInstaller::CLI { constexpr std::string_view s_Command_ArgName_SilentAndInteractive = "silent|interactive"sv; - constexpr std::string_view s_CommandException_ReplacementToken = "%1"sv; const Utility::LocIndString CommandException::Message() const { if (m_replace) { - std::string result; - - // Find the %1 in the message - std::string_view message = m_message.get(); - size_t index = message.find(s_CommandException_ReplacementToken); - - if (index != std::string::npos) - { - result = message.substr(0, index); - result += m_replace.value(); - result += message.substr(index + s_CommandException_ReplacementToken.length()); - - return Utility::LocIndString{ std::move(result) }; - } + return Utility::LocIndString{ Utility::FindAndReplaceMessageToken(m_message, m_replace.value()) }; } // Fall back to just using the message. @@ -679,7 +665,7 @@ namespace AppInstaller::CLI if (execArgs.Contains(Execution::Args::Type::CustomHeader) && !execArgs.Contains(Execution::Args::Type::Source) && !execArgs.Contains(Execution::Args::Type::SourceName)) { - throw CommandException(Resource::String::HeaderArgumentNotApplicableWithoutSource, Argument::ForType(Execution::Args::Type::CustomHeader).Name(), {}); + throw CommandException(Resource::String::HeaderArgumentNotApplicableWithoutSource, Argument::ForType(Execution::Args::Type::CustomHeader).Name()); } ValidateArgumentsInternal(execArgs); diff --git a/src/AppInstallerCLICore/Commands/ExportCommand.cpp b/src/AppInstallerCLICore/Commands/ExportCommand.cpp index 0418f3d3c7..d8aa68ab64 100644 --- a/src/AppInstallerCLICore/Commands/ExportCommand.cpp +++ b/src/AppInstallerCLICore/Commands/ExportCommand.cpp @@ -17,6 +17,7 @@ namespace AppInstaller::CLI Argument{ "output", 'o', Execution::Args::Type::OutputFile, Resource::String::OutputFileArgumentDescription, ArgumentType::Positional, true }, Argument{ "source", 's', Execution::Args::Type::Source, Resource::String::ExportSourceArgumentDescription, ArgumentType::Standard }, Argument{ "include-versions", Argument::NoAlias, Execution::Args::Type::IncludeVersions, Resource::String::ExportIncludeVersionsArgumentDescription, ArgumentType::Flag }, + Argument::ForType(Execution::Args::Type::AcceptSourceAgreements), }; } diff --git a/src/AppInstallerCLICore/Commands/ImportCommand.cpp b/src/AppInstallerCLICore/Commands/ImportCommand.cpp index 6c9b33385f..6bc90abe4b 100644 --- a/src/AppInstallerCLICore/Commands/ImportCommand.cpp +++ b/src/AppInstallerCLICore/Commands/ImportCommand.cpp @@ -18,6 +18,7 @@ namespace AppInstaller::CLI Argument{ "ignore-unavailable", Argument::NoAlias, Execution::Args::Type::IgnoreUnavailable, Resource::String::ImportIgnoreUnavailableArgumentDescription, ArgumentType::Flag }, Argument{ "ignore-versions", Argument::NoAlias, Execution::Args::Type::IgnoreVersions, Resource::String::ImportIgnorePackageVersionsArgumentDescription, ArgumentType::Flag }, Argument::ForType(Execution::Args::Type::AcceptPackageAgreements), + Argument::ForType(Execution::Args::Type::AcceptSourceAgreements), }; } diff --git a/src/AppInstallerCLICore/Commands/InstallCommand.cpp b/src/AppInstallerCLICore/Commands/InstallCommand.cpp index 9995e2063c..e7fe58819a 100644 --- a/src/AppInstallerCLICore/Commands/InstallCommand.cpp +++ b/src/AppInstallerCLICore/Commands/InstallCommand.cpp @@ -41,6 +41,7 @@ namespace AppInstaller::CLI Argument::ForType(Args::Type::HashOverride), Argument::ForType(Args::Type::AcceptPackageAgreements), Argument::ForType(Args::Type::CustomHeader), + Argument::ForType(Args::Type::AcceptSourceAgreements), }; } diff --git a/src/AppInstallerCLICore/Commands/ListCommand.cpp b/src/AppInstallerCLICore/Commands/ListCommand.cpp index 21a8995027..256c37caea 100644 --- a/src/AppInstallerCLICore/Commands/ListCommand.cpp +++ b/src/AppInstallerCLICore/Commands/ListCommand.cpp @@ -23,6 +23,7 @@ namespace AppInstaller::CLI Argument::ForType(Execution::Args::Type::Count), Argument::ForType(Execution::Args::Type::Exact), Argument::ForType(Execution::Args::Type::CustomHeader), + Argument::ForType(Execution::Args::Type::AcceptSourceAgreements), }; } diff --git a/src/AppInstallerCLICore/Commands/SearchCommand.cpp b/src/AppInstallerCLICore/Commands/SearchCommand.cpp index 8bbbd2cdd7..15178d3c9a 100644 --- a/src/AppInstallerCLICore/Commands/SearchCommand.cpp +++ b/src/AppInstallerCLICore/Commands/SearchCommand.cpp @@ -24,6 +24,7 @@ namespace AppInstaller::CLI Argument::ForType(Execution::Args::Type::Count), Argument::ForType(Execution::Args::Type::Exact), Argument::ForType(Execution::Args::Type::CustomHeader), + Argument::ForType(Execution::Args::Type::AcceptSourceAgreements), }; } diff --git a/src/AppInstallerCLICore/Commands/ShowCommand.cpp b/src/AppInstallerCLICore/Commands/ShowCommand.cpp index 4d573ce106..40c58f8d7b 100644 --- a/src/AppInstallerCLICore/Commands/ShowCommand.cpp +++ b/src/AppInstallerCLICore/Commands/ShowCommand.cpp @@ -7,8 +7,6 @@ #include "Workflows/WorkflowBase.h" #include "Resources.h" -using namespace AppInstaller::CLI::Execution; - namespace AppInstaller::CLI { std::vector ShowCommand::GetArguments() const @@ -26,6 +24,7 @@ namespace AppInstaller::CLI Argument::ForType(Execution::Args::Type::Exact), Argument::ForType(Execution::Args::Type::ListVersions), Argument::ForType(Execution::Args::Type::CustomHeader), + Argument::ForType(Execution::Args::Type::AcceptSourceAgreements), }; } diff --git a/src/AppInstallerCLICore/Commands/SourceCommand.cpp b/src/AppInstallerCLICore/Commands/SourceCommand.cpp index beb81dbc51..f11890f33b 100644 --- a/src/AppInstallerCLICore/Commands/SourceCommand.cpp +++ b/src/AppInstallerCLICore/Commands/SourceCommand.cpp @@ -53,6 +53,7 @@ namespace AppInstaller::CLI Argument::ForType(Args::Type::SourceArg), Argument::ForType(Args::Type::SourceType), Argument::ForType(Args::Type::CustomHeader), + Argument::ForType(Args::Type::AcceptSourceAgreements), }; } @@ -79,7 +80,26 @@ namespace AppInstaller::CLI Workflow::EnsureRunningAsAdmin << Workflow::GetSourceList << Workflow::CheckSourceListAgainstAdd << - Workflow::AddSource; + // TODO: Could improve the workflow by opening the source before adding during ISource refactoring work + Workflow::AddSource << + Workflow::OpenSourceForSourceAdd; + + if (context.IsTerminated() && + (context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED || + context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED)) + { + auto contextForRemovePtr = context.Clone(); + Context& contextForRemove = *contextForRemovePtr; + contextForRemove.Args.AddArg(Args::Type::SourceName, context.Args.GetArg(Args::Type::SourceName)); + + contextForRemove << + Workflow::GetSourceListWithFilter << + Workflow::RemoveSources; + } + else + { + context.Reporter.Info() << Resource::String::Done << std::endl; + } } std::vector SourceListCommand::GetArguments() const diff --git a/src/AppInstallerCLICore/Commands/UninstallCommand.cpp b/src/AppInstallerCLICore/Commands/UninstallCommand.cpp index bac721c70f..93fcf92124 100644 --- a/src/AppInstallerCLICore/Commands/UninstallCommand.cpp +++ b/src/AppInstallerCLICore/Commands/UninstallCommand.cpp @@ -31,6 +31,7 @@ namespace AppInstaller::CLI Argument::ForType(Args::Type::Silent), Argument::ForType(Args::Type::Log), Argument::ForType(Args::Type::CustomHeader), + Argument::ForType(Args::Type::AcceptSourceAgreements), }; } diff --git a/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp b/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp index 72c0003535..fd1c00bbc6 100644 --- a/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp +++ b/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp @@ -43,8 +43,9 @@ namespace AppInstaller::CLI Argument::ForType(Args::Type::InstallLocation), Argument::ForType(Args::Type::HashOverride), Argument::ForType(Args::Type::AcceptPackageAgreements), - Argument{ "all", Argument::NoAlias, Args::Type::All, Resource::String::UpdateAllArgumentDescription, ArgumentType::Flag }, + Argument::ForType(Args::Type::AcceptSourceAgreements), Argument::ForType(Execution::Args::Type::CustomHeader), + Argument{ "all", Argument::NoAlias, Args::Type::All, Resource::String::UpdateAllArgumentDescription, ArgumentType::Flag }, }; } diff --git a/src/AppInstallerCLICore/ContextOrchestrator.cpp b/src/AppInstallerCLICore/ContextOrchestrator.cpp index c6a28c367a..f9876d4bcb 100644 --- a/src/AppInstallerCLICore/ContextOrchestrator.cpp +++ b/src/AppInstallerCLICore/ContextOrchestrator.cpp @@ -102,8 +102,11 @@ namespace AppInstaller::CLI::Execution try { ::AppInstaller::CLI::RootCommand rootCommand; + + std::unique_ptr setThreadGlobalsToPreviousState = item->GetContext().GetThreadGlobals().SetForCurrentThread(); + std::unique_ptr<::AppInstaller::CLI::Command> command = std::make_unique<::AppInstaller::CLI::COMInstallCommand>(rootCommand.Name()); - ::AppInstaller::Logging::Telemetry().LogCommand(command->FullName()); + item->GetContext().GetThreadGlobals().GetTelemetryLogger().LogCommand(command->FullName()); command->ValidateArguments(item->GetContext().Args); item->GetContext().EnableCtrlHandler(); diff --git a/src/AppInstallerCLICore/ExecutionArgs.h b/src/AppInstallerCLICore/ExecutionArgs.h index 01d8295f29..5bdb18d611 100644 --- a/src/AppInstallerCLICore/ExecutionArgs.h +++ b/src/AppInstallerCLICore/ExecutionArgs.h @@ -78,6 +78,7 @@ namespace AppInstaller::CLI::Execution Info, // Show general info about WinGet VerboseLogs, // Increases winget logging level to verbose CustomHeader, // Optional Rest source header + AcceptSourceAgreements, // Accept all source agreements // Used for demonstration purposes ExperimentalArg, diff --git a/src/AppInstallerCLICore/ExecutionContext.cpp b/src/AppInstallerCLICore/ExecutionContext.cpp index 85acd26337..6304ddee95 100644 --- a/src/AppInstallerCLICore/ExecutionContext.cpp +++ b/src/AppInstallerCLICore/ExecutionContext.cpp @@ -205,4 +205,10 @@ namespace AppInstaller::CLI::Execution m_executionStage = stage; Logging::SetExecutionStage(static_cast(m_executionStage)); } + + AppInstaller::ThreadLocalStorage::ThreadGlobals& Context::GetThreadGlobals() + { + return m_threadGlobals; + } + } diff --git a/src/AppInstallerCLICore/ExecutionContext.h b/src/AppInstallerCLICore/ExecutionContext.h index bd4a0f4426..3594a91a75 100644 --- a/src/AppInstallerCLICore/ExecutionContext.h +++ b/src/AppInstallerCLICore/ExecutionContext.h @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #pragma once -#include +#include "winget/ThreadGlobals.h" #include "ExecutionReporter.h" #include "ExecutionArgs.h" #include "ExecutionContextData.h" @@ -54,6 +54,7 @@ namespace AppInstaller::CLI::Execution InstallerExecutionUseUpdate = 0x1, InstallerHashMatched = 0x2, InstallerTrusted = 0x4, + AgreementsAcceptedByCaller = 0x8, }; DEFINE_ENUM_FLAG_OPERATORS(ContextFlag); @@ -122,6 +123,9 @@ namespace AppInstaller::CLI::Execution virtual void SetExecutionStage(Workflow::ExecutionStage stage, bool); + // Get Globals for Current Thread + AppInstaller::ThreadLocalStorage::ThreadGlobals& GetThreadGlobals(); + #ifndef AICLI_DISABLE_TEST_HOOKS // Enable tests to override behavior virtual bool ShouldExecuteWorkflowTask(const Workflow::WorkflowTask&) { return true; } @@ -134,5 +138,6 @@ namespace AppInstaller::CLI::Execution size_t m_CtrlSignalCount = 0; ContextFlag m_flags = ContextFlag::None; Workflow::ExecutionStage m_executionStage = Workflow::ExecutionStage::Initial; + AppInstaller::ThreadLocalStorage::ThreadGlobals m_threadGlobals; }; } diff --git a/src/AppInstallerCLICore/ExecutionReporter.cpp b/src/AppInstallerCLICore/ExecutionReporter.cpp index 900a0e8acb..cdf7e46a31 100644 --- a/src/AppInstallerCLICore/ExecutionReporter.cpp +++ b/src/AppInstallerCLICore/ExecutionReporter.cpp @@ -12,6 +12,7 @@ namespace AppInstaller::CLI::Execution const Sequence& HelpCommandEmphasis = TextFormat::Foreground::Bright; const Sequence& HelpArgumentEmphasis = TextFormat::Foreground::Bright; const Sequence& ManifestInfoEmphasis = TextFormat::Foreground::Bright; + const Sequence& SourceInfoEmphasis = TextFormat::Foreground::Bright; const Sequence& NameEmphasis = TextFormat::Foreground::BrightCyan; const Sequence& IdEmphasis = TextFormat::Foreground::BrightCyan; const Sequence& UrlEmphasis = TextFormat::Foreground::BrightBlue; @@ -103,7 +104,6 @@ namespace AppInstaller::CLI::Execution bool Reporter::PromptForBoolResponse(Resource::LocString message, Level level) { - bool defaultResponse = false; const std::vector options { BoolPromptOption{ Resource::String::PromptOptionYes, 'Y', true }, @@ -138,12 +138,6 @@ namespace AppInstaller::CLI::Execution THROW_HR(APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR); } - // If response was empty, use the default - if (Utility::IsEmptyOrWhitespace(response)) - { - return defaultResponse; - } - // Find the matching option ignoring whitespace Utility::Trim(response); for (const auto& option : options) diff --git a/src/AppInstallerCLICore/ExecutionReporter.h b/src/AppInstallerCLICore/ExecutionReporter.h index 3e6f86a0db..f5e257f034 100644 --- a/src/AppInstallerCLICore/ExecutionReporter.h +++ b/src/AppInstallerCLICore/ExecutionReporter.h @@ -159,6 +159,7 @@ namespace AppInstaller::CLI::Execution extern const VirtualTerminal::Sequence& HelpCommandEmphasis; extern const VirtualTerminal::Sequence& HelpArgumentEmphasis; extern const VirtualTerminal::Sequence& ManifestInfoEmphasis; + extern const VirtualTerminal::Sequence& SourceInfoEmphasis; extern const VirtualTerminal::Sequence& NameEmphasis; extern const VirtualTerminal::Sequence& IdEmphasis; extern const VirtualTerminal::Sequence& UrlEmphasis; diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h index 41331d9474..8f99444616 100644 --- a/src/AppInstallerCLICore/Resources.h +++ b/src/AppInstallerCLICore/Resources.h @@ -20,6 +20,7 @@ namespace AppInstaller::CLI::Resource struct String { WINGET_DEFINE_RESOURCE_STRINGID(AcceptPackageAgreementsArgumentDescription); + WINGET_DEFINE_RESOURCE_STRINGID(AcceptSourceAgreementsArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(AdjoinedNotFlagError); WINGET_DEFINE_RESOURCE_STRINGID(AdjoinedNotFoundError); WINGET_DEFINE_RESOURCE_STRINGID(AvailableArguments); @@ -115,8 +116,6 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(InvalidJsonFile); WINGET_DEFINE_RESOURCE_STRINGID(InvalidNameError); WINGET_DEFINE_RESOURCE_STRINGID(LicenseAgreement); - WINGET_DEFINE_RESOURCE_STRINGID(LicenseAgreementPrompt); - WINGET_DEFINE_RESOURCE_STRINGID(LicenseNotAgreedTo); WINGET_DEFINE_RESOURCE_STRINGID(Links); WINGET_DEFINE_RESOURCE_STRINGID(ListCommandLongDescription); WINGET_DEFINE_RESOURCE_STRINGID(ListCommandShortDescription); @@ -159,6 +158,8 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(OutputFileArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(OverrideArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(Package); + WINGET_DEFINE_RESOURCE_STRINGID(PackageAgreementsNotAgreedTo); + WINGET_DEFINE_RESOURCE_STRINGID(PackageAgreementsPrompt); WINGET_DEFINE_RESOURCE_STRINGID(PackageDependencies); WINGET_DEFINE_RESOURCE_STRINGID(PendingWorkError); WINGET_DEFINE_RESOURCE_STRINGID(PoliciesDisabled); @@ -215,6 +216,11 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(SourceAddBegin); WINGET_DEFINE_RESOURCE_STRINGID(SourceAddCommandLongDescription); WINGET_DEFINE_RESOURCE_STRINGID(SourceAddCommandShortDescription); + WINGET_DEFINE_RESOURCE_STRINGID(SourceAddOpenSourceFailed); + WINGET_DEFINE_RESOURCE_STRINGID(SourceAgreementsMarketMessage); + WINGET_DEFINE_RESOURCE_STRINGID(SourceAgreementsNotAgreedTo); + WINGET_DEFINE_RESOURCE_STRINGID(SourceAgreementsPrompt); + WINGET_DEFINE_RESOURCE_STRINGID(SourceAgreementsTitle); WINGET_DEFINE_RESOURCE_STRINGID(SourceArgArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(SourceArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(SourceCommandLongDescription); diff --git a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp index 073aa62fc0..5ff027074f 100644 --- a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp @@ -83,7 +83,7 @@ namespace AppInstaller::CLI::Workflow } } - void ShowLicenseAgreements::operator()(Execution::Context& context) const + void ShowPackageAgreements::operator()(Execution::Context& context) const { const auto& manifest = context.Get(); auto agreements = manifest.CurrentLocalization.Get(); @@ -99,40 +99,46 @@ namespace AppInstaller::CLI::Workflow if (m_ensureAcceptance) { - context << Workflow::EnsureLicenseAcceptance(/* showPrompt */ true); + context << Workflow::EnsurePackageAgreementsAcceptance(/* showPrompt */ true); } } - void EnsureLicenseAcceptance::operator()(Execution::Context& context) const + void EnsurePackageAgreementsAcceptance::operator()(Execution::Context& context) const { + if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::AgreementsAcceptedByCaller)) + { + AICLI_LOG(CLI, Info, << "Skipping package agreements acceptance check because AgreementsAcceptedByCaller flag is set."); + return; + } + if (context.Args.Contains(Execution::Args::Type::AcceptPackageAgreements)) { - AICLI_LOG(CLI, Info, << "License agreements accepted by CLI flag"); + AICLI_LOG(CLI, Info, << "Package agreements accepted by CLI flag"); return; } if (m_showPrompt) { - bool accepted = context.Reporter.PromptForBoolResponse(Resource::String::LicenseAgreementPrompt); + bool accepted = context.Reporter.PromptForBoolResponse(Resource::String::PackageAgreementsPrompt); if (accepted) { - AICLI_LOG(CLI, Info, << "License agreements accepted in prompt"); + AICLI_LOG(CLI, Info, << "Package agreements accepted in prompt"); return; } else { - AICLI_LOG(CLI, Info, << "License agreements not accepted in prompt"); + AICLI_LOG(CLI, Info, << "Package agreements not accepted in prompt"); } } - AICLI_LOG(CLI, Error, << "License not agreed to."); - context.Reporter.Error() << Resource::String::LicenseNotAgreedTo << std::endl; - AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_LICENSE_NOT_ACCEPTED); + AICLI_LOG(CLI, Error, << "Package agreements were not agreed to."); + context.Reporter.Error() << Resource::String::PackageAgreementsNotAgreedTo << std::endl; + AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED); } - void EnsureLicenseAcceptanceForMultipleInstallers(Execution::Context& context) + void EnsurePackageAgreementsAcceptanceForMultipleInstallers(Execution::Context& context) { - bool hasLicenseAgreements = false; + bool hasPackageAgreements = false; for (auto package : context.Get()) { // Show agreements for each package in a sub-context @@ -142,20 +148,20 @@ namespace AppInstaller::CLI::Workflow showContext.Add(package.Manifest); showContext << - Workflow::ReportManifestIdentity << - Workflow::ShowLicenseAgreements(/* ensureAcceptance */ false); + Workflow::ReportManifestIdentityWithVersion << + Workflow::ShowPackageAgreements(/* ensureAcceptance */ false); if (showContext.IsTerminated()) { AICLI_TERMINATE_CONTEXT(showContext.GetTerminationHR()); } - hasLicenseAgreements |= !package.Manifest.CurrentLocalization.Get().empty(); + hasPackageAgreements |= !package.Manifest.CurrentLocalization.Get().empty(); } // If any package has agreements, ensure they are accepted - if (hasLicenseAgreements) + if (hasPackageAgreements) { - context << Workflow::EnsureLicenseAcceptance(/* showPrompt */ false); + context << Workflow::EnsurePackageAgreementsAcceptance(/* showPrompt */ false); } } @@ -507,7 +513,7 @@ namespace AppInstaller::CLI::Workflow void ReportIdentityAndInstallationDisclaimer(Execution::Context& context) { context << - Workflow::ReportManifestIdentity << + Workflow::ReportManifestIdentityWithVersion << Workflow::ShowInstallationDisclaimer; } @@ -529,7 +535,7 @@ namespace AppInstaller::CLI::Workflow { context << Workflow::ReportIdentityAndInstallationDisclaimer << - Workflow::ShowLicenseAgreements(/* ensureAcceptance */ true) << + Workflow::ShowPackageAgreements(/* ensureAcceptance */ true) << Workflow::GetDependenciesFromInstaller << Workflow::ReportDependencies(Resource::String::InstallAndUpgradeCommandsReportDependencies) << Workflow::InstallPackageInstaller; @@ -538,7 +544,7 @@ namespace AppInstaller::CLI::Workflow void InstallMultiplePackages::operator()(Execution::Context& context) const { // Show all license agreements before installing anything - context << Workflow::EnsureLicenseAcceptanceForMultipleInstallers; + context << Workflow::EnsurePackageAgreementsAcceptanceForMultipleInstallers; if (context.IsTerminated()) { return; @@ -576,8 +582,7 @@ namespace AppInstaller::CLI::Workflow installContext.Add(package.Installer); installContext << - Workflow::ReportManifestIdentity << - Workflow::ShowInstallationDisclaimer << + Workflow::ReportIdentityAndInstallationDisclaimer << Workflow::InstallPackageInstaller; installContext.Reporter.Info() << std::endl; diff --git a/src/AppInstallerCLICore/Workflows/InstallFlow.h b/src/AppInstallerCLICore/Workflows/InstallFlow.h index 887821d431..bcc7d09dfd 100644 --- a/src/AppInstallerCLICore/Workflows/InstallFlow.h +++ b/src/AppInstallerCLICore/Workflows/InstallFlow.h @@ -27,9 +27,9 @@ namespace AppInstaller::CLI::Workflow // Required Args: None // Inputs: Manifest // Outputs: None - struct ShowLicenseAgreements : public WorkflowTask + struct ShowPackageAgreements : public WorkflowTask { - ShowLicenseAgreements(bool ensureAcceptance) : WorkflowTask("ShowLicenseAgreements"), m_ensureAcceptance(ensureAcceptance) {} + ShowPackageAgreements(bool ensureAcceptance) : WorkflowTask("ShowPackageAgreements"), m_ensureAcceptance(ensureAcceptance) {} void operator()(Execution::Context& context) const override; @@ -42,9 +42,9 @@ namespace AppInstaller::CLI::Workflow // Required Args: None // Inputs: None // Outputs: None - struct EnsureLicenseAcceptance : public WorkflowTask + struct EnsurePackageAgreementsAcceptance : public WorkflowTask { - EnsureLicenseAcceptance(bool showPrompt) : WorkflowTask("EnsureLicenseAcceptance"), m_showPrompt(showPrompt) {} + EnsurePackageAgreementsAcceptance(bool showPrompt) : WorkflowTask("EnsurePackageAgreementsAcceptance"), m_showPrompt(showPrompt) {} void operator()(Execution::Context& context) const override; @@ -58,7 +58,7 @@ namespace AppInstaller::CLI::Workflow // Required Args: None // Inputs: PackagesToInstall // Outputs: None - void EnsureLicenseAcceptanceForMultipleInstallers(Execution::Context& context); + void EnsurePackageAgreementsAcceptanceForMultipleInstallers(Execution::Context& context); // Composite flow that chooses what to do based on the installer type. // Required Args: None diff --git a/src/AppInstallerCLICore/Workflows/SourceFlow.cpp b/src/AppInstallerCLICore/Workflows/SourceFlow.cpp index f9b990f052..99cab18554 100644 --- a/src/AppInstallerCLICore/Workflows/SourceFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/SourceFlow.cpp @@ -90,19 +90,37 @@ namespace AppInstaller::CLI::Workflow sourceDetails.Type = context.Args.GetArg(Args::Type::SourceType); } - sourceDetails.CustomHeader = GetCustomHeaderFromArg(context, sourceDetails); - context.Reporter.Info() << Resource::String::SourceAddBegin << std::endl << " "_liv << sourceDetails.Name << " -> "_liv << sourceDetails.Arg << std::endl; - if (context.Reporter.ExecuteWithProgress(std::bind(Repository::AddSource, sourceDetails, std::placeholders::_1))) + if (!context.Reporter.ExecuteWithProgress(std::bind(Repository::AddSource, sourceDetails, std::placeholders::_1))) { - context.Reporter.Info() << Resource::String::Done; + context.Reporter.Info() << Resource::String::Cancelled << std::endl; } - else + } + + void OpenSourceForSourceAdd(Execution::Context& context) + { + try { - context.Reporter.Info() << Resource::String::Cancelled << std::endl; + auto sourceDetails = Repository::GetSource(context.Args.GetArg(Args::Type::SourceName)); + sourceDetails.value().CustomHeader = GetCustomHeaderFromArg(context, sourceDetails.value()); + + auto result = context.Reporter.ExecuteWithProgress(std::bind(Repository::OpenSourceFromDetails, sourceDetails.value(), std::placeholders::_1), true); + + if (!result.Source) + { + context.Reporter.Error() << Resource::String::SourceAddOpenSourceFailed; + AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED); + } + + context << Workflow::HandleSourceAgreements(result.Source); + } + catch (...) + { + context.Reporter.Error() << Resource::String::SourceAddOpenSourceFailed << std::endl; + AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED); } } diff --git a/src/AppInstallerCLICore/Workflows/SourceFlow.h b/src/AppInstallerCLICore/Workflows/SourceFlow.h index c5abe42f22..af00829cab 100644 --- a/src/AppInstallerCLICore/Workflows/SourceFlow.h +++ b/src/AppInstallerCLICore/Workflows/SourceFlow.h @@ -30,6 +30,12 @@ namespace AppInstaller::CLI::Workflow // Outputs: None void AddSource(Execution::Context& context); + // Opens a source before source add command. + // Required Args: None + // Inputs: None + // Outputs: Source + void OpenSourceForSourceAdd(Execution::Context& context); + // Lists the sources in SourceList. // Required Args: None // Inputs: SourceList diff --git a/src/AppInstallerCLICore/Workflows/WorkflowBase.cpp b/src/AppInstallerCLICore/Workflows/WorkflowBase.cpp index 6acd0e02a0..636198d844 100644 --- a/src/AppInstallerCLICore/Workflows/WorkflowBase.cpp +++ b/src/AppInstallerCLICore/Workflows/WorkflowBase.cpp @@ -136,6 +136,70 @@ namespace AppInstaller::CLI::Workflow searchRequest.MaximumResults = std::stoi(std::string(args.GetArg(Execution::Args::Type::Count))); } } + + bool HandleSourceAgreementsForOneSource(Execution::Context& context, const SourceDetails& source) + { + AICLI_LOG(CLI, Verbose, << "Checking Source agreements for source: " << source.Name); + + if (CheckSourceAgreements(source)) + { + AICLI_LOG(CLI, Verbose, << "Source agreements satisfied. Source: " << source.Name); + return true; + } + + // Show source agreements + std::string agreementsTitleMessage = Resource::LocString{ Resource::String::SourceAgreementsTitle }; + context.Reporter.Info() << Execution::SourceInfoEmphasis << + Utility::LocIndString{ Utility::FindAndReplaceMessageToken(agreementsTitleMessage, source.Name) } << std::endl; + + const auto& agreements = source.Information.SourceAgreements; + + for (const auto& agreement : agreements) + { + if (!agreement.Label.empty()) + { + context.Reporter.Info() << Execution::SourceInfoEmphasis << Utility::LocIndString{ agreement.Label } << " "; + } + + if (!agreement.Text.empty()) + { + context.Reporter.Info() << Utility::LocIndString{ agreement.Text } << std::endl; + } + + if (!agreement.Url.empty()) + { + context.Reporter.Info() << Utility::LocIndString{ agreement.Url } << std::endl; + } + } + + // Show message for each individual implicit agreement field + auto fields = GetAgreementFieldsFromSourceInformation(source.Information); + if (WI_IsFlagSet(fields, ImplicitAgreementFieldEnum::Market)) + { + context.Reporter.Info() << Resource::String::SourceAgreementsMarketMessage << std::endl; + } + + context.Reporter.Info() << std::endl; + + bool accepted = context.Args.Contains(Execution::Args::Type::AcceptSourceAgreements); + + if (!accepted) + { + accepted = context.Reporter.PromptForBoolResponse(Resource::String::SourceAgreementsPrompt); + } + + if (accepted) + { + AICLI_LOG(CLI, Verbose, << "Source agreements accepted. Source: " << source.Name); + SaveAcceptedSourceAgreements(source); + } + else + { + AICLI_LOG(CLI, Verbose, << "Source agreements rejected. Source: " << source.Name); + } + + return accepted; + } } bool WorkflowTask::operator==(const WorkflowTask& other) const @@ -174,6 +238,12 @@ namespace AppInstaller::CLI::Workflow return; } + context << HandleSourceAgreements(source); + if (context.IsTerminated()) + { + return; + } + context.Add(std::move(source)); } @@ -185,6 +255,12 @@ namespace AppInstaller::CLI::Workflow return; } + context << HandleSourceAgreements(source); + if (context.IsTerminated()) + { + return; + } + if (!context.Contains(Execution::Data::Sources)) { context.Add({ std::move(source) }); @@ -667,6 +743,12 @@ namespace AppInstaller::CLI::Workflow } void ReportManifestIdentity(Execution::Context& context) + { + const auto& manifest = context.Get(); + ReportIdentity(context, manifest.CurrentLocalization.Get(), manifest.Id); + } + + void ReportManifestIdentityWithVersion(Execution::Context& context) { const auto& manifest = context.Get(); ReportIdentity(context, manifest.CurrentLocalization.Get(), manifest.Id, manifest.Version); @@ -789,6 +871,38 @@ namespace AppInstaller::CLI::Workflow { context.SetExecutionStage(m_stage, m_allowBackward); } + + void HandleSourceAgreements::operator()(Execution::Context& context) const + { + if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::AgreementsAcceptedByCaller)) + { + AICLI_LOG(CLI, Info, << "Skipping source agreements acceptance check because AgreementsAcceptedByCaller flag is set."); + return; + } + + bool allAccepted = true; + + if (m_source->IsComposite()) + { + for (auto const& source : m_source->GetAvailableSources()) + { + if (!HandleSourceAgreementsForOneSource(context, source->GetDetails())) + { + allAccepted = false; + } + } + } + else + { + allAccepted = HandleSourceAgreementsForOneSource(context, m_source->GetDetails()); + } + + if (!allAccepted) + { + context.Reporter.Error() << Resource::String::SourceAgreementsNotAgreedTo << std::endl; + AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED); + } + } } AppInstaller::CLI::Execution::Context& operator<<(AppInstaller::CLI::Execution::Context& context, AppInstaller::CLI::Workflow::WorkflowTask::Func f) diff --git a/src/AppInstallerCLICore/Workflows/WorkflowBase.h b/src/AppInstallerCLICore/Workflows/WorkflowBase.h index add49d1bb4..2a7a976964 100644 --- a/src/AppInstallerCLICore/Workflows/WorkflowBase.h +++ b/src/AppInstallerCLICore/Workflows/WorkflowBase.h @@ -277,6 +277,12 @@ namespace AppInstaller::CLI::Workflow // Outputs: None void ReportManifestIdentity(Execution::Context& context); + // Reports the manifest's identity with version. + // Required Args: None + // Inputs: Manifest + // Outputs: None + void ReportManifestIdentityWithVersion(Execution::Context& context); + // Composite flow that produces a manifest; either from one given on the command line or by searching. // Required Args: None // Inputs: None @@ -339,6 +345,20 @@ namespace AppInstaller::CLI::Workflow ExecutionStage m_stage; bool m_allowBackward; }; + + // Handles all opened source(s) agreements if needed. + // Required Args: The source to be checked for agreements + // Inputs: None + // Outputs: None + struct HandleSourceAgreements : public WorkflowTask + { + HandleSourceAgreements(std::shared_ptr source) : WorkflowTask("HandleSourceAgreements"), m_source(std::move(source)) {} + + void operator()(Execution::Context& context) const override; + + private: + std::shared_ptr m_source; + }; } // Passes the context to the function if it has not been terminated; returns the context. diff --git a/src/AppInstallerCLIE2ETests/Constants.cs b/src/AppInstallerCLIE2ETests/Constants.cs index eb56f2bdd5..af96d7a734 100644 --- a/src/AppInstallerCLIE2ETests/Constants.cs +++ b/src/AppInstallerCLIE2ETests/Constants.cs @@ -131,8 +131,13 @@ public class ErrorCode public const int ERROR_RESTSOURCE_INVALID_VERSION = unchecked((int)0x8a15003E); public const int ERROR_SOURCE_DATA_INTEGRITY_FAILURE = unchecked((int)0x8a15003F); public const int ERROR_STREAM_READ_FAILURE = unchecked((int)0x8a150040); - public const int ERROR_LICENSE_NOT_ACCEPTED = unchecked((int)0x8a150041); + public const int ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED = unchecked((int)0x8a150041); public const int ERROR_PROMPT_INPUT_ERROR = unchecked((int)0x8a150042); + public const int ERROR_UNSUPPORTED_SOURCE_REQUEST = unchecked((int)0x8a150043); + public const int ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND = unchecked((int)0x8a150044); + public const int ERROR_SOURCE_OPEN_FAILED = unchecked((int)0x8a150045); + public const int ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED = unchecked((int)0x8a150046); + public const int ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH = unchecked((int)0x8a150047); } } } diff --git a/src/AppInstallerCLIE2ETests/FeaturesCommand.cs b/src/AppInstallerCLIE2ETests/FeaturesCommand.cs index a59f091470..237a8e014d 100644 --- a/src/AppInstallerCLIE2ETests/FeaturesCommand.cs +++ b/src/AppInstallerCLIE2ETests/FeaturesCommand.cs @@ -38,7 +38,6 @@ public void EnableExperimentalFeatures() ConfigureFeature("experimentalArg", true); ConfigureFeature("experimentalCmd", true); ConfigureFeature("experimentalMSStore", true); - ConfigureFeature("packagedAPI", true); var result = TestCommon.RunAICLICommand("features", ""); Assert.True(result.StdOut.Contains("Enabled")); } diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw index 2e0d477ebf..44dd843078 100644 --- a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw +++ b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -961,12 +961,12 @@ Configuration is disabled due to Group Policy. Exported package requires license agreement to install: - - The publisher requires that you view the following information and accept the EULA before installing. + + The publisher requires that you view the above information and accept the agreements before installing. Do you agree to the terms? - - License not agreed to. Installation cancelled. + + Package agreements were not agreed to. Operation cancelled. Agreements: @@ -1019,6 +1019,25 @@ Do you agree to the terms? Yes + + Failed to open the added source. + + + Accept all source agreements during source operations + + + The `%1` source requires that you view the following agreements before using. + {Locked="%1"} The value will be replaced with the source name + + + Do you agree to all the source agreements terms? + + + One or more of the source agreements were not agreed to. Operation cancelled. Please accept the source agreements or remove the corresponding sources. + + + The source requires current machine's geographic region to be sent to function properly. + Successfully installed. Restart the application to complete the upgrade. @@ -1029,6 +1048,6 @@ Do you agree to the terms? Ignoring the optional header as it is not applicable for this source. - The optional header is not applicable without specifying a Rest source + The optional header is not applicable without specifying a source \ No newline at end of file diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj index 0b17df13c8..0c2f95b854 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj @@ -205,6 +205,7 @@ + diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters index 240870f9b2..c5773504d7 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters @@ -170,6 +170,9 @@ Source Files + + Source Files + diff --git a/src/AppInstallerCLITests/CustomHeader.cpp b/src/AppInstallerCLITests/CustomHeader.cpp index e07c2bc00d..9741b197c5 100644 --- a/src/AppInstallerCLITests/CustomHeader.cpp +++ b/src/AppInstallerCLITests/CustomHeader.cpp @@ -6,7 +6,7 @@ #include "TestSettings.h" #include "TestSource.h" #include "TestRestRequestHandler.h" -#include +#include #include #include #include @@ -161,3 +161,52 @@ TEST_CASE("CreateSource_CustomHeaderNotApplicable", "[RestSource][CustomHeader]" auto source = OpenSourceFromDetails(details, progress).Source; REQUIRE(!source.get()->GetDetails().CustomHeader.has_value()); } + +TEST_CASE("RestSourceSearch_CustomHeader", "[RestSource][CustomHeader]") +{ + utility::string_t customHeader = L"Testing custom header"; + auto header = std::make_pair<>(CustomHeaderName, customHeader); + HttpClientHelper helper{ GetCustomHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) }; + std::unordered_map headers; + headers.emplace(CustomHeaderName, customHeader); + + V1_1::Interface v1_1{ "https://restsource.com/api", {}, headers, std::move(helper) }; + Schema::IRestClient::SearchResult searchResponse = v1_1.Search({}); + REQUIRE(searchResponse.Matches.size() == 1); + Schema::IRestClient::Package package = searchResponse.Matches.at(0); +} + +TEST_CASE("RestSourceSearch_WhitespaceCustomHeader", "[RestSource][CustomHeader]") +{ + utility::string_t customHeader = L" "; + auto header = std::make_pair<>(CustomHeaderName, customHeader); + HttpClientHelper helper{ GetCustomHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) }; + std::unordered_map headers; + headers.emplace(CustomHeaderName, customHeader); + + V1_1::Interface v1_1{ "https://restsource.com/api", {}, headers, std::move(helper) }; + Schema::IRestClient::SearchResult searchResponse = v1_1.Search({}); + REQUIRE(searchResponse.Matches.size() == 1); +} + +TEST_CASE("RestSourceSearch_NoCustomHeader", "[RestSource][CustomHeader]") +{ + utility::string_t customHeader = L" "; + auto header = std::make_pair<>(CustomHeaderName, customHeader); + HttpClientHelper helper{ GetCustomHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) }; + std::unordered_map headers; + headers.emplace(CustomHeaderName, customHeader); + + V1_1::Interface v1_1{ "https://restsource.com/api", {}, {}, std::move(helper) }; + REQUIRE_THROWS_HR(v1_1.Search({}), APPINSTALLER_CLI_ERROR_RESTSOURCE_INTERNAL_ERROR); +} + +TEST_CASE("RestSourceSearch_CustomHeaderExceedingSize", "[RestSource][CustomHeader]") +{ + std::string customHeader = "This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. "; + auto header = std::make_pair<>(CustomHeaderName, JsonHelper::GetUtilityString(customHeader)); + HttpClientHelper helper{ GetCustomHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) }; + + REQUIRE_THROWS_HR(RestClient::Create(utility::conversions::to_utf8string("https://restsource.com/api"), customHeader, std::move(helper)), + APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH); +} diff --git a/src/AppInstallerCLITests/HttpClientHelper.cpp b/src/AppInstallerCLITests/HttpClientHelper.cpp index 007aa180b0..a4b9fa883f 100644 --- a/src/AppInstallerCLITests/HttpClientHelper.cpp +++ b/src/AppInstallerCLITests/HttpClientHelper.cpp @@ -4,9 +4,9 @@ #include "TestCommon.h" #include "TestRestRequestHandler.h" #include -#include +#include -using namespace AppInstaller::Repository::Rest; +using namespace AppInstaller::Repository::Rest::Schema; TEST_CASE("ExtractJsonResponse_UnsupportedMimeType", "[RestSource][RestSearch]") { @@ -19,3 +19,9 @@ TEST_CASE("ValidateAndExtractResponse_ServiceUnavailable", "[RestSource]") HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::ServiceUnavailable) }; REQUIRE_THROWS_HR(helper.HandleGet(L"https://testUri"), MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, web::http::status_codes::ServiceUnavailable)); } + +TEST_CASE("ValidateAndExtractResponse_NotFound", "[RestSource]") +{ + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) }; + REQUIRE_THROWS_HR(helper.HandleGet(L"https://testUri"), APPINSTALLER_CLI_ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND); +} diff --git a/src/AppInstallerCLITests/RestClient.cpp b/src/AppInstallerCLITests/RestClient.cpp index ffef18aa0d..d044975052 100644 --- a/src/AppInstallerCLITests/RestClient.cpp +++ b/src/AppInstallerCLITests/RestClient.cpp @@ -20,8 +20,16 @@ TEST_CASE("GetLatestCommonVersion", "[RestSource]") { std::set wingetSupportedContracts = { Version {"1.0.0"}, Version {"1.2.0"} }; std::vector versions{ "1.0.0", "2.0.0", "1.2.0" }; - IRestClient::Information info{ "SourceIdentifier", std::move(versions) }; - std::optional actual = RestClient::GetLatestCommonVersion(info, wingetSupportedContracts); + std::optional actual = RestClient::GetLatestCommonVersion(versions, wingetSupportedContracts); + REQUIRE(actual); + REQUIRE(actual.value().ToString() == "1.2.0"); +} + +TEST_CASE("GetLatestCommonVersion_OnlyMajorMinorVersionMatched", "[RestSource]") +{ + std::set wingetSupportedContracts = { Version {"1.0.0"}, Version {"1.2.0"} }; + std::vector versions{ "1.0.0", "2.0.0", "1.2.1" }; + std::optional actual = RestClient::GetLatestCommonVersion(versions, wingetSupportedContracts); REQUIRE(actual); REQUIRE(actual.value().ToString() == "1.2.0"); } @@ -30,18 +38,19 @@ TEST_CASE("GetLatestCommonVersion_UnsupportedVersion", "[RestSource]") { std::set wingetSupportedContracts = { Version {"3.0.0"}, Version {"4.2.0"} }; std::vector versions{ "1.0.0", "2.0.0" }; - IRestClient::Information info{ "SourceIdentifier", std::move(versions) }; - std::optional actual = RestClient::GetLatestCommonVersion(info, wingetSupportedContracts); + std::optional actual = RestClient::GetLatestCommonVersion(versions, wingetSupportedContracts); REQUIRE(!actual); } TEST_CASE("GetSupportedInterface", "[RestSource]") { + IRestClient::Information info{ "TestId", { "1.0.0" } }; + Version version{ "1.0.0" }; - REQUIRE(RestClient::GetSupportedInterface(utility::conversions::to_utf8string(TestRestUri), {}, version)->GetVersion() == version); + REQUIRE(RestClient::GetSupportedInterface(utility::conversions::to_utf8string(TestRestUri), {}, info, version)->GetVersion() == version); Version invalid{ "1.2.0" }; - REQUIRE_THROWS(RestClient::GetSupportedInterface(utility::conversions::to_utf8string(TestRestUri), {}, invalid)); + REQUIRE_THROWS(RestClient::GetSupportedInterface(utility::conversions::to_utf8string(TestRestUri), {}, info, invalid)); } TEST_CASE("GetInformation_Success", "[RestSource]") @@ -51,19 +60,76 @@ TEST_CASE("GetInformation_Success", "[RestSource]") "Data" : { "SourceIdentifier": "Source123", "ServerSupportedVersions": [ - "0.2.0", - "1.0.0"] + "1.0.0", + "1.1.0"], + "SourceAgreements": { + "AgreementsIdentifier": "agreementV1", + "Agreements": [{ + "AgreementLabel": "EULA", + "Agreement": "this is store agreement", + "AgreementUrl": "https://store.agreement" + } + ] + }, + "RequiredQueryParameters": [ + "Market" + ], + "RequiredPackageMatchFields": [ + "Market" + ], + "UnsupportedQueryParameters": [ + "Moniker" + ], + "UnsupportedPackageMatchFields": [ + "Moniker" + ] }})delimiter"); HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) }; IRestClient::Information information = RestClient::GetInformation(TestRestUri, {}, std::move(helper)); REQUIRE(information.SourceIdentifier == "Source123"); REQUIRE(information.ServerSupportedVersions.size() == 2); - REQUIRE(information.ServerSupportedVersions.at(0) == "0.2.0"); - REQUIRE(information.ServerSupportedVersions.at(1) == "1.0.0"); + REQUIRE(information.ServerSupportedVersions.at(0) == "1.0.0"); + REQUIRE(information.ServerSupportedVersions.at(1) == "1.1.0"); + REQUIRE(information.SourceAgreementsIdentifier == "agreementV1"); + REQUIRE(information.SourceAgreements.size() == 1); + REQUIRE(information.SourceAgreements.at(0).Label == "EULA"); + REQUIRE(information.SourceAgreements.at(0).Text == "this is store agreement"); + REQUIRE(information.SourceAgreements.at(0).Url == "https://store.agreement"); + REQUIRE(information.RequiredQueryParameters.size() == 1); + REQUIRE(information.RequiredQueryParameters.at(0) == "Market"); + REQUIRE(information.RequiredPackageMatchFields.size() == 1); + REQUIRE(information.RequiredPackageMatchFields.at(0) == "Market"); + REQUIRE(information.UnsupportedQueryParameters.size() == 1); + REQUIRE(information.UnsupportedQueryParameters.at(0) == "Moniker"); + REQUIRE(information.UnsupportedPackageMatchFields.size() == 1); + REQUIRE(information.UnsupportedPackageMatchFields.at(0) == "Moniker"); +} + +TEST_CASE("GetInformation_Fail_AgreementsWithoutIdentifier", "[RestSource]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data" : { + "SourceIdentifier": "Source123", + "ServerSupportedVersions": [ + "1.0.0", + "1.1.0"], + "SourceAgreements": { + "Agreements": [{ + "AgreementLabel": "EULA", + "Agreement": "this is store agreement", + "AgreementUrl": "https://store.agreement" + } + ] + } + }})delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) }; + REQUIRE_THROWS_HR(RestClient::GetInformation(TestRestUri, {}, std::move(helper)), APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE); } -TEST_CASE("RestClientCreate_UnexpectedVersion", "[RestSource]") +TEST_CASE("RestClientCreate_UnsupportedVersion", "[RestSource]") { utility::string_t sample = _XPLATSTR( R"delimiter({ @@ -75,11 +141,10 @@ TEST_CASE("RestClientCreate_UnexpectedVersion", "[RestSource]") }})delimiter"); HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) }; - REQUIRE_THROWS_HR(RestClient::Create("https://restsource.com/api", {}, std::move(helper)), - APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE); + REQUIRE_THROWS_HR(RestClient::Create("https://restsource.com/api", {}, std::move(helper)), APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE); } -TEST_CASE("RestClientCreate_Success", "[RestSource]") +TEST_CASE("RestClientCreate_1.0_Success", "[RestSource]") { utility::string_t sample = _XPLATSTR( R"delimiter({ @@ -94,3 +159,54 @@ TEST_CASE("RestClientCreate_Success", "[RestSource]") RestClient client = RestClient::Create(utility::conversions::to_utf8string(TestRestUri), {}, std::move(helper)); REQUIRE(client.GetSourceIdentifier() == "Source123"); } + +TEST_CASE("RestClientCreate_1.1_Success", "[RestSource]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data" : { + "SourceIdentifier": "Source123", + "ServerSupportedVersions": [ + "1.0.0", + "1.1.0"], + "SourceAgreements": { + "AgreementsIdentifier": "agreementV1", + "Agreements": [{ + "AgreementLabel": "EULA", + "Agreement": "this is store agreement", + "AgreementUrl": "https://store.agreement" + } + ] + }, + "RequiredQueryParameters": [ + "Market" + ], + "RequiredPackageMatchFields": [ + "Market" + ], + "UnsupportedQueryParameters": [ + "Moniker" + ], + "UnsupportedPackageMatchFields": [ + "Moniker" + ] + }})delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) }; + RestClient client = RestClient::Create(utility::conversions::to_utf8string(TestRestUri), {}, std::move(helper)); + REQUIRE(client.GetSourceIdentifier() == "Source123"); + auto information = client.GetSourceInformation(); + REQUIRE(information.SourceAgreementsIdentifier == "agreementV1"); + REQUIRE(information.SourceAgreements.size() == 1); + REQUIRE(information.SourceAgreements.at(0).Label == "EULA"); + REQUIRE(information.SourceAgreements.at(0).Text == "this is store agreement"); + REQUIRE(information.SourceAgreements.at(0).Url == "https://store.agreement"); + REQUIRE(information.RequiredQueryParameters.size() == 1); + REQUIRE(information.RequiredQueryParameters.at(0) == "Market"); + REQUIRE(information.RequiredPackageMatchFields.size() == 1); + REQUIRE(information.RequiredPackageMatchFields.at(0) == "Market"); + REQUIRE(information.UnsupportedQueryParameters.size() == 1); + REQUIRE(information.UnsupportedQueryParameters.at(0) == "Moniker"); + REQUIRE(information.UnsupportedPackageMatchFields.size() == 1); + REQUIRE(information.UnsupportedPackageMatchFields.at(0) == "Moniker"); +} diff --git a/src/AppInstallerCLITests/RestInterface_1_0.cpp b/src/AppInstallerCLITests/RestInterface_1_0.cpp index 29fb5e5757..efb5e19580 100644 --- a/src/AppInstallerCLITests/RestInterface_1_0.cpp +++ b/src/AppInstallerCLITests/RestInterface_1_0.cpp @@ -3,7 +3,6 @@ #include "pch.h" #include "TestCommon.h" #include "TestRestRequestHandler.h" -#include #include #include #include @@ -271,7 +270,7 @@ namespace }; } -TEST_CASE("Search_GoodResponse", "[RestSource]") +TEST_CASE("Search_GoodResponse", "[RestSource][Interface_1_0]") { utility::string_t sample = _XPLATSTR( R"delimiter({ @@ -299,7 +298,7 @@ TEST_CASE("Search_GoodResponse", "[RestSource]") REQUIRE(package.Versions.at(1).VersionAndChannel.GetVersion().ToString().compare("2.0.0") == 0); } -TEST_CASE("Search_GoodResponse_AllFields", "[RestSource][Rest]") +TEST_CASE("Search_GoodResponse_AllFields", "[RestSource][Interface_1_0]") { utility::string_t sample = _XPLATSTR( R"delimiter({ @@ -341,7 +340,7 @@ TEST_CASE("Search_GoodResponse_AllFields", "[RestSource][Rest]") REQUIRE(package.Versions.at(0).ProductCodes.at(1) == "pc2"); } -TEST_CASE("Search_ContinuationToken", "[RestSource]") +TEST_CASE("Search_ContinuationToken", "[RestSource][Interface_1_0]") { utility::string_t sample = _XPLATSTR( R"delimiter({ @@ -376,7 +375,7 @@ TEST_CASE("Search_ContinuationToken", "[RestSource]") REQUIRE(resultsWithSize1.Matches.size() == requestWithSize1.MaximumResults); } -TEST_CASE("Search_BadResponse_NoVersions", "[RestSource]") +TEST_CASE("Search_BadResponse_NoVersions", "[RestSource][Interface_1_0]") { utility::string_t sample = _XPLATSTR( R"delimiter({ @@ -393,15 +392,14 @@ TEST_CASE("Search_BadResponse_NoVersions", "[RestSource]") REQUIRE_THROWS_HR(v1.Search({}), APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA); } -TEST_CASE("Search_BadResponse_NotFoundCode", "[RestSource]") +TEST_CASE("Search_BadResponse_NotFoundCode", "[RestSource][Interface_1_0]") { HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) }; Interface v1{ TestRestUriString, std::move(helper) }; - Schema::IRestClient::SearchResult result = v1.Search({}); - REQUIRE(result.Matches.empty()); + REQUIRE_THROWS_HR(v1.Search({}), APPINSTALLER_CLI_ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND); } -TEST_CASE("Search_Optimized_ManifestResponse", "[RestSource]") +TEST_CASE("Search_Optimized_ManifestResponse", "[RestSource][Interface_1_0]") { utility::string_t sample = GetGoodManifest_RequiredFields(); HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; @@ -432,18 +430,17 @@ TEST_CASE("Search_Optimized_ManifestResponse", "[RestSource]") REQUIRE(manifest.Installers[0].Url == "https://installer.example.com/foobar.exe"); } -TEST_CASE("Search_Optimized_NoResponse_NotFoundCode", "[RestSource]") +TEST_CASE("Search_Optimized_NoResponse_NotFoundCode", "[RestSource][Interface_1_0]") { HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) }; AppInstaller::Repository::SearchRequest request; PackageMatchFilter filter{ PackageMatchField::Id, MatchType::Exact, "Foo" }; request.Filters.emplace_back(std::move(filter)); Interface v1{ TestRestUriString, std::move(helper) }; - Schema::IRestClient::SearchResult result = v1.Search(request); - REQUIRE(result.Matches.empty()); + REQUIRE_THROWS_HR(v1.Search(request), APPINSTALLER_CLI_ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND); } -TEST_CASE("GetManifests_GoodResponse", "[RestSource]") +TEST_CASE("GetManifests_GoodResponse", "[RestSource][Interface_1_0]") { GoodManifest_AllFields sampleManifest; utility::string_t sample = sampleManifest.GetSampleManifest_AllFields(); @@ -462,7 +459,7 @@ TEST_CASE("GetManifests_GoodResponse", "[RestSource]") sampleManifest.VerifyInstallers_AllFields(manifest); } -TEST_CASE("GetManifests_BadResponse_SuccessCode", "[RestSource]") +TEST_CASE("GetManifests_BadResponse_SuccessCode", "[RestSource][Interface_1_0]") { utility::string_t badManifest = _XPLATSTR( R"delimiter({ @@ -481,10 +478,49 @@ TEST_CASE("GetManifests_BadResponse_SuccessCode", "[RestSource]") REQUIRE_THROWS_HR(v1.GetManifests("Foo.Bar"), APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA); } -TEST_CASE("GetManifests_NotFoundCode", "[RestSource]") +TEST_CASE("GetManifests_NotFoundCode", "[RestSource][Interface_1_0]") { HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) }; Interface v1{ TestRestUriString, std::move(helper) }; - std::vector manifests = v1.GetManifests("Foo.Bar"); - REQUIRE(manifests.empty()); + REQUIRE_THROWS_HR(v1.GetManifests("Foo.Bar"), APPINSTALLER_CLI_ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND); } + +TEST_CASE("GetManifests_GoodResponse_UnknownInstaller", "[RestSource][Interface_1_0]") +{ + utility::string_t msstoreInstallerResponse = _XPLATSTR( + R"delimiter({ + "Data": { + "PackageIdentifier": "Foo.Bar", + "Versions": [ + { + "PackageVersion": "5.0.0", + "DefaultLocale": { + "PackageLocale": "en-us", + "Publisher": "Foo", + "PackageName": "Bar", + "License": "Foo bar license", + "ShortDescription": "Foo bar description" + }, + "Installers": [ + { + "Architecture": "x64", + "InstallerType": "msstore", + "MSStoreProductIdentifier": "9nblggh4nns1" + } + ] + } + ] + } + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(msstoreInstallerResponse)) }; + Interface v1{ TestRestUriString, std::move(helper) }; + std::vector manifests = v1.GetManifests("Foo.Bar"); + REQUIRE(manifests.size() == 1); + + // Verify manifest is populated and manifest validation passed + Manifest manifest = manifests[0]; + REQUIRE(manifest.Installers.size() == 1); + REQUIRE(manifest.Installers.at(0).InstallerType == InstallerTypeEnum::Unknown); + REQUIRE(manifest.Installers.at(0).ProductId.empty()); +} \ No newline at end of file diff --git a/src/AppInstallerCLITests/RestInterface_1_1.cpp b/src/AppInstallerCLITests/RestInterface_1_1.cpp new file mode 100644 index 0000000000..a488f4be97 --- /dev/null +++ b/src/AppInstallerCLITests/RestInterface_1_1.cpp @@ -0,0 +1,270 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "TestCommon.h" +#include "TestRestRequestHandler.h" +#include +#include +#include +#include + +using namespace TestCommon; +using namespace AppInstaller::Utility; +using namespace AppInstaller::Manifest; +using namespace AppInstaller::Repository; +using namespace AppInstaller::Repository::Rest; +using namespace AppInstaller::Repository::Rest::Schema; +using namespace AppInstaller::Repository::Rest::Schema::V1_1; + +namespace +{ + const std::string TestRestUriString = "http://restsource.com/api"; + + IRestClient::Information GetTestSourceInformation() + { + IRestClient::Information result; + + result.RequiredPackageMatchFields.emplace_back("Market"); + result.RequiredQueryParameters.emplace_back("Market"); + result.UnsupportedPackageMatchFields.emplace_back("Moniker"); + result.UnsupportedQueryParameters.emplace_back("Channel"); + + return result; + } +} + +TEST_CASE("Search_BadResponse_UnsupportedPackageMatchFields", "[RestSource][Interface_1_1]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data" : [], + "UnsupportedPackageMatchFields" : [ "Moniker" ] + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_1{ TestRestUriString, GetTestSourceInformation(), {}, std::move(helper) }; + AppInstaller::Repository::SearchRequest request; + PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, "Foo" }; + request.Filters.emplace_back(std::move(filter)); + REQUIRE_THROWS_HR(v1_1.Search(request), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST); +} + +TEST_CASE("Search_BadResponse_RequiredPackageMatchFields", "[RestSource][Interface_1_1]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data" : [], + "RequiredPackageMatchFields" : [ "Moniker" ] + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_1{ TestRestUriString, GetTestSourceInformation(), {}, std::move(helper) }; + AppInstaller::Repository::SearchRequest request; + PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, "Foo" }; + request.Filters.emplace_back(std::move(filter)); + REQUIRE_THROWS_HR(v1_1.Search(request), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST); +} + +TEST_CASE("GetManifests_BadResponse_UnsupportedQueryParameters", "[RestSource][Interface_1_1]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data" : null, + "UnsupportedQueryParameters" : [ "Channel" ] + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_1{ TestRestUriString, GetTestSourceInformation(), {}, std::move(helper) }; + REQUIRE_THROWS_HR(v1_1.GetManifests("Foo"), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST); +} + +TEST_CASE("GetManifests_BadResponse_RequiredQueryParameters", "[RestSource][Interface_1_1]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data" : null, + "RequiredQueryParameters" : [ "Version" ] + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_1{ TestRestUriString, GetTestSourceInformation(), {}, std::move(helper) }; + REQUIRE_THROWS_HR(v1_1.GetManifests("Foo"), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST); +} + +TEST_CASE("Search_BadRequest_UnsupportedPackageMatchFields", "[RestSource][Interface_1_1]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data" : [ + { + "PackageIdentifier": "git.package", + "PackageName": "package", + "Publisher": "git", + "Versions": [ + { "PackageVersion": "1.0.0" }, + { "PackageVersion": "2.0.0"}] + }] + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_1{ TestRestUriString, GetTestSourceInformation(), {}, std::move(helper) }; + AppInstaller::Repository::SearchRequest request; + PackageMatchFilter filter{ PackageMatchField::Moniker, MatchType::Exact, "Foo" }; + request.Filters.emplace_back(std::move(filter)); + REQUIRE_THROWS_HR(v1_1.Search(request), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST); +} + +TEST_CASE("Search_GoodRequest_OnlyMarketRequired", "[RestSource][Interface_1_1]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data" : [ + { + "PackageIdentifier": "git.package", + "PackageName": "package", + "Publisher": "git", + "Versions": [ + { "PackageVersion": "1.0.0" }, + { "PackageVersion": "2.0.0"}] + }] + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_1{ TestRestUriString, GetTestSourceInformation(), {}, std::move(helper) }; + AppInstaller::Repository::SearchRequest request; + PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, "Foo" }; + request.Filters.emplace_back(std::move(filter)); + Schema::IRestClient::SearchResult searchResponse = v1_1.Search(request); + REQUIRE(searchResponse.Matches.size() == 1); + Schema::IRestClient::Package package = searchResponse.Matches.at(0); + REQUIRE(package.PackageInformation.PackageIdentifier.compare("git.package") == 0); + REQUIRE(package.PackageInformation.Publisher.compare("git") == 0); + REQUIRE(package.PackageInformation.PackageName.compare("package") == 0); + REQUIRE(package.Versions.size() == 2); + REQUIRE(package.Versions.at(0).VersionAndChannel.GetVersion().ToString().compare("1.0.0") == 0); + REQUIRE(package.Versions.at(1).VersionAndChannel.GetVersion().ToString().compare("2.0.0") == 0); +} + +TEST_CASE("GetManifests_BadRequest_UnsupportedQueryParameters", "[RestSource][Interface_1_1]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data": { + "PackageIdentifier": "Foo.Bar", + "Versions": [ + { + "PackageVersion": "5.0.0", + "DefaultLocale": { + "PackageLocale": "en-us", + "Publisher": "Foo", + "PackageName": "Bar", + "License": "Foo bar license", + "ShortDescription": "Foo bar description" + }, + "Installers": [ + { + "Architecture": "x64", + "InstallerSha256": "011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6", + "InstallerType": "exe", + "InstallerUrl": "https://installer.example.com/foobar.exe" + } + ] + } + ] + } + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_1{ TestRestUriString, GetTestSourceInformation(), {}, std::move(helper) }; + REQUIRE_THROWS_HR(v1_1.GetManifestByVersion("Foo", "1.0", "beta"), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST); +} + +TEST_CASE("GetManifests_GoodRequest_OnlyMarketRequired", "[RestSource][Interface_1_1]") +{ + utility::string_t sample = _XPLATSTR( + R"delimiter({ + "Data": { + "PackageIdentifier": "Foo.Bar", + "Versions": [ + { + "PackageVersion": "5.0.0", + "DefaultLocale": { + "PackageLocale": "en-us", + "Publisher": "Foo", + "PackageName": "Bar", + "License": "Foo bar license", + "ShortDescription": "Foo bar description" + }, + "Installers": [ + { + "Architecture": "x64", + "InstallerSha256": "011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6", + "InstallerType": "exe", + "InstallerUrl": "https://installer.example.com/foobar.exe" + } + ] + } + ] + } + })delimiter"); + + IRestClient::Information info = GetTestSourceInformation(); + info.UnsupportedQueryParameters.clear(); + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_1{ TestRestUriString, info, {}, std::move(helper) }; + auto manifestResult = v1_1.GetManifestByVersion("Foo", "5.0.0", ""); + REQUIRE(manifestResult.has_value()); + const Manifest& manifest = manifestResult.value(); + REQUIRE(manifest.Id == "Foo.Bar"); + REQUIRE(manifest.Version == "5.0.0"); + REQUIRE(manifest.DefaultLocalization.Locale == "en-us"); + REQUIRE(manifest.DefaultLocalization.Get() == "Foo"); + REQUIRE(manifest.DefaultLocalization.Get() == "Bar"); + REQUIRE(manifest.DefaultLocalization.Get() == "Foo bar license"); + REQUIRE(manifest.DefaultLocalization.Get() == "Foo bar description"); + REQUIRE(manifest.Installers.size() == 1); + REQUIRE(manifest.Installers[0].Arch == Architecture::X64); + REQUIRE(manifest.Installers[0].Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes("011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6")); + REQUIRE(manifest.Installers[0].InstallerType == InstallerTypeEnum::Exe); + REQUIRE(manifest.Installers[0].Url == "https://installer.example.com/foobar.exe"); +} + +TEST_CASE("GetManifests_GoodResponse_MSStoreType", "[RestSource][Interface_1_1]") +{ + utility::string_t msstoreInstallerResponse = _XPLATSTR( + R"delimiter({ + "Data": { + "PackageIdentifier": "Foo.Bar", + "Versions": [ + { + "PackageVersion": "5.0.0", + "DefaultLocale": { + "PackageLocale": "en-us", + "Publisher": "Foo", + "PackageName": "Bar", + "License": "Foo bar license", + "ShortDescription": "Foo bar description" + }, + "Installers": [ + { + "Architecture": "x64", + "InstallerType": "msstore", + "MSStoreProductIdentifier": "9nblggh4nns1" + } + ] + } + ] + } + })delimiter"); + + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(msstoreInstallerResponse)) }; + Interface v1_1{ TestRestUriString, GetTestSourceInformation(), {}, std::move(helper) }; + std::vector manifests = v1_1.GetManifests("Foo.Bar"); + REQUIRE(manifests.size() == 1); + + // Verify manifest is populated and manifest validation passed + Manifest manifest = manifests[0]; + REQUIRE(manifest.Installers.size() == 1); + REQUIRE(manifest.Installers.at(0).InstallerType == InstallerTypeEnum::MSStore); + REQUIRE(manifest.Installers.at(0).ProductId == "9nblggh4nns1"); +} \ No newline at end of file diff --git a/src/AppInstallerCLITests/SearchRequestSerializer.cpp b/src/AppInstallerCLITests/SearchRequestSerializer.cpp index 7cd200da13..77641ac9f1 100644 --- a/src/AppInstallerCLITests/SearchRequestSerializer.cpp +++ b/src/AppInstallerCLITests/SearchRequestSerializer.cpp @@ -5,11 +5,11 @@ #include "TestRestRequestHandler.h" #include #include +#include using namespace TestCommon; using namespace AppInstaller::Repository; -using namespace AppInstaller::Repository::Rest::Schema::V1_0; -using namespace AppInstaller::Repository::Rest::Schema::V1_0::Json; +using namespace AppInstaller::Repository::Rest::Schema; TEST_CASE("SearchRequestSerializer_InclusionsFilters", "[RestSource]") { @@ -19,7 +19,7 @@ TEST_CASE("SearchRequestSerializer_InclusionsFilters", "[RestSource]") searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Moniker, MatchType::Exact, "FooBar")); searchRequest.MaximumResults = 10; - SearchRequestSerializer serializer; + V1_0::Json::SearchRequestSerializer serializer; web::json::value actual = serializer.Serialize(searchRequest); REQUIRE(!actual.is_null()); @@ -50,8 +50,8 @@ TEST_CASE("SearchRequestSerializer_Query", "[RestSource]") { SearchRequest searchRequest; searchRequest.Query = RequestMatch(MatchType::Substring, "Foo.Bar"); - - SearchRequestSerializer serializer; + + V1_0::Json::SearchRequestSerializer serializer; web::json::value actual = serializer.Serialize(std::move(searchRequest)); REQUIRE(!actual.is_null()); @@ -62,9 +62,27 @@ TEST_CASE("SearchRequestSerializer_Query", "[RestSource]") TEST_CASE("SearchRequestSerializer_FetchAllManifests", "[RestSource]") { - SearchRequestSerializer serializer; + V1_0::Json::SearchRequestSerializer serializer; web::json::value actual = serializer.Serialize({}); REQUIRE(!actual.is_null()); REQUIRE(actual.at(L"FetchAllManifests").as_bool()); } + +TEST_CASE("SearchRequestSerializer_NewFields", "[RestSource]") +{ + SearchRequest searchRequest; + searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::Substring, "Foo.Bar")); + searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Name, MatchType::Substring, "Foo")); + searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Market, MatchType::Exact, "FooBar")); + + V1_0::Json::SearchRequestSerializer serializerV1_0; + web::json::value actual_1_0 = serializerV1_0.Serialize(searchRequest); + REQUIRE(!actual_1_0.is_null()); + REQUIRE(actual_1_0.at(L"Filters").as_array().size() == 0); + + V1_1::Json::SearchRequestSerializer serializerV1_1; + web::json::value actual_1_1 = serializerV1_1.Serialize(searchRequest); + REQUIRE(!actual_1_1.is_null()); + REQUIRE(actual_1_1.at(L"Filters").as_array().size() == 1); +} diff --git a/src/AppInstallerCLITests/WorkFlow.cpp b/src/AppInstallerCLITests/WorkFlow.cpp index 0d48b01536..db0fea4edc 100644 --- a/src/AppInstallerCLITests/WorkFlow.cpp +++ b/src/AppInstallerCLITests/WorkFlow.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -521,6 +523,27 @@ void OverrideForMSStore(TestContext& context, bool isUpdate) } }); } +void OverrideForSourceAddWithAgreements(TestContext& context) +{ + context.Override({ EnsureRunningAsAdmin, [](TestContext&) + { + } }); + + context.Override({ AddSource, [](TestContext&) + { + } }); + + context.Override({ OpenSourceForSourceAdd, [](TestContext& context) + { + auto testSource = std::make_shared(); + testSource->Details.Information.SourceAgreementsIdentifier = "AgreementsIdentifier"; + testSource->Details.Information.SourceAgreements.emplace_back("Agreement Label", "Agreement Text", "https://test"); + testSource->Details.Information.RequiredPackageMatchFields.emplace_back("Market"); + testSource->Details.Information.RequiredQueryParameters.emplace_back("Market"); + context << Workflow::HandleSourceAgreements(testSource); + } }); +} + TEST_CASE("ExeInstallFlowWithTestManifest", "[InstallFlow][workflow]") { TestCommon::TempFile installResultPath("TestExeInstalled.txt"); @@ -899,7 +922,7 @@ TEST_CASE("InstallFlow_LicenseAgreement_Prompt", "[InstallFlow][workflow]") INFO(installOutput.str()); // Verify prompt was shown - REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::LicenseAgreementPrompt).get()) != std::string::npos); + REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageAgreementsPrompt).get()) != std::string::npos); // Verify agreements are shown REQUIRE(installOutput.str().find("Agreement with text") != std::string::npos); @@ -933,9 +956,9 @@ TEST_CASE("InstallFlow_LicenseAgreement_NotAccepted", "[InstallFlow][workflow]") REQUIRE(installOutput.str().find("https://TestAgreementUrl") != std::string::npos); // Verify installation failed - REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_LICENSE_NOT_ACCEPTED); + REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED); REQUIRE_FALSE(std::filesystem::exists(installResultPath.GetPath())); - REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::LicenseNotAgreedTo).get()) != std::string::npos); + REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageAgreementsNotAgreedTo).get()) != std::string::npos); } TEST_CASE("ShowFlow_SearchAndShowAppInfo", "[ShowFlow][workflow]") @@ -1321,9 +1344,9 @@ TEST_CASE("UpdateFlow_LicenseAgreement_NotAccepted", "[UpdateFlow][workflow]") REQUIRE(updateOutput.str().find("This is the agreement for the EXE") != std::string::npos); // Verify Installer is not called. - REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_LICENSE_NOT_ACCEPTED); + REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED); REQUIRE_FALSE(std::filesystem::exists(updateResultPath.GetPath())); - REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::LicenseNotAgreedTo).get()) != std::string::npos); + REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::PackageAgreementsNotAgreedTo).get()) != std::string::npos); } TEST_CASE("UpdateFlow_All_LicenseAgreement", "[UpdateFlow][workflow]") @@ -1382,7 +1405,7 @@ TEST_CASE("UpdateFlow_All_LicenseAgreement_NotAccepted", "[UpdateFlow][workflow] REQUIRE(updateOutput.str().find("This is the agreement for the MSIX") != std::string::npos); // Verify installers are not called. - REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_LICENSE_NOT_ACCEPTED); + REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED); REQUIRE_FALSE(std::filesystem::exists(updateExeResultPath.GetPath())); REQUIRE_FALSE(std::filesystem::exists(updateMsixResultPath.GetPath())); REQUIRE_FALSE(std::filesystem::exists(updateMSStoreResultPath.GetPath())); @@ -1801,7 +1824,7 @@ TEST_CASE("ImportFlow_LicenseAgreement_NotAccepted", "[ImportFlow][workflow]") REQUIRE(importOutput.str().find("This is the agreement for the EXE") != std::string::npos); // Command should have failed - REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_LICENSE_NOT_ACCEPTED); + REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED); } void VerifyMotw(const std::filesystem::path& testFile, DWORD zone) @@ -2037,6 +2060,87 @@ TEST_CASE("InstallerWithoutDependencies_RootDependenciesAreUsed", "[dependencies REQUIRE(installOutput.str().find("PreviewIISOnRoot") != std::string::npos); } +TEST_CASE("SourceAddFlow_Agreement", "[SourceAddFlow][workflow]") +{ + std::ostringstream sourceAddOutput; + TestContext context{ sourceAddOutput, std::cin }; + OverrideForSourceAddWithAgreements(context); + context.Args.AddArg(Execution::Args::Type::SourceName, "TestSource"sv); + context.Args.AddArg(Execution::Args::Type::SourceType, "Microsoft.Test"sv); + context.Args.AddArg(Execution::Args::Type::SourceArg, "TestArg"sv); + context.Args.AddArg(Execution::Args::Type::AcceptSourceAgreements); + + SourceAddCommand sourceAdd({}); + sourceAdd.Execute(context); + INFO(sourceAddOutput.str()); + + // Verify agreements are shown + REQUIRE(sourceAddOutput.str().find("Agreement Label") != std::string::npos); + REQUIRE(sourceAddOutput.str().find("Agreement Text") != std::string::npos); + REQUIRE(sourceAddOutput.str().find("https://test") != std::string::npos); + REQUIRE(sourceAddOutput.str().find(Resource::LocString(Resource::String::SourceAgreementsMarketMessage).get()) != std::string::npos); + + // Verify Installer is called. + REQUIRE(context.GetTerminationHR() == S_OK); +} + +TEST_CASE("SourceAddFlow_Agreement_Prompt_Yes", "[SourceAddFlow][workflow]") +{ + // Accept the agreements by saying "Yes" at the prompt + std::istringstream sourceAddInput{ "y" }; + std::ostringstream sourceAddOutput; + TestContext context{ sourceAddOutput, sourceAddInput }; + OverrideForSourceAddWithAgreements(context); + context.Args.AddArg(Execution::Args::Type::SourceName, "TestSource"sv); + context.Args.AddArg(Execution::Args::Type::SourceType, "Microsoft.Test"sv); + context.Args.AddArg(Execution::Args::Type::SourceArg, "TestArg"sv); + + SourceAddCommand sourceAdd({}); + sourceAdd.Execute(context); + INFO(sourceAddOutput.str()); + + // Verify agreements are shown + REQUIRE(sourceAddOutput.str().find("Agreement Label") != std::string::npos); + REQUIRE(sourceAddOutput.str().find("Agreement Text") != std::string::npos); + REQUIRE(sourceAddOutput.str().find("https://test") != std::string::npos); + REQUIRE(sourceAddOutput.str().find(Resource::LocString(Resource::String::SourceAgreementsMarketMessage).get()) != std::string::npos); + + // Verify Installer is called. + REQUIRE(context.GetTerminationHR() == S_OK); +} + +TEST_CASE("SourceAddFlow_Agreement_Prompt_No", "[SourceAddFlow][workflow]") +{ + // Accept the agreements by saying "No" at the prompt + std::istringstream sourceAddInput{ "n" }; + std::ostringstream sourceAddOutput; + TestContext context{ sourceAddOutput, sourceAddInput }; + OverrideForSourceAddWithAgreements(context); + // This tests RemoveSource is called after agreement is not accepted. If they are not called, the test fails with unused override. + context.Override({ GetSourceListWithFilter, [](TestContext&) + { + } }); + context.Override({ RemoveSources, [](TestContext&) + { + } }); + context.Args.AddArg(Execution::Args::Type::SourceName, "TestSource"sv); + context.Args.AddArg(Execution::Args::Type::SourceType, "Microsoft.Test"sv); + context.Args.AddArg(Execution::Args::Type::SourceArg, "TestArg"sv); + + SourceAddCommand sourceAdd({}); + sourceAdd.Execute(context); + INFO(sourceAddOutput.str()); + + // Verify agreements are shown + REQUIRE(sourceAddOutput.str().find("Agreement Label") != std::string::npos); + REQUIRE(sourceAddOutput.str().find("Agreement Text") != std::string::npos); + REQUIRE(sourceAddOutput.str().find("https://test") != std::string::npos); + REQUIRE(sourceAddOutput.str().find(Resource::LocString(Resource::String::SourceAgreementsMarketMessage).get()) != std::string::npos); + + // Verify Installer is called. + REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED); +} + TEST_CASE("OpenSource_WithCustomHeader", "[OpenSource][CustomHeader]") { SetSetting(Streams::UserSources, R"(Sources:)"sv); diff --git a/src/AppInstallerCLITests/YamlManifest.cpp b/src/AppInstallerCLITests/YamlManifest.cpp index 90b5b3511c..b32244cbcd 100644 --- a/src/AppInstallerCLITests/YamlManifest.cpp +++ b/src/AppInstallerCLITests/YamlManifest.cpp @@ -240,12 +240,12 @@ TEST_CASE("ReadBadManifests", "[ManifestValidation]") { "Manifest-Bad-NameMissing.yaml", "Missing required property 'Name'" }, { "Manifest-Bad-PublisherMissing.yaml", "Missing required property 'Publisher'" }, { "Manifest-Bad-Sha256Invalid.yaml", "Failed to validate against schema associated with property name 'Sha256'" }, - { "Manifest-Bad-Sha256Missing.yaml", "Required field missing. Field: Sha256" }, + { "Manifest-Bad-Sha256Missing.yaml", "Required field missing. Field: InstallerSha256" }, { "Manifest-Bad-SwitchInvalid.yaml", "Unknown field. Field: NotASwitch", true }, { "Manifest-Bad-UnknownProperty.yaml", "Unknown field. Field: Fake", true }, { "Manifest-Bad-UnsupportedVersion.yaml", "Unsupported ManifestVersion" }, - { "Manifest-Bad-UrlInvalid.yaml", "Invalid field value. Field: Url" }, - { "Manifest-Bad-UrlMissing.yaml", "Required field missing. Field: Url" }, + { "Manifest-Bad-UrlInvalid.yaml", "Invalid field value. Field: InstallerUrl" }, + { "Manifest-Bad-UrlMissing.yaml", "Required field missing. Field: InstallerUrl" }, { "Manifest-Bad-VersionInvalid.yaml", "Failed to validate against schema associated with property name 'Version'" }, { "Manifest-Bad-VersionMissing.yaml", "Missing required property 'Version'" }, { "Manifest-Bad-InvalidManifestVersionValue.yaml", "Failed to validate against schema associated with property name 'ManifestVersion'" }, diff --git a/src/AppInstallerCLITests/pch.h b/src/AppInstallerCLITests/pch.h index 570835446d..a00a6a8312 100644 --- a/src/AppInstallerCLITests/pch.h +++ b/src/AppInstallerCLITests/pch.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj index 60dee2bb22..a4ead8ed9a 100644 --- a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj +++ b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj @@ -302,6 +302,7 @@ + @@ -363,6 +364,7 @@ + diff --git a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters index eb53d4eeb5..aa6b9f981a 100644 --- a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters +++ b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters @@ -177,6 +177,9 @@ Public\winget + + Public\winget + @@ -299,6 +302,9 @@ Source Files + + Source Files + diff --git a/src/AppInstallerCommonCore/AppInstallerLogging.cpp b/src/AppInstallerCommonCore/AppInstallerLogging.cpp index d2dfa21050..3514c4fcbc 100644 --- a/src/AppInstallerCommonCore/AppInstallerLogging.cpp +++ b/src/AppInstallerCommonCore/AppInstallerLogging.cpp @@ -8,6 +8,7 @@ #include "Public/AppInstallerTelemetry.h" #include "Public/AppInstallerDateTime.h" #include "Public/AppInstallerRuntime.h" +#include "Public/winget/ThreadGlobals.h" namespace AppInstaller::Logging { @@ -49,12 +50,6 @@ namespace AppInstaller::Logging size_t GetMaxChannelNameLength() { return 4; } - DiagnosticLogger& DiagnosticLogger::GetInstance() - { - static DiagnosticLogger instance; - return instance; - } - void DiagnosticLogger::AddLogger(std::unique_ptr&& logger) { m_loggers.emplace_back(std::move(logger)); @@ -130,6 +125,20 @@ namespace AppInstaller::Logging } } + DiagnosticLogger& Log() + { + ThreadLocalStorage::ThreadGlobals* pThreadGlobals = ThreadLocalStorage::ThreadGlobals::GetForCurrentThread(); + if (pThreadGlobals) + { + return pThreadGlobals->GetDiagnosticLogger(); + } + else + { + static DiagnosticLogger processGlobalLogger; + return processGlobalLogger; + } + } + void AddFileLogger() { Log().AddLogger(std::make_unique()); diff --git a/src/AppInstallerCommonCore/AppInstallerStrings.cpp b/src/AppInstallerCommonCore/AppInstallerStrings.cpp index 63cc0a6dea..dfec1d8e68 100644 --- a/src/AppInstallerCommonCore/AppInstallerStrings.cpp +++ b/src/AppInstallerCommonCore/AppInstallerStrings.cpp @@ -13,6 +13,7 @@ namespace AppInstaller::Utility using namespace std::string_view_literals; constexpr std::string_view s_SpaceChars = AICLI_SPACE_CHARS; constexpr std::wstring_view s_WideSpaceChars = L"" AICLI_SPACE_CHARS; + constexpr std::string_view s_MessageReplacementToken = "%1"sv; namespace { @@ -504,4 +505,11 @@ namespace AppInstaller::Utility return result; } + + std::string FindAndReplaceMessageToken(std::string_view message, std::string_view value) + { + std::string result{ message }; + FindAndReplace(result, s_MessageReplacementToken, value); + return result; + } } diff --git a/src/AppInstallerCommonCore/AppInstallerTelemetry.cpp b/src/AppInstallerCommonCore/AppInstallerTelemetry.cpp index cbf2a8be63..2585d67fdb 100644 --- a/src/AppInstallerCommonCore/AppInstallerTelemetry.cpp +++ b/src/AppInstallerCommonCore/AppInstallerTelemetry.cpp @@ -7,6 +7,7 @@ #include "Public/AppInstallerSHA256.h" #include "Public/AppInstallerStrings.h" #include "winget/UserSettings.h" +#include "Public/winget/ThreadGlobals.h" #define AICLI_TraceLoggingStringView(_sv_,_name_) TraceLoggingCountedUtf8String(_sv_.data(), static_cast(_sv_.size()), _name_) #define AICLI_TraceLoggingWStringView(_sv_,_name_) TraceLoggingCountedWideString(_sv_.data(), static_cast(_sv_.size()), _name_) @@ -14,7 +15,7 @@ #define AICLI_TraceLoggingWriteActivity(_eventName_,...) TraceLoggingWriteActivity(\ g_hTraceProvider,\ _eventName_,\ -GetActivityId(false),\ +GetActivityId(),\ nullptr,\ TraceLoggingCountedUtf8String(m_caller.c_str(), static_cast(m_caller.size()), "Caller"),\ TraceLoggingPackedFieldEx(m_telemetryCorrelationJsonW.c_str(), static_cast((m_telemetryCorrelationJsonW.size() + 1) * sizeof(wchar_t)), TlgInUNICODESTRING, TlgOutJSON, "CvJson"),\ @@ -55,48 +56,16 @@ namespace AppInstaller::Logging { Telemetry().LogFailure(info); } - - GUID CreateGuid() - { - GUID result{}; - (void)CoCreateGuid(&result); - return result; - } - } - - const GUID* GetActivityId(bool isNewActivity) - { - static GUID activityId; - if (isNewActivity == true) - { - activityId = CreateGuid(); - } - return &activityId; - } - - void SetActivityId() - { - GetActivityId(true); } TelemetryTraceLogger::TelemetryTraceLogger() { - // TODO: Needs to be made a singleton registration/removal in the future - RegisterTraceLogging(); - - m_isSettingEnabled = !Settings::User().Get(); - m_userProfile = Runtime::GetPathTo(Runtime::PathName::UserProfile).wstring(); + std::ignore = CoCreateGuid(&m_activityId); } - - TelemetryTraceLogger::~TelemetryTraceLogger() + + const GUID* TelemetryTraceLogger::GetActivityId() const { - UnRegisterTraceLogging(); - } - - TelemetryTraceLogger& TelemetryTraceLogger::GetInstance() - { - static TelemetryTraceLogger instance; - return instance; + return &m_activityId; } bool TelemetryTraceLogger::DisableRuntime() @@ -109,6 +78,12 @@ namespace AppInstaller::Logging m_isRuntimeEnabled = true; } + void TelemetryTraceLogger::Initialize() + { + m_isSettingEnabled = !Settings::User().Get(); + m_userProfile = Runtime::GetPathTo(Runtime::PathName::UserProfile).wstring(); + } + void TelemetryTraceLogger::SetTelemetryCorrelationJson(const std::wstring_view jsonStr_view) noexcept { // Check if passed in string is a valid Json formatted before returning the value @@ -179,8 +154,6 @@ namespace AppInstaller::Logging packageVersion = Runtime::GetPackageVersion(); } - Logging::SetActivityId(); - if (IsTelemetryEnabled()) { AICLI_TraceLoggingWriteActivity( @@ -192,7 +165,7 @@ namespace AppInstaller::Logging TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); } - AICLI_LOG(Core, Info, << "WinGet, version [" << version << "], activity [" << *GetActivityId(false) << ']'); + AICLI_LOG(Core, Info, << "WinGet, version [" << version << "], activity [" << *GetActivityId() << ']'); AICLI_LOG(Core, Info, << "OS: " << Runtime::GetOSVersion()); AICLI_LOG(Core, Info, << "Command line Args: " << Utility::ConvertToUTF8(GetCommandLineW())); if (Runtime::IsRunningInPackagedContext()) @@ -541,7 +514,8 @@ namespace AppInstaller::Logging TraceLoggingUInt32(s_subExecutionId, "SubExecutionId"), AICLI_TraceLoggingStringView(url, "Url"), TraceLoggingHResult(hr, "HResult"), - TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } } @@ -573,8 +547,16 @@ namespace AppInstaller::Logging return *s_TelemetryTraceLogger_TestOverride.get(); } #endif - - return TelemetryTraceLogger::GetInstance(); + ThreadLocalStorage::ThreadGlobals* pThreadGlobals = ThreadLocalStorage::ThreadGlobals::GetForCurrentThread(); + if (pThreadGlobals) + { + return pThreadGlobals->GetTelemetryLogger(); + } + else + { + static GlobalTelemetryTraceLogger processGlobalTelemetry; + return processGlobalTelemetry; + } } void EnableWilFailureTelemetry() diff --git a/src/AppInstallerCommonCore/Errors.cpp b/src/AppInstallerCommonCore/Errors.cpp index 64a607bca1..a05c1be5ee 100644 --- a/src/AppInstallerCommonCore/Errors.cpp +++ b/src/AppInstallerCommonCore/Errors.cpp @@ -142,10 +142,20 @@ namespace AppInstaller return "The source data is corrupted or tampered"; case APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE: return "Error reading from the stream"; - case APPINSTALLER_CLI_ERROR_LICENSE_NOT_ACCEPTED: - return "License not agreed to"; + case APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED: + return "Package agreements were not agreed to"; case APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR: return "Error reading input in prompt"; + case APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST: + return "The search request is not supported by one or more sources"; + case APPINSTALLER_CLI_ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND: + return "The rest source endpoint is not found."; + case APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED: + return "Failed to open the source."; + case APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED: + return "Source agreements were not agreed to"; + case APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH: + return "Header size exceeds the allowable limit of 1024 characters. Please reduce the size and try again."; default: return "Unknown Error Code"; } diff --git a/src/AppInstallerCommonCore/ExperimentalFeature.cpp b/src/AppInstallerCommonCore/ExperimentalFeature.cpp index 77a0e51109..d1b9826bd0 100644 --- a/src/AppInstallerCommonCore/ExperimentalFeature.cpp +++ b/src/AppInstallerCommonCore/ExperimentalFeature.cpp @@ -43,8 +43,6 @@ namespace AppInstaller::Settings return userSettings.Get(); case ExperimentalFeature::Feature::ExperimentalMSStore: return userSettings.Get(); - case ExperimentalFeature::Feature::PackagedAPI: - return userSettings.Get(); case ExperimentalFeature::Feature::Dependencies: return userSettings.Get(); case ExperimentalFeature::Feature::DirectMSI: @@ -77,8 +75,6 @@ namespace AppInstaller::Settings return ExperimentalFeature{ "Argument Sample", "experimentalArg", "https://aka.ms/winget-settings", Feature::ExperimentalArg }; case Feature::ExperimentalMSStore: return ExperimentalFeature{ "Microsoft Store Support", "experimentalMSStore", "https://aka.ms/winget-settings", Feature::ExperimentalMSStore }; - case Feature::PackagedAPI: - return ExperimentalFeature{ "Packaged API Support", "packagedAPI", "https://aka.ms/winget-settings", Feature::PackagedAPI }; case Feature::Dependencies: return ExperimentalFeature{ "Show Dependencies Information", "dependencies", "https://aka.ms/winget-settings", Feature::Dependencies }; case Feature::DirectMSI: diff --git a/src/AppInstallerCommonCore/Manifest/ManifestValidation.cpp b/src/AppInstallerCommonCore/Manifest/ManifestValidation.cpp index b72c6c4c72..bd9b44a78c 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestValidation.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestValidation.cpp @@ -6,7 +6,7 @@ namespace AppInstaller::Manifest { - std::vector ValidateManifest(const Manifest& manifest) + std::vector ValidateManifest(const Manifest& manifest, bool fullValidation) { std::vector resultErrors; @@ -23,10 +23,11 @@ namespace AppInstaller::Manifest } catch (const std::exception&) { - resultErrors.emplace_back(ManifestError::InvalidFieldValue, "Version", manifest.Version); + resultErrors.emplace_back(ManifestError::InvalidFieldValue, "PackageVersion", manifest.Version); } - ValidateManifestLocalization(manifest.ManifestVersion, manifest.DefaultLocalization, resultErrors); + auto defaultLocErrors = ValidateManifestLocalization(manifest.DefaultLocalization); + std::move(defaultLocErrors.begin(), defaultLocErrors.end(), std::inserter(resultErrors, resultErrors.end())); // Comparison function to check duplicate installer entry. {installerType, arch, language and scope} combination is the key. // Todo: use the comparator from ManifestComparator when that one is fully implemented. @@ -63,6 +64,12 @@ namespace AppInstaller::Manifest // Validate installers for (auto const& installer : manifest.Installers) { + // If not full validation, for future compatibility, skip validating unknown installers. + if (installer.InstallerType == InstallerTypeEnum::Unknown && !fullValidation) + { + continue; + } + if (!duplicateInstallerFound && !installerSet.insert(installer).second) { resultErrors.emplace_back(ManifestError::DuplicateInstallerEntry); @@ -71,7 +78,7 @@ namespace AppInstaller::Manifest if (installer.Arch == Utility::Architecture::Unknown) { - resultErrors.emplace_back(ManifestError::InvalidFieldValue, "Arch"); + resultErrors.emplace_back(ManifestError::InvalidFieldValue, "Architecture"); } if (installer.InstallerType == InstallerTypeEnum::Unknown) @@ -97,10 +104,13 @@ namespace AppInstaller::Manifest if (installer.InstallerType == InstallerTypeEnum::MSStore) { - // MSStore type is not supported in community repo - resultErrors.emplace_back( - ManifestError::FieldValueNotSupported, "InstallerType", - InstallerTypeToString(installer.InstallerType)); + if (fullValidation) + { + // MSStore type is not supported in community repo + resultErrors.emplace_back( + ManifestError::FieldValueNotSupported, "InstallerType", + InstallerTypeToString(installer.InstallerType)); + } if (installer.ProductId.empty()) { @@ -112,11 +122,11 @@ namespace AppInstaller::Manifest // For other types, Url and Sha256 are required if (installer.Url.empty()) { - resultErrors.emplace_back(ManifestError::RequiredFieldMissing, "Url"); + resultErrors.emplace_back(ManifestError::RequiredFieldMissing, "InstallerUrl"); } if (installer.Sha256.empty()) { - resultErrors.emplace_back(ManifestError::RequiredFieldMissing, "Sha256"); + resultErrors.emplace_back(ManifestError::RequiredFieldMissing, "InstallerSha256"); } // ProductId should not be used if (!installer.ProductId.empty()) @@ -135,7 +145,7 @@ namespace AppInstaller::Manifest // Check empty string before calling IsValidUrl to avoid duplicate error reporting. if (!installer.Url.empty() && IsValidURL(NULL, Utility::ConvertToUTF16(installer.Url).c_str(), 0) == S_FALSE) { - resultErrors.emplace_back(ManifestError::InvalidFieldValue, "Url", installer.Url); + resultErrors.emplace_back(ManifestError::InvalidFieldValue, "InstallerUrl", installer.Url); } if (!installer.Locale.empty() && !Locale::IsWellFormedBcp47Tag(installer.Locale)) @@ -147,20 +157,23 @@ namespace AppInstaller::Manifest // Validate localizations for (auto const& localization : manifest.Localizations) { - ValidateManifestLocalization(manifest.ManifestVersion, localization, resultErrors); + auto locErrors = ValidateManifestLocalization(localization); + std::move(locErrors.begin(), locErrors.end(), std::inserter(resultErrors, resultErrors.end())); } return resultErrors; } - void ValidateManifestLocalization(const ManifestVer& manifestVersion, const ManifestLocalization& localization, std::vector& resultErrors) + std::vector ValidateManifestLocalization(const ManifestLocalization& localization) { + std::vector resultErrors; + if (!localization.Locale.empty() && !Locale::IsWellFormedBcp47Tag(localization.Locale)) { resultErrors.emplace_back(ManifestError::InvalidBcp47Value, "PackageLocale", localization.Locale); } - if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_1 }) + if (localization.Contains(Localization::Agreements)) { const auto& agreements = localization.Get(); for (const auto& agreement : agreements) @@ -172,5 +185,7 @@ namespace AppInstaller::Manifest } } } + + return resultErrors; } } \ No newline at end of file diff --git a/src/AppInstallerCommonCore/Public/AppInstallerErrors.h b/src/AppInstallerCommonCore/Public/AppInstallerErrors.h index 391db61644..4a8f5e7257 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerErrors.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerErrors.h @@ -77,9 +77,15 @@ #define APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION ((HRESULT)0x8a15003E) #define APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE ((HRESULT)0x8a15003F) #define APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE ((HRESULT)0x8a150040) -#define APPINSTALLER_CLI_ERROR_LICENSE_NOT_ACCEPTED ((HRESULT)0x8a150041) +#define APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED ((HRESULT)0x8a150041) #define APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR ((HRESULT)0x8a150042) #define APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT ((HRESULT)0x8a150043) +#define APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST ((HRESULT)0x8a150043) +#define APPINSTALLER_CLI_ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND ((HRESULT)0x8a150044) +#define APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED ((HRESULT)0x8a150045) +#define APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED ((HRESULT)0x8a150046) +#define APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH ((HRESULT)0x8a150047) + namespace AppInstaller { diff --git a/src/AppInstallerCommonCore/Public/AppInstallerLanguageUtilities.h b/src/AppInstallerCommonCore/Public/AppInstallerLanguageUtilities.h index e7cacc3a6e..0b673d346c 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerLanguageUtilities.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerLanguageUtilities.h @@ -138,7 +138,7 @@ namespace AppInstaller const typename Variant::variant_t& GetVariant(Enum e) const { auto itr = m_data.find(e); - THROW_HR_IF_MSG(E_NOT_SET, itr == m_data.cend(), "GetVariant(%d)", e); + THROW_HR_IF_MSG(E_NOT_SET, itr == m_data.cend(), "GetVariant(%d)", static_cast(e)); return itr->second; } diff --git a/src/AppInstallerCommonCore/Public/AppInstallerLogging.h b/src/AppInstallerCommonCore/Public/AppInstallerLogging.h index 66d8fac090..da44ce5d8f 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerLogging.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerLogging.h @@ -72,6 +72,8 @@ namespace AppInstaller::Logging // desired level, as nothing is enabled by default. struct DiagnosticLogger { + DiagnosticLogger() = default; + ~DiagnosticLogger() = default; DiagnosticLogger(const DiagnosticLogger&) = delete; @@ -119,18 +121,13 @@ namespace AppInstaller::Logging void Write(Channel channel, Level level, std::string_view message); private: - DiagnosticLogger() = default; std::vector> m_loggers; uint64_t m_enabledChannels = 0; Level m_enabledLevel = Level::Info; }; - // Helper to make the call sites look clean. - inline DiagnosticLogger& Log() - { - return DiagnosticLogger::GetInstance(); - } + DiagnosticLogger& Log(); // Adds the default file logger to the DiagnosticLogger. void AddFileLogger(); diff --git a/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h b/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h index 7cd05a5357..584571c611 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h @@ -23,6 +23,9 @@ namespace AppInstaller::Runtime // Gets a string representation of the OS version for debugging purposes. Utility::LocIndString GetOSVersion(); + // Gets the OS region. + std::string GetOSRegion(); + // A path to be retrieved based on the runtime. enum class PathName { diff --git a/src/AppInstallerCommonCore/Public/AppInstallerStrings.h b/src/AppInstallerCommonCore/Public/AppInstallerStrings.h index 25c4e51238..71078acaa3 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerStrings.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerStrings.h @@ -136,4 +136,7 @@ namespace AppInstaller::Utility // Expands environment variables within the input. std::wstring ExpandEnvironmentVariables(const std::wstring& input); + + // Replace message predefined token + std::string FindAndReplaceMessageToken(std::string_view message, std::string_view value); } diff --git a/src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h b/src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h index 07da77a1db..69527a0445 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h @@ -6,6 +6,7 @@ #include #include +#include namespace AppInstaller::Logging { @@ -15,7 +16,9 @@ namespace AppInstaller::Logging // this should not become a burden. struct TelemetryTraceLogger { - virtual ~TelemetryTraceLogger(); + TelemetryTraceLogger(); + + ~TelemetryTraceLogger() = default; TelemetryTraceLogger(const TelemetryTraceLogger&) = default; TelemetryTraceLogger& operator=(const TelemetryTraceLogger&) = default; @@ -23,13 +26,16 @@ namespace AppInstaller::Logging TelemetryTraceLogger(TelemetryTraceLogger&&) = default; TelemetryTraceLogger& operator=(TelemetryTraceLogger&&) = default; - // Gets the singleton instance of this type. - static TelemetryTraceLogger& GetInstance(); - // Control whether this trace logger is enabled at runtime. bool DisableRuntime(); void EnableRuntime(); + // Return address of m_activityId + const GUID* GetActivityId() const; + + // Capture if UserSettings is enabled and set user profile path + void Initialize(); + // Store the passed in name of the Caller for COM calls void SetCaller(const std::string& caller); @@ -123,8 +129,6 @@ namespace AppInstaller::Logging void LogNonFatalDOError(std::string_view url, HRESULT hr) const noexcept; protected: - TelemetryTraceLogger(); - bool IsTelemetryEnabled() const noexcept; // Used to anonymize a string to the best of our ability. @@ -135,6 +139,7 @@ namespace AppInstaller::Logging bool m_isSettingEnabled = true; std::atomic_bool m_isRuntimeEnabled{ true }; + GUID m_activityId = GUID_NULL; std::wstring m_telemetryCorrelationJsonW = L"{}"; std::string m_caller; @@ -142,17 +147,19 @@ namespace AppInstaller::Logging std::wstring m_userProfile; }; + struct GlobalTelemetryTraceLogger : TelemetryTraceLogger + { + GlobalTelemetryTraceLogger() { Initialize(); } + + ~GlobalTelemetryTraceLogger() = default; + }; + // Helper to make the call sites look clean. TelemetryTraceLogger& Telemetry(); // Turns on wil failure telemetry and logging. void EnableWilFailureTelemetry(); - const GUID* GetActivityId(bool isNewActivity); - - // Set ActivityId - void SetActivityId(); - // An RAII object to disable telemetry during its lifetime. // Primarily used by the complete command to prevent messy input from spamming us. struct DisableTelemetryScope diff --git a/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h b/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h index 286cd29b0e..91a4e9547b 100644 --- a/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h +++ b/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h @@ -21,10 +21,9 @@ namespace AppInstaller::Settings { None = 0x0, ExperimentalMSStore = 0x1, - PackagedAPI = 0x2, - Dependencies = 0x4, + Dependencies = 0x2, // Before making DirectMSI non-experimental, it should be part of manifest validation. - DirectMSI = 0x8, + DirectMSI = 0x4, Max, // This MUST always be after all experimental features // Features listed after Max will not be shown with the features command diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestValidation.h b/src/AppInstallerCommonCore/Public/winget/ManifestValidation.h index a0bbf70a65..3817534a9e 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestValidation.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestValidation.h @@ -193,6 +193,7 @@ namespace AppInstaller::Manifest bool m_warningOnly; }; - std::vector ValidateManifest(const Manifest& manifest); - void ValidateManifestLocalization(const ManifestVer& manifestVersion, const ManifestLocalization& localization, std::vector& resultErrors); + // fullValidation: bool to set if manifest validation should perform extra validation that is not required for reading a manifest. + std::vector ValidateManifest(const Manifest& manifest, bool fullValidation = true); + std::vector ValidateManifestLocalization(const ManifestLocalization& localization); } \ No newline at end of file diff --git a/src/AppInstallerCommonCore/Public/winget/ThreadGlobals.h b/src/AppInstallerCommonCore/Public/winget/ThreadGlobals.h new file mode 100644 index 0000000000..6267c39711 --- /dev/null +++ b/src/AppInstallerCommonCore/Public/winget/ThreadGlobals.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include + +namespace AppInstaller::ThreadLocalStorage +{ + + struct PreviousThreadGlobals; + + struct ThreadGlobals + { + ThreadGlobals() = default; + ~ThreadGlobals() = default; + + AppInstaller::Logging::DiagnosticLogger& GetDiagnosticLogger(); + + AppInstaller::Logging::TelemetryTraceLogger& GetTelemetryLogger(); + + // Set Globals for Current Thread + // Return RAII object with it's ownership to set the AppInstaller ThreadLocalStorage back to previous state + std::unique_ptr SetForCurrentThread(); + + // Return Globals for Current Thread + static ThreadGlobals* GetForCurrentThread(); + + private: + + void Initialize(); + + std::unique_ptr m_pDiagnosticLogger; + std::unique_ptr m_pTelemetryLogger; + std::once_flag loggerInitOnceFlag; + + }; + + struct PreviousThreadGlobals + { + ~PreviousThreadGlobals(); + + PreviousThreadGlobals(ThreadGlobals* previous) : m_previous(previous) {}; + + private: + + ThreadGlobals* m_previous; + }; +} diff --git a/src/AppInstallerCommonCore/Public/winget/UserSettings.h b/src/AppInstallerCommonCore/Public/winget/UserSettings.h index 6eb4be16e6..bb08ba4c22 100644 --- a/src/AppInstallerCommonCore/Public/winget/UserSettings.h +++ b/src/AppInstallerCommonCore/Public/winget/UserSettings.h @@ -76,7 +76,6 @@ namespace AppInstaller::Settings NetworkDOProgressTimeoutInSeconds, InstallLocalePreference, InstallLocaleRequirement, - EFPackagedAPI, EFDirectMSI, Max }; @@ -124,7 +123,6 @@ namespace AppInstaller::Settings SETTINGMAPPING_SPECIALIZATION(Setting::NetworkDOProgressTimeoutInSeconds, uint32_t, std::chrono::seconds, 60s, ".network.doProgressTimeoutInSeconds"sv); SETTINGMAPPING_SPECIALIZATION(Setting::InstallLocalePreference, std::vector, std::vector, {}, ".installBehavior.preferences.locale"sv); SETTINGMAPPING_SPECIALIZATION(Setting::InstallLocaleRequirement, std::vector, std::vector, {}, ".installBehavior.requirements.locale"sv); - SETTINGMAPPING_SPECIALIZATION(Setting::EFPackagedAPI, bool, bool, false, ".experimentalFeatures.packagedAPI"sv); SETTINGMAPPING_SPECIALIZATION(Setting::EFDirectMSI, bool, bool, false, ".experimentalFeatures.directMSI"sv); // Used to deduce the SettingVariant type; making a variant that includes std::monostate and all SettingMapping types. diff --git a/src/AppInstallerCommonCore/Public/winget/Yaml.h b/src/AppInstallerCommonCore/Public/winget/Yaml.h index 7f58b858af..9c8e0d5007 100644 --- a/src/AppInstallerCommonCore/Public/winget/Yaml.h +++ b/src/AppInstallerCommonCore/Public/winget/Yaml.h @@ -194,6 +194,7 @@ namespace AppInstaller::YAML Emitter& operator<<(EmitterEvent event); Emitter& operator<<(std::string_view value); Emitter& operator<<(int64_t value); + Emitter& operator<<(int value); Emitter& operator<<(bool value); // Gets the result of the emitter; can only be retrieved once. diff --git a/src/AppInstallerCommonCore/Runtime.cpp b/src/AppInstallerCommonCore/Runtime.cpp index 667bc39a39..7875cee0e1 100644 --- a/src/AppInstallerCommonCore/Runtime.cpp +++ b/src/AppInstallerCommonCore/Runtime.cpp @@ -220,6 +220,12 @@ namespace AppInstaller::Runtime return LocIndString{ strstr.str() }; } + + std::string GetOSRegion() + { + winrt::Windows::Globalization::GeographicRegion region; + return Utility::ConvertToUTF8(region.CodeTwoLetter()); + } #endif std::filesystem::path GetPathTo(PathName path) diff --git a/src/AppInstallerCommonCore/Telemetry/TraceLogging.cpp b/src/AppInstallerCommonCore/Telemetry/TraceLogging.cpp index f069f08e5c..22826f886b 100644 --- a/src/AppInstallerCommonCore/Telemetry/TraceLogging.cpp +++ b/src/AppInstallerCommonCore/Telemetry/TraceLogging.cpp @@ -15,6 +15,15 @@ bool g_IsTelemetryProviderEnabled{}; UCHAR g_TelemetryProviderLevel{}; ULONGLONG g_TelemetryProviderMatchAnyKeyword{}; +struct TraceProvider +{ + TraceProvider(); + + ~TraceProvider(); +}; + +TraceProvider g_TraceProvider{}; + void WINAPI TelemetryProviderEnabledCallback( _In_ LPCGUID /*sourceId*/, _In_ ULONG isEnabled, @@ -29,12 +38,12 @@ void WINAPI TelemetryProviderEnabledCallback( g_TelemetryProviderMatchAnyKeyword = matchAnyKeyword; } -void RegisterTraceLogging() +TraceProvider::TraceProvider() { TraceLoggingRegisterEx(g_hTraceProvider, TelemetryProviderEnabledCallback, nullptr); } -void UnRegisterTraceLogging() +TraceProvider::~TraceProvider() { TraceLoggingUnregister(g_hTraceProvider); } diff --git a/src/AppInstallerCommonCore/Telemetry/TraceLogging.h b/src/AppInstallerCommonCore/Telemetry/TraceLogging.h index 8b3eb2065e..e487389600 100644 --- a/src/AppInstallerCommonCore/Telemetry/TraceLogging.h +++ b/src/AppInstallerCommonCore/Telemetry/TraceLogging.h @@ -63,7 +63,4 @@ TRACELOGGING_DECLARE_PROVIDER(g_hTraceProvider); extern bool g_IsTelemetryProviderEnabled; extern UCHAR g_TelemetryProviderLevel; -extern ULONGLONG g_TelemetryProviderMatchAnyKeyword; - -extern void RegisterTraceLogging(); -extern void UnRegisterTraceLogging(); +extern ULONGLONG g_TelemetryProviderMatchAnyKeyword; \ No newline at end of file diff --git a/src/AppInstallerCommonCore/ThreadGlobals.cpp b/src/AppInstallerCommonCore/ThreadGlobals.cpp new file mode 100644 index 0000000000..a93822beb4 --- /dev/null +++ b/src/AppInstallerCommonCore/ThreadGlobals.cpp @@ -0,0 +1,74 @@ +#include "pch.h" +#include "Public/winget/ThreadGlobals.h" + +namespace AppInstaller::ThreadLocalStorage +{ + using namespace AppInstaller::Logging; + + // Set and return Globals for Current Thread + static ThreadGlobals* SetOrGetThreadGlobals(bool setThreadGlobals, ThreadGlobals* pThreadGlobals = nullptr); + + DiagnosticLogger& ThreadGlobals::GetDiagnosticLogger() + { + return *(m_pDiagnosticLogger); + } + + TelemetryTraceLogger& ThreadGlobals::GetTelemetryLogger() + { + return *(m_pTelemetryLogger); + } + + std::unique_ptr ThreadGlobals::SetForCurrentThread() + { + Initialize(); + + std::unique_ptr p_prevThreadGlobals = std::make_unique(SetOrGetThreadGlobals(true, this)); + + return p_prevThreadGlobals; + } + + void ThreadGlobals::Initialize() + { + try + { + std::call_once(loggerInitOnceFlag, [this]() + { + m_pDiagnosticLogger = std::make_unique(); + m_pTelemetryLogger = std::make_unique(); + + // The above make_unique for TelemetryTraceLogger will either create an object or will throw which is caught below. + m_pTelemetryLogger->Initialize(); + }); + } + catch (...) + { + // May throw std::system_error if any condition prevents calls to call_once from executing as specified + // May throw std::bad_alloc or any exception thrown by the constructor of TelemetryTraceLogger + // Loggers are best effort and shouldn't block core functionality. So eat up the exceptions here + } + } + + ThreadGlobals* ThreadGlobals::GetForCurrentThread() + { + return SetOrGetThreadGlobals(false); + } + + ThreadGlobals* SetOrGetThreadGlobals(bool setThreadGlobals, ThreadGlobals* pThreadGlobals) + { + thread_local AppInstaller::ThreadLocalStorage::ThreadGlobals* t_pThreadGlobals = nullptr; + + if (setThreadGlobals == true) + { + AppInstaller::ThreadLocalStorage::ThreadGlobals* previous_pThreadGlobals = t_pThreadGlobals; + t_pThreadGlobals = pThreadGlobals; + return previous_pThreadGlobals; + } + + return t_pThreadGlobals; + } + + PreviousThreadGlobals::~PreviousThreadGlobals() + { + std::ignore = SetOrGetThreadGlobals(true, m_previous); + } +} diff --git a/src/AppInstallerCommonCore/TraceLogger.cpp b/src/AppInstallerCommonCore/TraceLogger.cpp index 8a1289370f..798a88444e 100644 --- a/src/AppInstallerCommonCore/TraceLogger.cpp +++ b/src/AppInstallerCommonCore/TraceLogger.cpp @@ -3,6 +3,7 @@ #include "pch.h" #include "Public/winget/TraceLogger.h" #include "Public/AppInstallerTelemetry.h" +#include "Public/winget/ThreadGlobals.h" namespace AppInstaller::Logging { @@ -14,7 +15,7 @@ namespace AppInstaller::Logging TraceLoggingWriteActivity(g_hTraceProvider, "Diagnostics", - AppInstaller::Logging::GetActivityId(false), + nullptr, // TODO: ActivityId of the Global and COMContext telemetry to be logged in future nullptr, TraceLoggingString(strstr.str().c_str(), "LogMessage")); } diff --git a/src/AppInstallerCommonCore/UserSettings.cpp b/src/AppInstallerCommonCore/UserSettings.cpp index 194c333bcf..eb07d01fb3 100644 --- a/src/AppInstallerCommonCore/UserSettings.cpp +++ b/src/AppInstallerCommonCore/UserSettings.cpp @@ -227,7 +227,6 @@ namespace AppInstaller::Settings WINGET_VALIDATE_PASS_THROUGH(EFExperimentalMSStore) WINGET_VALIDATE_PASS_THROUGH(EFDependencies) WINGET_VALIDATE_PASS_THROUGH(TelemetryDisable) - WINGET_VALIDATE_PASS_THROUGH(EFPackagedAPI) WINGET_VALIDATE_PASS_THROUGH(EFDirectMSI) WINGET_VALIDATE_SIGNATURE(InstallScopePreference) diff --git a/src/AppInstallerCommonCore/Yaml.cpp b/src/AppInstallerCommonCore/Yaml.cpp index 29ea694142..023bba7c15 100644 --- a/src/AppInstallerCommonCore/Yaml.cpp +++ b/src/AppInstallerCommonCore/Yaml.cpp @@ -417,6 +417,13 @@ namespace AppInstaller::YAML return operator<<(stream.str()); } + Emitter& Emitter::operator<<(int value) + { + std::ostringstream stream; + stream << value; + return operator<<(stream.str()); + } + Emitter& Emitter::operator<<(bool value) { return operator<<(value ? "true"sv : "false"sv); diff --git a/src/AppInstallerCommonCore/pch.h b/src/AppInstallerCommonCore/pch.h index e32c72df1f..68cb4d9a6b 100644 --- a/src/AppInstallerCommonCore/pch.h +++ b/src/AppInstallerCommonCore/pch.h @@ -76,6 +76,7 @@ #include #include #include +#include #endif diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj index 5ae43e7652..95f31ab2ac 100644 --- a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj +++ b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj @@ -260,17 +260,19 @@ - - - + + + + + @@ -317,15 +319,18 @@ Create - - - - - - + + + + + + + + + diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters index 9ac4eae0f3..9d9d9a29ce 100644 --- a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters +++ b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters @@ -49,6 +49,12 @@ {15639b2c-ce61-4a18-995a-a73cf1a5817e} + + {9d8095ed-07de-4bc9-bfe7-630b781586d0} + + + {2cc20cdb-dcb2-4e0e-b04f-e2d838146100} + @@ -174,9 +180,6 @@ Rest\Schema - - Rest - Rest @@ -189,12 +192,6 @@ Rest\Schema - - Rest\Schema\1_0\Json - - - Rest\Schema\1_0\Json - Rest\Schema\1_0\Json @@ -219,6 +216,21 @@ Microsoft + + Rest\Schema + + + Rest\Schema + + + Rest\Schema\1_1 + + + Rest\Schema\1_1\Json + + + Rest\Schema\1_1\Json + @@ -296,12 +308,9 @@ Microsoft\Schema\1_2 - + Rest\Schema\1_0 - - Rest - Rest @@ -314,16 +323,13 @@ Rest\Schema - + Rest\Schema\1_0\Json - + Rest\Schema\1_0\Json - - Rest\Schema\1_0\Json - - + Rest\Schema\1_0\Json @@ -332,9 +338,24 @@ Microsoft\Schema\1_3 + + Rest\Schema + Microsoft + + Rest\Schema + + + Rest\Schema\1_1 + + + Rest\Schema\1_1\Json + + + Rest\Schema\1_1\Json + diff --git a/src/AppInstallerRepositoryCore/CompositeSource.h b/src/AppInstallerRepositoryCore/CompositeSource.h index 8fa8404987..2785093d3a 100644 --- a/src/AppInstallerRepositoryCore/CompositeSource.h +++ b/src/AppInstallerRepositoryCore/CompositeSource.h @@ -32,6 +32,9 @@ namespace AppInstaller::Repository // and thus the packages may come from disparate sources as well. bool IsComposite() const override { return true; } + // Gets the available sources if the source is composite. + std::vector> GetAvailableSources() const override { return m_availableSources; } + // Execute a search on the source. SearchResult Search(const SearchRequest& request) const override; diff --git a/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySearch.h b/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySearch.h index d9c96d85a5..0dc8471293 100644 --- a/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySearch.h +++ b/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySearch.h @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #pragma once +#include #include #include #include @@ -43,6 +44,8 @@ namespace AppInstaller::Repository PackageFamilyName, ProductCode, NormalizedNameAndPublisher, + Market, + Unknown = 9999 }; // A single match to be performed during a search. @@ -263,55 +266,33 @@ namespace AppInstaller::Repository bool Truncated = false; }; - inline std::string_view MatchTypeToString(MatchType type) + struct UnsupportedRequestException : public wil::ResultException { - using namespace std::string_view_literals; - - switch (type) - { - case MatchType::Exact: - return "Exact"sv; - case MatchType::CaseInsensitive: - return "CaseInsensitive"sv; - case MatchType::StartsWith: - return "StartsWith"sv; - case MatchType::Substring: - return "Substring"sv; - case MatchType::Wildcard: - return "Wildcard"sv; - case MatchType::Fuzzy: - return "Fuzzy"sv; - case MatchType::FuzzySubstring: - return "FuzzySubstring"sv; - } - - return "UnknownMatchType"sv; - } + UnsupportedRequestException() : wil::ResultException(APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST) {} + + UnsupportedRequestException( + std::vector unsupportedPackageMatchFields, + std::vector requiredPackageMatchFields, + std::vector unsupportedQueryParameters, + std::vector requiredQueryParameters) : + wil::ResultException(APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST), + UnsupportedPackageMatchFields(std::move(unsupportedPackageMatchFields)), RequiredPackageMatchFields(std::move(requiredPackageMatchFields)), + UnsupportedQueryParameters(std::move(unsupportedQueryParameters)), RequiredQueryParameters(std::move(requiredQueryParameters)) {} + + std::vector UnsupportedPackageMatchFields; + std::vector RequiredPackageMatchFields; + std::vector UnsupportedQueryParameters; + std::vector RequiredQueryParameters; + + const char* what() const noexcept override; + + private: + mutable std::string m_whatMessage; + }; - inline std::string_view PackageMatchFieldToString(PackageMatchField matchField) - { - using namespace std::string_view_literals; + std::string_view MatchTypeToString(MatchType type); - switch (matchField) - { - case PackageMatchField::Command: - return "Command"sv; - case PackageMatchField::Id: - return "Id"sv; - case PackageMatchField::Moniker: - return "Moniker"sv; - case PackageMatchField::Name: - return "Name"sv; - case PackageMatchField::Tag: - return "Tag"sv; - case PackageMatchField::PackageFamilyName: - return "PackageFamilyName"sv; - case PackageMatchField::ProductCode: - return "ProductCode"sv; - case PackageMatchField::NormalizedNameAndPublisher: - return "NormalizedNameAndPublisher"sv; - } + std::string_view PackageMatchFieldToString(PackageMatchField matchField); - return "UnknownMatchField"sv; - } + PackageMatchField StringToPackageMatchField(std::string_view field); } diff --git a/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySource.h b/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySource.h index 749368f6cc..3f686f597c 100644 --- a/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySource.h +++ b/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySource.h @@ -36,6 +36,38 @@ namespace AppInstaller::Repository std::string_view ToString(SourceOrigin origin); + // Individual source agreement entry. Label will be highlighted in the display as the key of the agreement entry. + struct SourceAgreement + { + std::string Label; + std::string Text; + std::string Url; + + SourceAgreement(std::string label, std::string text, std::string url) : + Label(std::move(label)), Text(std::move(text)), Url(std::move(url)) {} + }; + + struct SourceInformation + { + // Identifier of the source agreements. This is used to identify if source agreements have changed. + std::string SourceAgreementsIdentifier; + + // List of source agreements that require user to accept. + std::vector SourceAgreements; + + // Unsupported match fields in search request. If this field is in the filters, the request may fail. + std::vector UnsupportedPackageMatchFields; + + // Required match fields in search request. If this field is not found in the filters, the request may fail(except Market). + std::vector RequiredPackageMatchFields; + + // Unsupported query parameters in get manifest request. + std::vector UnsupportedQueryParameters; + + // Required query parameters in get manifest request. + std::vector RequiredQueryParameters; + }; + // Interface for retrieving information about a source without acting on it. struct SourceDetails { @@ -64,12 +96,26 @@ namespace AppInstaller::Repository SourceTrustLevel TrustLevel = SourceTrustLevel::None; // Whether the source behavior has restrictions - bool Restricted = false; + bool Restricted = false; // Custom header for Rest sources std::optional CustomHeader; + + // Source information containing source agreements, required/unsupported match fields. + SourceInformation Information; + }; + + // Fields that require user agreements. + enum class ImplicitAgreementFieldEnum : int + { + None = 0x0, + Market = 0x1, }; + DEFINE_ENUM_FLAG_OPERATORS(ImplicitAgreementFieldEnum); + + ImplicitAgreementFieldEnum GetAgreementFieldsFromSourceInformation(const SourceInformation& info); + // Interface for interacting with a source from outside of the repository lib. struct ISource { @@ -88,6 +134,9 @@ namespace AppInstaller::Repository // and thus the packages may come from disparate sources as well. virtual bool IsComposite() const { return false; } + // Gets the available sources if the source is composite. + virtual std::vector> GetAvailableSources() const { return {}; } + // Execute a search on the source. virtual SearchResult Search(const SearchRequest& request) const = 0; }; @@ -197,4 +246,10 @@ namespace AppInstaller::Repository // Checks if a source supports passing custom header. bool SupportsCustomHeader(const SourceDetails& sourceDetails); + + // Checks the source agreements and returns if agreements are satisfied. + bool CheckSourceAgreements(const SourceDetails& source); + + // Saves the accepted source agreements in metadata. + void SaveAcceptedSourceAgreements(const SourceDetails& source); } diff --git a/src/AppInstallerRepositoryCore/RepositorySource.cpp b/src/AppInstallerRepositoryCore/RepositorySource.cpp index 81341653e2..c5f7ef765c 100644 --- a/src/AppInstallerRepositoryCore/RepositorySource.cpp +++ b/src/AppInstallerRepositoryCore/RepositorySource.cpp @@ -30,6 +30,8 @@ namespace AppInstaller::Repository constexpr std::string_view s_MetadataYaml_Sources = "Sources"sv; constexpr std::string_view s_MetadataYaml_Source_Name = "Name"sv; constexpr std::string_view s_MetadataYaml_Source_LastUpdate = "LastUpdate"sv; + constexpr std::string_view s_MetadataYaml_Source_AcceptedAgreementsIdentifier = "AcceptedAgreementsIdentifier"sv; + constexpr std::string_view s_MetadataYaml_Source_AcceptedAgreementFields = "AcceptedAgreementFields"sv; constexpr std::string_view s_Source_WingetCommunityDefault_Name = "winget"sv; constexpr std::string_view s_Source_WingetCommunityDefault_Arg = "https://winget.azureedge.net/cache"sv; @@ -58,6 +60,10 @@ namespace AppInstaller::Repository // If true, this is a tombstone, marking the deletion of a source at a lower priority origin. bool IsTombstone = false; + std::string AcceptedAgreementsIdentifier; + + int AcceptedAgreementFields = 0; + SourceDetailsInternal() = default; SourceDetailsInternal(const SourceDetails& details) : SourceDetails(details) {}; @@ -449,6 +455,8 @@ namespace AppInstaller::Repository int64_t lastUpdateInEpoch{}; if (!TryReadScalar(name, settingValue, source, s_MetadataYaml_Source_LastUpdate, lastUpdateInEpoch)) { return false; } details.LastUpdateTime = Utility::ConvertUnixEpochToSystemClock(lastUpdateInEpoch); + TryReadScalar(name, settingValue, source, s_MetadataYaml_Source_AcceptedAgreementsIdentifier, details.AcceptedAgreementsIdentifier, false); + TryReadScalar(name, settingValue, source, s_MetadataYaml_Source_AcceptedAgreementFields, details.AcceptedAgreementFields, false); return true; }); } @@ -520,7 +528,7 @@ namespace AppInstaller::Repository if (!TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Arg, details.Arg)) { return false; } if (!TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Data, details.Data)) { return false; } if (!TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_IsTombstone, details.IsTombstone)) { return false; } - TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Identifier, details.Identifier); + TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Identifier, details.Identifier, false); return true; }); @@ -614,6 +622,8 @@ namespace AppInstaller::Repository out << YAML::BeginMap; out << YAML::Key << s_MetadataYaml_Source_Name << YAML::Value << details.Name; out << YAML::Key << s_MetadataYaml_Source_LastUpdate << YAML::Value << Utility::ConvertSystemClockToUnixEpoch(details.LastUpdateTime); + out << YAML::Key << s_MetadataYaml_Source_AcceptedAgreementsIdentifier << YAML::Value << details.AcceptedAgreementsIdentifier; + out << YAML::Key << s_MetadataYaml_Source_AcceptedAgreementFields << YAML::Value << details.AcceptedAgreementFields; out << YAML::EndMap; } @@ -777,11 +787,14 @@ namespace AppInstaller::Repository void AddSource(const SourceDetailsInternal& source); void RemoveSource(const SourceDetailsInternal& source); - void UpdateSourceLastUpdateTime(const SourceDetails& source); - // Save source metadata. Currently only LastTimeUpdated is used. void SaveMetadata() const; + bool CheckSourceAgreements(const SourceDetails& details); + + // SaveMetadata() should be called after all accepted source agreements are updated. + void SaveAcceptedSourceAgreements(const SourceDetails& details); + private: std::vector m_sourceList; @@ -818,6 +831,8 @@ namespace AppInstaller::Repository if (source) { source->LastUpdateTime = metaSource.LastUpdateTime; + source->AcceptedAgreementFields = metaSource.AcceptedAgreementFields; + source->AcceptedAgreementsIdentifier = metaSource.AcceptedAgreementsIdentifier; } } } @@ -909,6 +924,69 @@ namespace AppInstaller::Repository { SetMetadata(m_sourceList); } + + bool SourceListInternal::CheckSourceAgreements(const SourceDetails& details) + { + auto agreementFields = GetAgreementFieldsFromSourceInformation(details.Information); + + if (agreementFields == ImplicitAgreementFieldEnum::None && details.Information.SourceAgreementsIdentifier.empty()) + { + // No agreements to be accepted. + return true; + } + + auto detailsInternal = GetCurrentSource(details.Name); + if (!detailsInternal) + { + // Source not found. + return false; + } + + return static_cast(agreementFields) == detailsInternal->AcceptedAgreementFields && + details.Information.SourceAgreementsIdentifier == detailsInternal->AcceptedAgreementsIdentifier; + } + + void SourceListInternal::SaveAcceptedSourceAgreements(const SourceDetails& details) + { + auto agreementFields = GetAgreementFieldsFromSourceInformation(details.Information); + + if (agreementFields == ImplicitAgreementFieldEnum::None && details.Information.SourceAgreementsIdentifier.empty()) + { + // No agreements to be accepted. + return; + } + + auto detailsInternal = GetCurrentSource(details.Name); + if (!detailsInternal) + { + // No source to update. + return; + } + + detailsInternal->AcceptedAgreementFields = static_cast(agreementFields); + detailsInternal->AcceptedAgreementsIdentifier = details.Information.SourceAgreementsIdentifier; + + SaveMetadata(); + } + + std::string GetStringVectorMessage(const std::vector& input) + { + std::string result; + bool first = true; + for (auto const& field : input) + { + if (first) + { + result += field; + first = false; + } + else + { + result += ", " + field; + } + } + return result; + } } std::string_view ToString(SourceOrigin origin) @@ -926,6 +1004,19 @@ namespace AppInstaller::Repository } } + ImplicitAgreementFieldEnum GetAgreementFieldsFromSourceInformation(const SourceInformation& info) + { + ImplicitAgreementFieldEnum result = ImplicitAgreementFieldEnum::None; + + if (info.RequiredPackageMatchFields.end() != std::find_if(info.RequiredPackageMatchFields.begin(), info.RequiredPackageMatchFields.end(), [&](const auto& field) { return Utility::CaseInsensitiveEquals(field, "market"); }) || + info.RequiredQueryParameters.end() != std::find_if(info.RequiredQueryParameters.begin(), info.RequiredQueryParameters.end(), [&](const auto& param) { return Utility::CaseInsensitiveEquals(param, "market"); })) + { + WI_SetFlag(result, ImplicitAgreementFieldEnum::Market); + } + + return result; + } + std::vector GetSources() { SourceListInternal sourceList; @@ -1305,6 +1396,18 @@ namespace AppInstaller::Repository return Utility::CaseInsensitiveEquals(Rest::RestSourceFactory::Type(), sourceDetails.Type); } + bool CheckSourceAgreements(const SourceDetails& source) + { + SourceListInternal sourceList; + return sourceList.CheckSourceAgreements(source); + } + + void SaveAcceptedSourceAgreements(const SourceDetails& source) + { + SourceListInternal sourceList; + sourceList.SaveAcceptedSourceAgreements(source); + } + bool SearchRequest::IsForEverything() const { return (!Query.has_value() && Inclusions.empty() && Filters.empty()); @@ -1362,6 +1465,130 @@ namespace AppInstaller::Repository } } + const char* UnsupportedRequestException::what() const noexcept + { + if (m_whatMessage.empty()) + { + m_whatMessage = "The request is not supported."; + + if (!UnsupportedPackageMatchFields.empty()) + { + m_whatMessage += "Unsupported Package Match Fields: " + GetStringVectorMessage(UnsupportedPackageMatchFields); + } + if (!RequiredPackageMatchFields.empty()) + { + m_whatMessage += "Required Package Match Fields: " + GetStringVectorMessage(RequiredPackageMatchFields); + } + if (!UnsupportedQueryParameters.empty()) + { + m_whatMessage += "Unsupported Query Parameters: " + GetStringVectorMessage(UnsupportedQueryParameters); + } + if (!RequiredQueryParameters.empty()) + { + m_whatMessage += "Required Query Parameters: " + GetStringVectorMessage(RequiredQueryParameters); + } + } + return m_whatMessage.c_str(); + } + + std::string_view MatchTypeToString(MatchType type) + { + using namespace std::string_view_literals; + + switch (type) + { + case MatchType::Exact: + return "Exact"sv; + case MatchType::CaseInsensitive: + return "CaseInsensitive"sv; + case MatchType::StartsWith: + return "StartsWith"sv; + case MatchType::Substring: + return "Substring"sv; + case MatchType::Wildcard: + return "Wildcard"sv; + case MatchType::Fuzzy: + return "Fuzzy"sv; + case MatchType::FuzzySubstring: + return "FuzzySubstring"sv; + } + + return "UnknownMatchType"sv; + } + + std::string_view PackageMatchFieldToString(PackageMatchField matchField) + { + using namespace std::string_view_literals; + + switch (matchField) + { + case PackageMatchField::Command: + return "Command"sv; + case PackageMatchField::Id: + return "Id"sv; + case PackageMatchField::Moniker: + return "Moniker"sv; + case PackageMatchField::Name: + return "Name"sv; + case PackageMatchField::Tag: + return "Tag"sv; + case PackageMatchField::PackageFamilyName: + return "PackageFamilyName"sv; + case PackageMatchField::ProductCode: + return "ProductCode"sv; + case PackageMatchField::NormalizedNameAndPublisher: + return "NormalizedNameAndPublisher"sv; + case PackageMatchField::Market: + return "Market"sv; + } + + return "UnknownMatchField"sv; + } + + PackageMatchField StringToPackageMatchField(std::string_view field) + { + std::string toLower = Utility::ToLower(field); + + if (toLower == "command") + { + return PackageMatchField::Command; + } + else if (toLower == "id") + { + return PackageMatchField::Id; + } + else if (toLower == "moniker") + { + return PackageMatchField::Moniker; + } + else if (toLower == "name") + { + return PackageMatchField::Name; + } + else if (toLower == "tag") + { + return PackageMatchField::Tag; + } + else if (toLower == "packagefamilyname") + { + return PackageMatchField::PackageFamilyName; + } + else if (toLower == "productcode") + { + return PackageMatchField::ProductCode; + } + else if (toLower == "normalizednameandpublisher") + { + return PackageMatchField::NormalizedNameAndPublisher; + } + else if (toLower == "market") + { + return PackageMatchField::Market; + } + + return PackageMatchField::Unknown; + } + #ifndef AICLI_DISABLE_TEST_HOOKS void TestHook_SetSourceFactoryOverride(const std::string& type, std::function()>&& factory) { diff --git a/src/AppInstallerRepositoryCore/Rest/RestClient.cpp b/src/AppInstallerRepositoryCore/Rest/RestClient.cpp index 1965d25fb0..a019ef91dd 100644 --- a/src/AppInstallerRepositoryCore/Rest/RestClient.cpp +++ b/src/AppInstallerRepositoryCore/Rest/RestClient.cpp @@ -3,24 +3,24 @@ #include "pch.h" #include "RestClient.h" #include "Rest/Schema/1_0/Interface.h" -#include "Rest/HttpClientHelper.h" -#include "Rest/Schema/1_0/Json/InformationResponseDeserializer.h" +#include "Rest/Schema/1_1/Interface.h" +#include "Rest/Schema/HttpClientHelper.h" +#include "Rest/Schema/InformationResponseDeserializer.h" #include "Rest/Schema/JsonHelper.h" -#include "Rest/Schema/1_0/Json/CommonJsonConstants.h" #include "Rest/Schema/CommonRestConstants.h" #include "Rest/Schema/RestHelper.h" using namespace AppInstaller::Repository::Rest::Schema; using namespace AppInstaller::Repository::Rest::Schema::V1_0; -using namespace AppInstaller::Repository::Rest::Schema::V1_0::Json; using namespace AppInstaller::Utility; namespace AppInstaller::Repository::Rest { // Supported versions - std::set WingetSupportedContracts = { Version_1_0_0 }; + std::set WingetSupportedContracts = { Version_1_0_0, Version_1_1_0 }; constexpr std::string_view WindowsPackageManagerHeader = "Windows-Package-Manager"sv; + constexpr size_t WindowsPackageManagerHeaderMaxLength = 1024; namespace { std::unordered_map GetHeaders(std::optional customHeader) @@ -31,6 +31,8 @@ namespace AppInstaller::Repository::Rest return {}; } + THROW_HR_IF(APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH, customHeader.value().size() > WindowsPackageManagerHeaderMaxLength); + std::unordered_map headers; headers.emplace(JsonHelper::GetUtilityString(WindowsPackageManagerHeader), JsonHelper::GetUtilityString(customHeader.value())); return headers; @@ -47,7 +49,7 @@ namespace AppInstaller::Repository::Rest return m_interface->GetManifestByVersion(packageId, version, channel); } - RestClient::SearchResult RestClient::Search(const SearchRequest& request) const + IRestClient::SearchResult RestClient::Search(const SearchRequest& request) const { return m_interface->Search(request); } @@ -57,36 +59,52 @@ namespace AppInstaller::Repository::Rest return m_sourceIdentifier; } - utility::string_t RestClient::GetInformationEndpoint(const utility::string_t& restApiUri) + IRestClient::Information RestClient::GetSourceInformation() const { - utility::string_t endpoint = RestHelper::AppendPathToUri(restApiUri, JsonHelper::GetUtilityString(InformationGetEndpoint)); - return endpoint; + return m_interface->GetSourceInformation(); } IRestClient::Information RestClient::GetInformation( const utility::string_t& restApi, const std::unordered_map& additionalHeaders, const HttpClientHelper& clientHelper) { // Call information endpoint - std::optional response = clientHelper.HandleGet(GetInformationEndpoint(restApi), additionalHeaders); + utility::string_t endpoint = RestHelper::AppendPathToUri(restApi, JsonHelper::GetUtilityString(InformationGetEndpoint)); + std::optional response = clientHelper.HandleGet(endpoint, additionalHeaders); THROW_HR_IF(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, !response); - Json::InformationResponseDeserializer responseDeserializer; + InformationResponseDeserializer responseDeserializer; IRestClient::Information information = responseDeserializer.Deserialize(response.value()); return information; } std::optional RestClient::GetLatestCommonVersion( - const IRestClient::Information& information, const std::set& wingetSupportedVersions) + const std::vector& serverSupportedVersions, + const std::set& wingetSupportedVersions) { std::set commonVersions; - for (auto& version : information.ServerSupportedVersions) + for (auto& version : serverSupportedVersions) { Version versionInfo(version); - if (wingetSupportedVersions.find(versionInfo) != wingetSupportedVersions.end()) + auto itr = std::find_if(wingetSupportedVersions.begin(), wingetSupportedVersions.end(), + [&](const Version& v) + { + // Only check major and minor version match if applicable + if (v.GetParts().size() >= 2) + { + return versionInfo.GetParts().size() >= 2 && + versionInfo.GetParts().at(0) == v.GetParts().at(0) && + versionInfo.GetParts().at(1) == v.GetParts().at(1); + } + else + { + return versionInfo == v; + } + }); + if (itr != wingetSupportedVersions.end()) { - commonVersions.insert(std::move(versionInfo)); + commonVersions.insert(*itr); } } @@ -99,15 +117,19 @@ namespace AppInstaller::Repository::Rest } std::unique_ptr RestClient::GetSupportedInterface( - const std::string& api, const std::unordered_map& additionalHeaders, const Version& version) + const std::string& api, + const std::unordered_map& additionalHeaders, + const IRestClient::Information& information, + const Version& version) { if (version == Version_1_0_0) { return std::make_unique(api); } - - // TODO: USE additionalHeaders with V1.1 changes. - (void)additionalHeaders; + else if (version == Version_1_1_0) + { + return std::make_unique(api, information, additionalHeaders); + } THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION); } @@ -120,10 +142,10 @@ namespace AppInstaller::Repository::Rest auto headers = GetHeaders(customHeader); IRestClient::Information information = GetInformation(restEndpoint, headers, helper); - std::optional latestCommonVersion = GetLatestCommonVersion(information, WingetSupportedContracts); + std::optional latestCommonVersion = GetLatestCommonVersion(information.ServerSupportedVersions, WingetSupportedContracts); THROW_HR_IF(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, !latestCommonVersion); - std::unique_ptr supportedInterface = GetSupportedInterface(utility::conversions::to_utf8string(restEndpoint), headers, latestCommonVersion.value()); + std::unique_ptr supportedInterface = GetSupportedInterface(utility::conversions::to_utf8string(restEndpoint), headers, information, latestCommonVersion.value()); return RestClient{ std::move(supportedInterface), information.SourceIdentifier }; } } diff --git a/src/AppInstallerRepositoryCore/Rest/RestClient.h b/src/AppInstallerRepositoryCore/Rest/RestClient.h index 420b126546..de05fbbbe7 100644 --- a/src/AppInstallerRepositoryCore/Rest/RestClient.h +++ b/src/AppInstallerRepositoryCore/Rest/RestClient.h @@ -4,7 +4,7 @@ #include #include #include "Rest/Schema/IRestClient.h" -#include "Rest/HttpClientHelper.h" +#include "Rest/Schema/HttpClientHelper.h" #include "cpprest/json.h" #include "AppInstallerRepositorySource.h" @@ -12,11 +12,6 @@ namespace AppInstaller::Repository::Rest { struct RestClient { - RestClient(std::unique_ptr supportedInterface, std::string sourceIdentifier); - - // The return type of Search - using SearchResult = Rest::Schema::IRestClient::SearchResult; - RestClient(const RestClient&) = delete; RestClient& operator=(const RestClient&) = delete; @@ -30,16 +25,18 @@ namespace AppInstaller::Repository::Rest std::string GetSourceIdentifier() const; - static std::optional GetLatestCommonVersion(const AppInstaller::Repository::Rest::Schema::IRestClient::Information& information, const std::set& wingetSupportedVersions); + Schema::IRestClient::Information GetSourceInformation() const; - static utility::string_t GetInformationEndpoint(const utility::string_t& restApiUri); + static std::optional GetLatestCommonVersion(const std::vector& serverSupportedVersions, const std::set& wingetSupportedVersions); - static Schema::IRestClient::Information GetInformation(const utility::string_t& restApi, const std::unordered_map& additionalHeaders, const HttpClientHelper& httpClientHelper); + static Schema::IRestClient::Information GetInformation(const utility::string_t& restApi, const std::unordered_map& additionalHeaders, const Schema::HttpClientHelper& httpClientHelper); - static std::unique_ptr GetSupportedInterface(const std::string& restApi, const std::unordered_map& additionalHeaders, const AppInstaller::Utility::Version& version); + static std::unique_ptr GetSupportedInterface(const std::string& restApi, const std::unordered_map& additionalHeaders, const Schema::IRestClient::Information& information, const AppInstaller::Utility::Version& version); - static RestClient Create(const std::string& restApi, std::optional customHeader, const HttpClientHelper & helper = {}); + static RestClient Create(const std::string& restApi, std::optional customHeader, const Schema::HttpClientHelper& helper = {}); private: + RestClient(std::unique_ptr supportedInterface, std::string sourceIdentifier); + std::unique_ptr m_interface; std::string m_sourceIdentifier; }; diff --git a/src/AppInstallerRepositoryCore/Rest/RestSource.cpp b/src/AppInstallerRepositoryCore/Rest/RestSource.cpp index e4d6b45eea..40d26ff600 100644 --- a/src/AppInstallerRepositoryCore/Rest/RestSource.cpp +++ b/src/AppInstallerRepositoryCore/Rest/RestSource.cpp @@ -315,6 +315,18 @@ namespace AppInstaller::Repository::Rest : m_details(details), m_restClient(std::move(restClient)) { m_details.Identifier = std::move(identifier); + + const auto& sourceInformation = m_restClient.GetSourceInformation(); + m_details.Information.UnsupportedPackageMatchFields = sourceInformation.UnsupportedPackageMatchFields; + m_details.Information.RequiredPackageMatchFields = sourceInformation.RequiredPackageMatchFields; + m_details.Information.UnsupportedQueryParameters = sourceInformation.UnsupportedQueryParameters; + m_details.Information.RequiredQueryParameters = sourceInformation.RequiredQueryParameters; + + m_details.Information.SourceAgreementsIdentifier = sourceInformation.SourceAgreementsIdentifier; + for (auto const& agreement : sourceInformation.SourceAgreements) + { + m_details.Information.SourceAgreements.emplace_back(agreement.Label, agreement.Text, agreement.Url); + } } const SourceDetails& RestSource::GetDetails() const @@ -334,7 +346,7 @@ namespace AppInstaller::Repository::Rest SearchResult RestSource::Search(const SearchRequest& request) const { - RestClient::SearchResult results = m_restClient.Search(request); + IRestClient::SearchResult results = m_restClient.Search(request); SearchResult searchResult; std::shared_ptr sharedThis = shared_from_this(); @@ -348,6 +360,8 @@ namespace AppInstaller::Repository::Rest searchResult.Matches.emplace_back(std::move(package), std::move(packageFilter)); } + searchResult.Truncated = results.Truncated; + return searchResult; } diff --git a/src/AppInstallerRepositoryCore/Rest/RestSourceFactory.cpp b/src/AppInstallerRepositoryCore/Rest/RestSourceFactory.cpp index 6ff191f2d2..11bf4d7984 100644 --- a/src/AppInstallerRepositoryCore/Rest/RestSourceFactory.cpp +++ b/src/AppInstallerRepositoryCore/Rest/RestSourceFactory.cpp @@ -13,7 +13,7 @@ namespace AppInstaller::Repository::Rest namespace { // The base class for data that comes from a rest based source. - struct RestSourceFactoryBase : public ISourceFactory + struct RestSourceFactoryImpl : public ISourceFactory { std::shared_ptr Create(const SourceDetails& details, IProgressCallback&) override final { @@ -58,6 +58,6 @@ namespace AppInstaller::Repository::Rest std::unique_ptr RestSourceFactory::Create() { - return std::make_unique(); + return std::make_unique(); } } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.h index de12531417..43c592e888 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.h @@ -2,10 +2,8 @@ // Licensed under the MIT License. #pragma once #include "Rest/Schema/IRestClient.h" +#include "Rest/Schema/HttpClientHelper.h" #include -#include "cpprest/json.h" -#include "Rest/HttpClientHelper.h" -#include namespace AppInstaller::Repository::Rest::Schema::V1_0 { @@ -21,19 +19,30 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 Interface& operator=(Interface&&) = default; Utility::Version GetVersion() const override; + IRestClient::Information GetSourceInformation() const override; IRestClient::SearchResult Search(const SearchRequest& request) const override; std::optional GetManifestByVersion(const std::string& packageId, const std::string& version, const std::string& channel) const override; std::vector GetManifests(const std::string& packageId, const std::map& params = {}) const override; - + protected: bool MeetsOptimizedSearchCriteria(const SearchRequest& request) const; IRestClient::SearchResult OptimizedSearch(const SearchRequest& request) const; IRestClient::SearchResult SearchInternal(const SearchRequest& request) const; + // Check query params against source information and update if necessary. + virtual std::map GetValidatedQueryParams(const std::map& params) const; + + // Check search request against source information and get json search body. + virtual web::json::value GetValidatedSearchBody(const SearchRequest& searchRequest) const; + + virtual SearchResult GetSearchResult(const web::json::value& searchResponseObject) const; + virtual std::vector GetParsedManifests(const web::json::value& manifestsResponseObject) const; + + std::unordered_map m_requiredRestApiHeaders; + private: std::string m_restApiUri; utility::string_t m_searchEndpoint; - std::unordered_map m_requiredRestApiHeaders; HttpClientHelper m_httpClientHelper; }; } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/CommonJsonConstants.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/CommonJsonConstants.h deleted file mode 100644 index 462c94db89..0000000000 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/CommonJsonConstants.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once -#include - -namespace AppInstaller::Repository::Rest::Schema::V1_0::Json -{ - // General API response constants - constexpr std::string_view Data = "Data"sv; - constexpr std::string_view ContinuationToken = "ContinuationToken"sv; - - // General API Header constant - constexpr std::string_view ContractVersion = "Version"sv; - - // General endpoint constants - constexpr std::string_view InformationGetEndpoint = "/information"sv; -} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/InformationResponseDeserializer.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/InformationResponseDeserializer.cpp deleted file mode 100644 index e842462409..0000000000 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/InformationResponseDeserializer.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include "Rest/Schema/IRestClient.h" -#include "Rest/Schema/JsonHelper.h" -#include "InformationResponseDeserializer.h" -#include "CommonJsonConstants.h" - -namespace AppInstaller::Repository::Rest::Schema::V1_0::Json -{ - namespace - { - // Information response constants - constexpr std::string_view SourceIdentifier = "SourceIdentifier"sv; - constexpr std::string_view ServerSupportedVersions = "ServerSupportedVersions"sv; - } - - IRestClient::Information InformationResponseDeserializer::Deserialize(const web::json::value& dataObject) const - { - // Get information result from json output. - std::optional information = DeserializeInformation(dataObject); - - THROW_HR_IF(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, !information); - - return information.value(); - } - - std::optional InformationResponseDeserializer::DeserializeInformation(const web::json::value& dataObject) const - { - try - { - if (dataObject.is_null()) - { - AICLI_LOG(Repo, Error, << "Missing json object."); - return {}; - } - - std::optional> data = JsonHelper::GetJsonValueFromNode(dataObject, JsonHelper::GetUtilityString(Data)); - if (!data) - { - AICLI_LOG(Repo, Error, << "Missing data"); - return {}; - } - - auto& dataValue = data.value().get(); - std::optional sourceId = JsonHelper::GetRawStringValueFromJsonNode(dataValue, JsonHelper::GetUtilityString(SourceIdentifier)); - if (!JsonHelper::IsValidNonEmptyStringValue(sourceId)) - { - AICLI_LOG(Repo, Error, << "Missing source identifier"); - return {}; - } - - std::optional> versions = JsonHelper::GetRawJsonArrayFromJsonNode(dataValue, JsonHelper::GetUtilityString(ServerSupportedVersions)); - - if (!versions || versions.value().get().size() == 0) - { - AICLI_LOG(Repo, Error, << "Missing supported versions"); - return {}; - } - - std::vector allVersions; - for (auto& versionItem : versions.value().get()) - { - std::optional sp = JsonHelper::GetRawStringValueFromJsonValue(versionItem); - if (sp) - { - allVersions.emplace_back(std::move(sp.value())); - } - } - - if (allVersions.size() == 0) - { - AICLI_LOG(Repo, Error, << "Received incomplete information."); - return {}; - } - - IRestClient::Information info{ std::move(sourceId.value()), std::move(allVersions) }; - return info; - } - catch (const std::exception& e) - { - AICLI_LOG(Repo, Error, << "Error encountered while deserializing Information. Reason: " << e.what()); - } - catch (...) - { - AICLI_LOG(Repo, Error, << "Received invalid information."); - } - - return {}; - } -} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer.h index a61b6b6f65..586cc9198b 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer.h @@ -17,8 +17,10 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json std::optional DeserializeLocale(const web::json::value& localeJsonObject) const; - std::optional DeserializeInstaller(const web::json::value& installerJsonObject) const; + virtual std::optional DeserializeInstaller(const web::json::value& installerJsonObject) const; std::optional DeserializeDependency(const web::json::value& dependenciesJsonObject) const; + + virtual Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const; }; } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer_1_0.cpp similarity index 76% rename from src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer.cpp rename to src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer_1_0.cpp index 5e9fd361c4..c2adb8f4f9 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer_1_0.cpp @@ -3,10 +3,10 @@ #include "pch.h" #include "Rest/Schema/1_0/Interface.h" #include "Rest/Schema/IRestClient.h" -#include "Rest/HttpClientHelper.h" +#include "Rest/Schema/HttpClientHelper.h" #include "ManifestDeserializer.h" #include "Rest/Schema/JsonHelper.h" -#include "Rest/Schema/1_0/Json/CommonJsonConstants.h" +#include "Rest/Schema/CommonRestConstants.h" using namespace AppInstaller::Manifest; @@ -93,6 +93,31 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json return result; } + + template + void TryParseStringLocaleField(Manifest::ManifestLocalization& manifestLocale, const web::json::value& localeJsonObject, std::string_view localeJsonFieldName) + { + auto value = JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(localeJsonFieldName)); + + if (JsonHelper::IsValidNonEmptyStringValue(value)) + { + manifestLocale.Add(value.value()); + } + } + + void TryParseInstallerSwitchField( + std::map& installerSwitches, + InstallerSwitchType switchType, + const web::json::value& switchesJsonObject, + std::string_view switchJsonFieldName) + { + auto value = JsonHelper::GetRawStringValueFromJsonNode(switchesJsonObject, JsonHelper::GetUtilityString(switchJsonFieldName)); + + if (JsonHelper::IsValidNonEmptyStringValue(value)) + { + installerSwitches[switchType] = value.value(); + } + } } std::vector ManifestDeserializer::Deserialize(const web::json::value& dataJsonObject) const @@ -172,6 +197,15 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json AICLI_LOG(Repo, Error, << "Missing default locale in package: " << manifest.Id); return {}; } + + if (!defaultLocaleObject.value().Contains(Manifest::Localization::PackageName) || + !defaultLocaleObject.value().Contains(Manifest::Localization::Publisher) || + !defaultLocaleObject.value().Contains(Manifest::Localization::ShortDescription)) + { + AICLI_LOG(Repo, Error, << "Missing PackageName, Publisher or ShortDescription in default locale: " << manifest.Id); + return {}; + } + manifest.DefaultLocalization = std::move(defaultLocaleObject.value()); // Moniker is in Default locale @@ -248,41 +282,25 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json } locale.Locale = std::move(packageLocale.value()); - std::optional packageName = JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(PackageName)); - if (!JsonHelper::IsValidNonEmptyStringValue(packageName)) + TryParseStringLocaleField(locale, localeJsonObject, PackageName); + TryParseStringLocaleField(locale, localeJsonObject, Publisher); + TryParseStringLocaleField(locale, localeJsonObject, ShortDescription); + TryParseStringLocaleField(locale, localeJsonObject, PublisherUrl); + TryParseStringLocaleField(locale, localeJsonObject, PublisherSupportUrl); + TryParseStringLocaleField(locale, localeJsonObject, PrivacyUrl); + TryParseStringLocaleField(locale, localeJsonObject, Author); + TryParseStringLocaleField(locale, localeJsonObject, PackageUrl); + TryParseStringLocaleField(locale, localeJsonObject, License); + TryParseStringLocaleField(locale, localeJsonObject, LicenseUrl); + TryParseStringLocaleField(locale, localeJsonObject, Copyright); + TryParseStringLocaleField(locale, localeJsonObject, CopyrightUrl); + TryParseStringLocaleField(locale, localeJsonObject, Description); + + auto tags = ConvertToManifestStringArray(JsonHelper::GetRawStringArrayFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(Tags))); + if (!tags.empty()) { - AICLI_LOG(Repo, Error, << "Missing package name."); - return {}; + locale.Add(tags); } - locale.Add(std::move(packageName.value())); - - std::optional publisher = JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(Publisher)); - if (!JsonHelper::IsValidNonEmptyStringValue(publisher)) - { - AICLI_LOG(Repo, Error, << "Missing publisher."); - return {}; - } - locale.Add(std::move(publisher.value())); - - std::optional shortDescription = JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(ShortDescription)); - if (!JsonHelper::IsValidNonEmptyStringValue(shortDescription)) - { - AICLI_LOG(Repo, Error, << "Missing short description."); - return {}; - } - locale.Add(std::move(shortDescription.value())); - - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(PublisherUrl)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(PublisherSupportUrl)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(PrivacyUrl)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(Author)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(PackageUrl)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(License)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(LicenseUrl)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(Copyright)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(CopyrightUrl)).value_or("")); - locale.Add(JsonHelper::GetRawStringValueFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(Description)).value_or("")); - locale.Add(ConvertToManifestStringArray(JsonHelper::GetRawStringArrayFromJsonNode(localeJsonObject, JsonHelper::GetUtilityString(Tags)))); return locale; } @@ -295,21 +313,14 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json } Manifest::ManifestInstaller installer; - std::optional url = JsonHelper::GetRawStringValueFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(InstallerUrl)); - if (!JsonHelper::IsValidNonEmptyStringValue(url)) - { - AICLI_LOG(Repo, Error, << "Missing installer url."); - return {}; - } - installer.Url = std::move(url.value()); + + installer.Url = JsonHelper::GetRawStringValueFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(InstallerUrl)).value_or(""); std::optional sha256 = JsonHelper::GetRawStringValueFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(InstallerSha256)); - if (!JsonHelper::IsValidNonEmptyStringValue(sha256)) + if (JsonHelper::IsValidNonEmptyStringValue(sha256)) { - AICLI_LOG(Repo, Error, << "Missing installer SHA256."); - return {}; + installer.Sha256 = Utility::SHA256::ConvertToBytes(sha256.value()); } - installer.Sha256 = Utility::SHA256::ConvertToBytes(sha256.value()); std::optional arch = JsonHelper::GetRawStringValueFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(Architecture)); if (!JsonHelper::IsValidNonEmptyStringValue(arch)) @@ -325,7 +336,7 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json AICLI_LOG(Repo, Error, << "Missing installer type."); return {}; } - installer.InstallerType = Manifest::ConvertToInstallerTypeEnum(installerType.value()); + installer.InstallerType = ConvertToInstallerType(installerType.value()); installer.Locale = JsonHelper::GetRawStringValueFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(InstallerLocale)).value_or(""); // platform @@ -370,18 +381,19 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json } // Installer Switches + installer.Switches = Manifest::GetDefaultKnownSwitches(installer.InstallerType); std::optional> switches = JsonHelper::GetJsonValueFromNode(installerJsonObject, JsonHelper::GetUtilityString(InstallerSwitches)); if (switches) { - auto& installerSwitches = switches.value().get(); - installer.Switches[InstallerSwitchType::Silent] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Silent)).value_or(""); - installer.Switches[InstallerSwitchType::SilentWithProgress] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(SilentWithProgress)).value_or(""); - installer.Switches[InstallerSwitchType::Interactive] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Interactive)).value_or(""); - installer.Switches[InstallerSwitchType::InstallLocation] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(InstallLocation)).value_or(""); - installer.Switches[InstallerSwitchType::Log] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Log)).value_or(""); - installer.Switches[InstallerSwitchType::Update] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Upgrade)).value_or(""); - installer.Switches[InstallerSwitchType::Custom] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Custom)).value_or(""); + const auto& installerSwitches = switches.value().get(); + TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Silent, installerSwitches, Silent); + TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::SilentWithProgress, installerSwitches, SilentWithProgress); + TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Interactive, installerSwitches, Interactive); + TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::InstallLocation, installerSwitches, InstallLocation); + TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Log, installerSwitches, Log); + TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Update, installerSwitches, Upgrade); + TryParseInstallerSwitchField(installer.Switches, InstallerSwitchType::Custom, installerSwitches, Custom); } // Installer SuccessCodes @@ -472,4 +484,44 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json return dependencyList; } + + Manifest::InstallerTypeEnum ManifestDeserializer::ConvertToInstallerType(std::string_view in) const + { + std::string inStrLower = Utility::ToLower(in); + + if (inStrLower == "inno") + { + return InstallerTypeEnum::Inno; + } + else if (inStrLower == "wix") + { + return InstallerTypeEnum::Wix; + } + else if (inStrLower == "msi") + { + return InstallerTypeEnum::Msi; + } + else if (inStrLower == "nullsoft") + { + return InstallerTypeEnum::Nullsoft; + } + else if (inStrLower == "zip") + { + return InstallerTypeEnum::Zip; + } + else if (inStrLower == "appx" || inStrLower == "msix") + { + return InstallerTypeEnum::Msix; + } + else if (inStrLower == "exe") + { + return InstallerTypeEnum::Exe; + } + else if (inStrLower == "burn") + { + return InstallerTypeEnum::Burn; + } + + return InstallerTypeEnum::Unknown; + } } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer.h index eb471370b0..307a134015 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer.h @@ -17,5 +17,7 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json std::optional GetRequestMatchJsonObject(const AppInstaller::Repository::RequestMatch& requestMatch) const; std::optional GetPackageMatchFilterJsonObject(const PackageMatchFilter& packageMatchFilter) const; + + virtual std::optional ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) const; }; } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer_1_0.cpp similarity index 84% rename from src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer.cpp rename to src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer_1_0.cpp index efeaf6e3fe..f79edfd4a8 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer_1_0.cpp @@ -4,7 +4,7 @@ #include "Rest/Schema/IRestClient.h" #include "SearchRequestSerializer.h" #include "Rest/Schema/JsonHelper.h" -#include "CommonJsonConstants.h" +#include "Rest/Schema/CommonRestConstants.h" namespace AppInstaller::Repository::Rest::Schema::V1_0::Json { @@ -21,32 +21,6 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json constexpr std::string_view PackageMatchField = "PackageMatchField"sv; constexpr std::string_view FetchAllManifests = "FetchAllManifests"sv; - std::optional ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) - { - // Match fields supported by Rest API schema. - switch (field) - { - case PackageMatchField::Command: - return "Command"sv; - case PackageMatchField::Id: - return "PackageIdentifier"sv; - case PackageMatchField::Moniker: - return "Moniker"sv; - case PackageMatchField::Name: - return "PackageName"sv; - case PackageMatchField::Tag: - return "Tag"sv; - case PackageMatchField::PackageFamilyName: - return "PackageFamilyName"sv; - case PackageMatchField::ProductCode: - return "ProductCode"sv; - case PackageMatchField::NormalizedNameAndPublisher: - return "NormalizedPackageNameAndPublisher"sv; - } - - return {}; - } - std::optional ConvertMatchTypeToString(AppInstaller::Repository::MatchType type) { // Match types supported by Rest API schema. @@ -162,7 +136,7 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json { web::json::value filter = web::json::value::object(); std::optional matchField = ConvertPackageMatchFieldToString(packageMatchFilter.Field); - + if (!matchField) { AICLI_LOG(Repo, Warning, << "Skipping unsupported package match field: " << packageMatchFilter.Field); @@ -198,4 +172,30 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json match[JsonHelper::GetUtilityString(MatchType)] = web::json::value::string(JsonHelper::GetUtilityString(matchType.value())); return match; } + + std::optional SearchRequestSerializer::ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) const + { + // Match fields supported by Rest API schema. + switch (field) + { + case PackageMatchField::Command: + return "Command"sv; + case PackageMatchField::Id: + return "PackageIdentifier"sv; + case PackageMatchField::Moniker: + return "Moniker"sv; + case PackageMatchField::Name: + return "PackageName"sv; + case PackageMatchField::Tag: + return "Tag"sv; + case PackageMatchField::PackageFamilyName: + return "PackageFamilyName"sv; + case PackageMatchField::ProductCode: + return "ProductCode"sv; + case PackageMatchField::NormalizedNameAndPublisher: + return "NormalizedPackageNameAndPublisher"sv; + } + + return {}; + } } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer.h index b9e318825c..90caf3a4ef 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer.h @@ -13,6 +13,6 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json IRestClient::SearchResult Deserialize(const web::json::value& searchResultJsonObject) const; protected: - std::optional DeserializeSearchResult(const web::json::value& searchResultJsonObject) const; + virtual std::optional DeserializeSearchResult(const web::json::value& searchResultJsonObject) const; }; } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer_1_0.cpp similarity index 97% rename from src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer.cpp rename to src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer_1_0.cpp index 6ab7914eca..d70104b8de 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer_1_0.cpp @@ -5,7 +5,7 @@ #include "SearchResponseDeserializer.h" #include "Rest/Schema/JsonHelper.h" #include "Rest/Schema/RestHelper.h" -#include "CommonJsonConstants.h" +#include "Rest/Schema/CommonRestConstants.h" namespace AppInstaller::Repository::Rest::Schema::V1_0::Json { diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/RestInterface_1_0.cpp similarity index 76% rename from src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.cpp rename to src/AppInstallerRepositoryCore/Rest/Schema/1_0/RestInterface_1_0.cpp index 13734d1e1e..b3bb7b9e42 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/RestInterface_1_0.cpp @@ -3,12 +3,11 @@ #include "pch.h" #include "Rest/Schema/1_0/Interface.h" #include "Rest/Schema/IRestClient.h" -#include "Rest/HttpClientHelper.h" +#include "Rest/Schema/HttpClientHelper.h" #include "Rest/Schema/JsonHelper.h" #include "winget/ManifestValidation.h" #include "Rest/Schema/RestHelper.h" #include "Rest/Schema/CommonRestConstants.h" -#include "Rest/Schema/1_0/Json/CommonJsonConstants.h" #include "Rest/Schema/1_0/Json/ManifestDeserializer.h" #include "Rest/Schema/1_0/Json/SearchResponseDeserializer.h" #include "Rest/Schema/1_0/Json/SearchRequestSerializer.h" @@ -18,21 +17,11 @@ using namespace AppInstaller::Repository::Rest::Schema::V1_0::Json; namespace AppInstaller::Repository::Rest::Schema::V1_0 { - // Endpoint constants - constexpr std::string_view ManifestSearchPostEndpoint = "/manifestSearch"sv; - constexpr std::string_view ManifestByVersionAndChannelGetEndpoint = "/packageManifests/"sv; - - // Query params - constexpr std::string_view VersionQueryParam = "Version"sv; - constexpr std::string_view ChannelQueryParam = "Channel"sv; - namespace { - web::json::value GetSearchBody(const SearchRequest& searchRequest) - { - SearchRequestSerializer serializer; - return serializer.Serialize(searchRequest); - } + // Query params + constexpr std::string_view VersionQueryParam = "Version"sv; + constexpr std::string_view ChannelQueryParam = "Channel"sv; utility::string_t GetSearchEndpoint(const std::string& restApiUri) { @@ -42,13 +31,13 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 utility::string_t GetManifestByVersionEndpoint( const std::string& restApiUri, const std::string& packageId, const std::map& queryParameters) { - utility::string_t versionEndpoint = RestHelper::AppendPathToUri( + utility::string_t getManifestEndpoint = RestHelper::AppendPathToUri( JsonHelper::GetUtilityString(restApiUri), JsonHelper::GetUtilityString(ManifestByVersionAndChannelGetEndpoint)); - utility::string_t packageIdPath = RestHelper::AppendPathToUri(versionEndpoint, JsonHelper::GetUtilityString(packageId)); + utility::string_t getManifestWithPackageIdPath = RestHelper::AppendPathToUri(getManifestEndpoint, JsonHelper::GetUtilityString(packageId)); // Create the endpoint with query parameters - return RestHelper::AppendQueryParamsToUri(packageIdPath, queryParameters); + return RestHelper::AppendQueryParamsToUri(getManifestWithPackageIdPath, queryParameters); } } @@ -57,7 +46,7 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 THROW_HR_IF(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL, !RestHelper::IsValidUri(JsonHelper::GetUtilityString(restApi))); m_searchEndpoint = GetSearchEndpoint(m_restApiUri); - m_requiredRestApiHeaders.emplace(JsonHelper::GetUtilityString(ContractVersion), JsonHelper::GetUtilityString(GetVersion().ToString())); + m_requiredRestApiHeaders.emplace(JsonHelper::GetUtilityString(ContractVersion), JsonHelper::GetUtilityString(Version_1_0_0.ToString())); } Utility::Version Interface::GetVersion() const @@ -65,6 +54,11 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 return Version_1_0_0; } + IRestClient::Information Interface::GetSourceInformation() const + { + return {}; + } + IRestClient::SearchResult Interface::Search(const SearchRequest& request) const { // Optimization @@ -89,17 +83,21 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 searchHeaders.insert_or_assign(JsonHelper::GetUtilityString(ContinuationToken), continuationToken); } - std::optional jsonObject = m_httpClientHelper.HandlePost(m_searchEndpoint, GetSearchBody(request), searchHeaders); + std::optional jsonObject = m_httpClientHelper.HandlePost(m_searchEndpoint, GetValidatedSearchBody(request), searchHeaders); utility::string_t ct; if (jsonObject) { - SearchResponseDeserializer searchResponseDeserializer; - SearchResult currentResult = searchResponseDeserializer.Deserialize(jsonObject.value()); - + SearchResult currentResult = GetSearchResult(jsonObject.value()); + size_t insertElements = !request.MaximumResults ? currentResult.Matches.size() : std::min(currentResult.Matches.size(), request.MaximumResults - results.Matches.size()); + if (insertElements < currentResult.Matches.size()) + { + results.Truncated = true; + } + std::move(currentResult.Matches.begin(), std::next(currentResult.Matches.begin(), insertElements), std::inserter(results.Matches, results.Matches.end())); ct = RestHelper::GetContinuationToken(jsonObject.value()).value_or(L""); } @@ -108,6 +106,11 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 } while (!continuationToken.empty() && (!request.MaximumResults || results.Matches.size() < request.MaximumResults)); + if (!continuationToken.empty()) + { + results.Truncated = true; + } + if (results.Matches.empty()) { AICLI_LOG(Repo, Verbose, << "No search results returned by rest source"); @@ -152,7 +155,7 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 // call the package manifest endpoint to get the manifest directly instead of running a search for it. if (!request.Query && request.Inclusions.size() == 0 && request.Filters.size() == 1 && request.Filters[0].Field == PackageMatchField::Id && - request.Filters[0].Type == MatchType::Exact) + (request.Filters[0].Type == MatchType::Exact || request.Filters[0].Type == MatchType::CaseInsensitive)) { AICLI_LOG(Repo, Verbose, << "Search request meets optimized search criteria."); return true; @@ -211,8 +214,12 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 std::vector Interface::GetManifests(const std::string& packageId, const std::map& params) const { + auto validatedParams = GetValidatedQueryParams(params); + std::vector results; - std::optional jsonObject = m_httpClientHelper.HandleGet(GetManifestByVersionEndpoint(m_restApiUri, packageId, params), m_requiredRestApiHeaders); + utility::string_t continuationToken; + std::unordered_map searchHeaders = m_requiredRestApiHeaders; + std::optional jsonObject = m_httpClientHelper.HandleGet(GetManifestByVersionEndpoint(m_restApiUri, packageId, validatedParams), m_requiredRestApiHeaders); if (!jsonObject) { @@ -221,14 +228,13 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 } // Parse json and return Manifests - ManifestDeserializer manifestDeserializer; - std::vector manifests = manifestDeserializer.Deserialize(jsonObject.value()); + std::vector manifests = GetParsedManifests(jsonObject.value()); // Manifest validation for (auto& manifestItem : manifests) { std::vector validationErrors = - AppInstaller::Manifest::ValidateManifest(manifestItem); + AppInstaller::Manifest::ValidateManifest(manifestItem, false); int errors = 0; for (auto& error : validationErrors) @@ -247,4 +253,27 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 return results; } + + std::map Interface::GetValidatedQueryParams(const std::map& params) const + { + return params; + } + + web::json::value Interface::GetValidatedSearchBody(const SearchRequest& searchRequest) const + { + SearchRequestSerializer serializer; + return serializer.Serialize(searchRequest); + } + + IRestClient::SearchResult Interface::GetSearchResult(const web::json::value& searchResponseObject) const + { + SearchResponseDeserializer searchResponseDeserializer; + return searchResponseDeserializer.Deserialize(searchResponseObject); + } + + std::vector Interface::GetParsedManifests(const web::json::value& manifestsResponseObject) const + { + ManifestDeserializer manifestDeserializer; + return manifestDeserializer.Deserialize(manifestsResponseObject); + } } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Interface.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Interface.h new file mode 100644 index 0000000000..babf7f1349 --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Interface.h @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "Rest/Schema/1_0/Interface.h" + +namespace AppInstaller::Repository::Rest::Schema::V1_1 +{ + // Interface to this schema version exposed through IRestClient. + struct Interface : public V1_0::Interface + { + Interface(const std::string& restApi, IRestClient::Information information, const std::unordered_map& additionalHeaders = {}, const HttpClientHelper& httpClientHelper = {}); + + Interface(const Interface&) = delete; + Interface& operator=(const Interface&) = delete; + + Interface(Interface&&) = default; + Interface& operator=(Interface&&) = default; + + Utility::Version GetVersion() const override; + IRestClient::Information GetSourceInformation() const override; + + protected: + // Check query params against source information and update if necessary. + std::map GetValidatedQueryParams(const std::map& params) const override; + + // Check search request against source information and get json search body. + web::json::value GetValidatedSearchBody(const SearchRequest& searchRequest) const override; + + SearchResult GetSearchResult(const web::json::value& searchResponseObject) const override; + std::vector GetParsedManifests(const web::json::value& manifestsResponseObject) const override; + + private: + IRestClient::Information m_information; + }; +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer.h new file mode 100644 index 0000000000..70406164fa --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "Rest/Schema/1_0/Json/ManifestDeserializer.h" + +namespace AppInstaller::Repository::Rest::Schema::V1_1::Json +{ + // Manifest Deserializer. + struct ManifestDeserializer : public V1_0::Json::ManifestDeserializer + { + // TODO: override DeserializeLocale, DeserializeInstaller accordingly to add new v1.1 fields + protected: + std::optional DeserializeInstaller(const web::json::value& installerJsonObject) const override; + + Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const override; + }; +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer_1_1.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer_1_1.cpp new file mode 100644 index 0000000000..4d5e619021 --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer_1_1.cpp @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ManifestDeserializer.h" +#include "Rest/Schema/JsonHelper.h" + +using namespace AppInstaller::Manifest; + +namespace AppInstaller::Repository::Rest::Schema::V1_1::Json +{ + namespace + { + // Installer + constexpr std::string_view MSStoreProductIdentifier = "MSStoreProductIdentifier"sv; + } + + Manifest::InstallerTypeEnum ManifestDeserializer::ConvertToInstallerType(std::string_view in) const + { + std::string inStrLower = Utility::ToLower(in); + + if (inStrLower == "msstore") + { + return InstallerTypeEnum::MSStore; + } + + return V1_0::Json::ManifestDeserializer::ConvertToInstallerType(in); + } + + std::optional ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const + { + auto result = V1_0::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject); + + if (result) + { + auto& installer = result.value(); + + installer.ProductId = JsonHelper::GetRawStringValueFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(MSStoreProductIdentifier)).value_or(""); + } + + return result; + } +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer.h new file mode 100644 index 0000000000..fdf608c5e9 --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include +#include "Rest/Schema/1_0/Json/SearchRequestSerializer.h" + +namespace AppInstaller::Repository::Rest::Schema::V1_1::Json +{ + // Search Result Serializer. + struct SearchRequestSerializer : public V1_0::Json::SearchRequestSerializer + { + protected: + std::optional ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) const override; + }; +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer_1_1.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer_1_1.cpp new file mode 100644 index 0000000000..60f37b1c63 --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer_1_1.cpp @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "SearchRequestSerializer.h" + +namespace AppInstaller::Repository::Rest::Schema::V1_1::Json +{ + std::optional SearchRequestSerializer::ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) const + { + if (field == PackageMatchField::Market) + { + return "Market"sv; + } + + return V1_0::Json::SearchRequestSerializer::ConvertPackageMatchFieldToString(field); + } +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_1/RestInterface_1_1.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/RestInterface_1_1.cpp new file mode 100644 index 0000000000..613dac173d --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_1/RestInterface_1_1.cpp @@ -0,0 +1,172 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "Rest/Schema/1_1/Interface.h" +#include "Rest/Schema/IRestClient.h" +#include "Rest/Schema/HttpClientHelper.h" +#include "Rest/Schema/JsonHelper.h" +#include "Rest/Schema/RestHelper.h" +#include "Rest/Schema/CommonRestConstants.h" +#include "Rest/Schema/1_1/Json/ManifestDeserializer.h" +#include "Rest/Schema/1_1/Json/SearchRequestSerializer.h" + +using namespace std::string_view_literals; +using namespace AppInstaller::Repository::Rest::Schema::V1_1::Json; + +namespace AppInstaller::Repository::Rest::Schema::V1_1 +{ + namespace + { + // Query params + constexpr std::string_view MarketQueryParam = "Market"sv; + + // Response constants + constexpr std::string_view UnsupportedPackageMatchFields = "UnsupportedPackageMatchFields"sv; + constexpr std::string_view RequiredPackageMatchFields = "RequiredPackageMatchFields"sv; + constexpr std::string_view UnsupportedQueryParameters = "UnsupportedQueryParameters"sv; + constexpr std::string_view RequiredQueryParameters = "RequiredQueryParameters"sv; + } + + Interface::Interface( + const std::string& restApi, + IRestClient::Information information, + const std::unordered_map& additionalHeaders, + const HttpClientHelper& httpClientHelper) : V1_0::Interface(restApi, httpClientHelper), m_information(std::move(information)) + { + m_requiredRestApiHeaders[JsonHelper::GetUtilityString(ContractVersion)] = JsonHelper::GetUtilityString(Version_1_1_0.ToString()); + + if (!additionalHeaders.empty()) + { + m_requiredRestApiHeaders.insert(additionalHeaders.begin(), additionalHeaders.end()); + } + } + + Utility::Version Interface::GetVersion() const + { + return Version_1_1_0; + } + + IRestClient::Information Interface::GetSourceInformation() const + { + return m_information; + } + + std::map Interface::GetValidatedQueryParams(const std::map& params) const + { + std::map result = params; + + for (auto const& param : m_information.RequiredQueryParameters) + { + if (params.end() == std::find_if(params.begin(), params.end(), [&](const auto& pair) { return Utility::CaseInsensitiveEquals(pair.first, param); })) + { + if (Utility::CaseInsensitiveEquals(param, MarketQueryParam)) + { + result.emplace(MarketQueryParam, Runtime::GetOSRegion()); + continue; + } + + AICLI_LOG(Repo, Error, << "Search request is not supported by the rest source. Required query Parameter: " << param); + throw UnsupportedRequestException({}, {}, {}, m_information.RequiredQueryParameters); + } + } + + for (auto const& param : m_information.UnsupportedQueryParameters) + { + if (params.end() != std::find_if(params.begin(), params.end(), [&](const auto& pair) { return Utility::CaseInsensitiveEquals(pair.first, param); })) + { + AICLI_LOG(Repo, Error, << "Search request is not supported by the rest source. Unsupported query Parameter: " << param); + throw UnsupportedRequestException({}, {}, m_information.UnsupportedQueryParameters, {}); + } + } + + return result; + } + + web::json::value Interface::GetValidatedSearchBody(const SearchRequest& searchRequest) const + { + SearchRequest resultSearchRequest = searchRequest; + + for (auto const& field : m_information.RequiredPackageMatchFields) + { + PackageMatchField matchField = StringToPackageMatchField(field); + + if (searchRequest.Filters.end() == std::find_if(searchRequest.Filters.begin(), searchRequest.Filters.end(), [&](const PackageMatchFilter& filter) { return filter.Field == matchField; })) + { + if (matchField == PackageMatchField::Market) + { + resultSearchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Market, MatchType::CaseInsensitive, Runtime::GetOSRegion())); + continue; + } + + AICLI_LOG(Repo, Error, << "Search request is not supported by the rest source. Required package match field: " << field); + throw UnsupportedRequestException({}, m_information.RequiredPackageMatchFields, {}, {}); + } + } + + for (auto const& field : m_information.UnsupportedPackageMatchFields) + { + PackageMatchField matchField = StringToPackageMatchField(field); + + if (matchField == PackageMatchField::Unknown) + { + continue; + } + + if (searchRequest.Inclusions.end() != std::find_if(searchRequest.Inclusions.begin(), searchRequest.Inclusions.end(), [&](const PackageMatchFilter& inclusion) { return inclusion.Field == matchField; })) + { + AICLI_LOG(Repo, Info, << "Search request Inclusions contains package match field not supported by the rest source. Ignoring the field. Unsupported package match field: " << field); + + auto itr = std::find_if(resultSearchRequest.Inclusions.begin(), resultSearchRequest.Inclusions.end(), [&](const PackageMatchFilter& inclusion) { return inclusion.Field == matchField; }); + resultSearchRequest.Inclusions.erase(itr); + } + + if (searchRequest.Filters.end() != std::find_if(searchRequest.Filters.begin(), searchRequest.Filters.end(), [&](const PackageMatchFilter& filter) { return filter.Field == matchField; })) + { + AICLI_LOG(Repo, Error, << "Search request is not supported by the rest source. Unsupported package match field: " << field); + throw UnsupportedRequestException(m_information.UnsupportedPackageMatchFields, {}, {}, {}); + } + } + + SearchRequestSerializer serializer; + return serializer.Serialize(resultSearchRequest); + } + + IRestClient::SearchResult Interface::GetSearchResult(const web::json::value& searchResponseObject) const + { + IRestClient::SearchResult result = V1_0::Interface::GetSearchResult(searchResponseObject); + + if (result.Matches.size() == 0) + { + auto requiredPackageMatchFields = JsonHelper::GetRawStringArrayFromJsonNode(searchResponseObject, JsonHelper::GetUtilityString(RequiredPackageMatchFields)); + auto unsupportedPackageMatchFields = JsonHelper::GetRawStringArrayFromJsonNode(searchResponseObject, JsonHelper::GetUtilityString(UnsupportedPackageMatchFields)); + + if (requiredPackageMatchFields.size() != 0 || unsupportedPackageMatchFields.size() != 0) + { + AICLI_LOG(Repo, Error, << "Search request is not supported by the rest source"); + throw UnsupportedRequestException(std::move(unsupportedPackageMatchFields), std::move(requiredPackageMatchFields), {}, {}); + } + } + + return result; + } + + std::vector Interface::GetParsedManifests(const web::json::value& manifestsResponseObject) const + { + ManifestDeserializer manifestDeserializer; + auto result = manifestDeserializer.Deserialize(manifestsResponseObject); + + if (result.size() == 0) + { + auto requiredQueryParameters = JsonHelper::GetRawStringArrayFromJsonNode(manifestsResponseObject, JsonHelper::GetUtilityString(RequiredQueryParameters)); + auto unsupportedQueryParameters = JsonHelper::GetRawStringArrayFromJsonNode(manifestsResponseObject, JsonHelper::GetUtilityString(UnsupportedQueryParameters)); + + if (requiredQueryParameters.size() != 0 || unsupportedQueryParameters.size() != 0) + { + AICLI_LOG(Repo, Error, << "Search request is not supported by the rest source"); + throw UnsupportedRequestException({}, {}, std::move(unsupportedQueryParameters), std::move(requiredQueryParameters)); + } + } + + return result; + } +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h b/src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h index facb42c1d6..6ee472dc9f 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h @@ -7,4 +7,17 @@ namespace AppInstaller::Repository::Rest::Schema { // Winget supported contract versions const Utility::Version Version_1_0_0{ "1.0.0" }; + const Utility::Version Version_1_1_0{ "1.1.0" }; + + // General API response constants + constexpr std::string_view Data = "Data"sv; + constexpr std::string_view ContinuationToken = "ContinuationToken"sv; + + // General API Header constant + constexpr std::string_view ContractVersion = "Version"sv; + + // General endpoint constants + constexpr std::string_view InformationGetEndpoint = "/information"sv; + constexpr std::string_view ManifestSearchPostEndpoint = "/manifestSearch"sv; + constexpr std::string_view ManifestByVersionAndChannelGetEndpoint = "/packageManifests/"sv; } diff --git a/src/AppInstallerRepositoryCore/Rest/HttpClientHelper.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/HttpClientHelper.cpp similarity index 78% rename from src/AppInstallerRepositoryCore/Rest/HttpClientHelper.cpp rename to src/AppInstallerRepositoryCore/Rest/Schema/HttpClientHelper.cpp index decfeb0deb..d6330b0f06 100644 --- a/src/AppInstallerRepositoryCore/Rest/HttpClientHelper.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/HttpClientHelper.cpp @@ -3,14 +3,14 @@ #include "pch.h" #include "HttpClientHelper.h" -namespace AppInstaller::Repository::Rest +namespace AppInstaller::Repository::Rest::Schema { HttpClientHelper::HttpClientHelper(std::optional> stage) : m_defaultRequestHandlerStage(stage) {} pplx::task HttpClientHelper::Post( const utility::string_t& uri, const web::json::value& body, const std::unordered_map& headers) const { - AICLI_LOG(Repo, Verbose, << "Sending http POST request to: " << utility::conversions::to_utf8string(uri)); + AICLI_LOG(Repo, Info, << "Sending http POST request to: " << utility::conversions::to_utf8string(uri)); web::http::client::http_client client = GetClient(uri); web::http::http_request request{ web::http::methods::POST }; request.headers().set_content_type(web::http::details::mime_types::application_json); @@ -22,6 +22,8 @@ namespace AppInstaller::Repository::Rest request.headers().add(pair.first, pair.second); } + AICLI_LOG(Repo, Verbose, << "Http POST request details:\n" << utility::conversions::to_utf8string(request.to_string())); + return client.request(request); } @@ -31,17 +33,16 @@ namespace AppInstaller::Repository::Rest web::http::http_response httpResponse; HttpClientHelper::Post(uri, body, headers).then([&httpResponse](const web::http::http_response& response) { - AICLI_LOG(Repo, Verbose, << "Response status: " << response.status_code()); httpResponse = response; }).wait(); - return ValidateAndExtractResponse(httpResponse); + return ValidateAndExtractResponse(httpResponse); } pplx::task HttpClientHelper::Get( const utility::string_t& uri, const std::unordered_map& headers) const { - AICLI_LOG(Repo, Verbose, << "Sending http GET request to: " << utility::conversions::to_utf8string(uri)); + AICLI_LOG(Repo, Info, << "Sending http GET request to: " << utility::conversions::to_utf8string(uri)); web::http::client::http_client client = GetClient(uri); web::http::http_request request{ web::http::methods::GET }; request.headers().set_content_type(web::http::details::mime_types::application_json); @@ -52,6 +53,8 @@ namespace AppInstaller::Repository::Rest request.headers().add(pair.first, pair.second); } + AICLI_LOG(Repo, Verbose, << "Http GET request details:\n" << utility::conversions::to_utf8string(request.to_string())); + return client.request(request); } @@ -61,11 +64,10 @@ namespace AppInstaller::Repository::Rest web::http::http_response httpResponse; Get(uri, headers).then([&httpResponse](const web::http::http_response& response) { - AICLI_LOG(Repo, Verbose, << "Response status: " << response.status_code()); httpResponse = response; }).wait(); - return ValidateAndExtractResponse(httpResponse); + return ValidateAndExtractResponse(httpResponse); } web::http::client::http_client HttpClientHelper::GetClient(const utility::string_t& uri) const @@ -83,6 +85,9 @@ namespace AppInstaller::Repository::Rest std::optional HttpClientHelper::ValidateAndExtractResponse(const web::http::http_response& response) const { + AICLI_LOG(Repo, Info, << "Response status: " << response.status_code()); + AICLI_LOG(Repo, Verbose, << "Response details: " << utility::conversions::to_utf8string(response.to_string())); + std::optional result; switch (response.status_code()) { @@ -91,6 +96,9 @@ namespace AppInstaller::Repository::Rest break; case web::http::status_codes::NotFound: + THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND); + break; + case web::http::status_codes::NoContent: result = {}; break; diff --git a/src/AppInstallerRepositoryCore/Rest/HttpClientHelper.h b/src/AppInstallerRepositoryCore/Rest/Schema/HttpClientHelper.h similarity index 94% rename from src/AppInstallerRepositoryCore/Rest/HttpClientHelper.h rename to src/AppInstallerRepositoryCore/Rest/Schema/HttpClientHelper.h index bf2a1bdd6d..0a73e62113 100644 --- a/src/AppInstallerRepositoryCore/Rest/HttpClientHelper.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/HttpClientHelper.h @@ -7,7 +7,7 @@ #include #include -namespace AppInstaller::Repository::Rest +namespace AppInstaller::Repository::Rest::Schema { struct HttpClientHelper { diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/IRestClient.h b/src/AppInstallerRepositoryCore/Rest/Schema/IRestClient.h index 8f26cde5c3..1930ca95f3 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/IRestClient.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/IRestClient.h @@ -49,12 +49,26 @@ namespace AppInstaller::Repository::Rest::Schema bool Truncated = false; }; + struct SourceAgreementEntry + { + std::string Label; + std::string Text; + std::string Url; + }; + // Information endpoint models struct Information { std::string SourceIdentifier; std::vector ServerSupportedVersions; + std::string SourceAgreementsIdentifier; + std::vector SourceAgreements; + std::vector UnsupportedPackageMatchFields; + std::vector RequiredPackageMatchFields; + std::vector UnsupportedQueryParameters; + std::vector RequiredQueryParameters; + Information() {} Information(std::string sourceId, std::vector versions) : SourceIdentifier(std::move(sourceId)), ServerSupportedVersions(std::move(versions)) {} }; @@ -62,6 +76,9 @@ namespace AppInstaller::Repository::Rest::Schema // Get interface version. virtual Utility::Version GetVersion() const = 0; + // Get source information. + virtual Information GetSourceInformation() const = 0; + // Performs a search based on the given criteria. virtual SearchResult Search(const SearchRequest& request) const = 0; diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.cpp new file mode 100644 index 0000000000..cc3719cede --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.cpp @@ -0,0 +1,136 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "Rest/Schema/IRestClient.h" +#include "Rest/Schema/JsonHelper.h" +#include "Rest/Schema/CommonRestConstants.h" +#include "InformationResponseDeserializer.h" + +namespace AppInstaller::Repository::Rest::Schema +{ + namespace + { + // Information response constants + constexpr std::string_view SourceIdentifier = "SourceIdentifier"sv; + constexpr std::string_view ServerSupportedVersions = "ServerSupportedVersions"sv; + + constexpr std::string_view SourceAgreements = "SourceAgreements"sv; + constexpr std::string_view SourceAgreementsIdentifier = "AgreementsIdentifier"sv; + constexpr std::string_view SourceAgreementsContent = "Agreements"sv; + constexpr std::string_view SourceAgreementLabel = "AgreementLabel"sv; + constexpr std::string_view SourceAgreementText = "Agreement"sv; + constexpr std::string_view SourceAgreementUrl = "AgreementUrl"sv; + + constexpr std::string_view UnsupportedPackageMatchFields = "UnsupportedPackageMatchFields"sv; + constexpr std::string_view RequiredPackageMatchFields = "RequiredPackageMatchFields"sv; + constexpr std::string_view UnsupportedQueryParameters = "UnsupportedQueryParameters"sv; + constexpr std::string_view RequiredQueryParameters = "RequiredQueryParameters"sv; + } + + IRestClient::Information InformationResponseDeserializer::Deserialize(const web::json::value& dataObject) const + { + // Get information result from json output. + std::optional information = DeserializeInformation(dataObject); + + THROW_HR_IF(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, !information); + + return information.value(); + } + + std::optional InformationResponseDeserializer::DeserializeInformation(const web::json::value& dataObject) const + { + try + { + if (dataObject.is_null()) + { + AICLI_LOG(Repo, Error, << "Missing json object."); + return {}; + } + + std::optional> data = JsonHelper::GetJsonValueFromNode(dataObject, JsonHelper::GetUtilityString(Data)); + if (!data) + { + AICLI_LOG(Repo, Error, << "Missing data"); + return {}; + } + + const auto& dataValue = data.value().get(); + std::optional sourceId = JsonHelper::GetRawStringValueFromJsonNode(dataValue, JsonHelper::GetUtilityString(SourceIdentifier)); + if (!JsonHelper::IsValidNonEmptyStringValue(sourceId)) + { + AICLI_LOG(Repo, Error, << "Missing source identifier"); + return {}; + } + + std::vector allVersions = JsonHelper::GetRawStringArrayFromJsonNode(dataValue, JsonHelper::GetUtilityString(ServerSupportedVersions)); + if (allVersions.size() == 0) + { + AICLI_LOG(Repo, Error, << "Missing supported versions."); + return {}; + } + + IRestClient::Information info{ std::move(sourceId.value()), std::move(allVersions) }; + + auto agreements = JsonHelper::GetJsonValueFromNode(dataValue, JsonHelper::GetUtilityString(SourceAgreements)); + if (agreements) + { + const auto& agreementsValue = agreements.value().get(); + + auto agreementsIdentifier = JsonHelper::GetRawStringValueFromJsonNode(agreementsValue, JsonHelper::GetUtilityString(SourceAgreementsIdentifier)); + if (!JsonHelper::IsValidNonEmptyStringValue(agreementsIdentifier)) + { + AICLI_LOG(Repo, Error, << "SourceAgreements node exists but AgreementsIdentifier is missing."); + return {}; + } + + info.SourceAgreementsIdentifier = std::move(agreementsIdentifier.value()); + + auto agreementsContent = JsonHelper::GetRawJsonArrayFromJsonNode(agreementsValue, JsonHelper::GetUtilityString(SourceAgreementsContent)); + if (agreementsContent) + { + for (auto const& agreementNode : agreementsContent.value().get()) + { + IRestClient::SourceAgreementEntry agreementEntry; + + std::optional label = JsonHelper::GetRawStringValueFromJsonNode(agreementNode, JsonHelper::GetUtilityString(SourceAgreementLabel)); + if (JsonHelper::IsValidNonEmptyStringValue(label)) + { + agreementEntry.Label = std::move(label.value()); + } + + std::optional text = JsonHelper::GetRawStringValueFromJsonNode(agreementNode, JsonHelper::GetUtilityString(SourceAgreementText)); + if (JsonHelper::IsValidNonEmptyStringValue(text)) + { + agreementEntry.Text = std::move(text.value()); + } + + std::optional url = JsonHelper::GetRawStringValueFromJsonNode(agreementNode, JsonHelper::GetUtilityString(SourceAgreementUrl)); + if (JsonHelper::IsValidNonEmptyStringValue(url)) + { + agreementEntry.Url = std::move(url.value()); + } + + info.SourceAgreements.emplace_back(std::move(agreementEntry)); + } + } + } + + info.RequiredPackageMatchFields = JsonHelper::GetRawStringArrayFromJsonNode(dataValue, JsonHelper::GetUtilityString(RequiredPackageMatchFields)); + info.UnsupportedPackageMatchFields = JsonHelper::GetRawStringArrayFromJsonNode(dataValue, JsonHelper::GetUtilityString(UnsupportedPackageMatchFields)); + info.RequiredQueryParameters = JsonHelper::GetRawStringArrayFromJsonNode(dataValue, JsonHelper::GetUtilityString(RequiredQueryParameters)); + info.UnsupportedQueryParameters = JsonHelper::GetRawStringArrayFromJsonNode(dataValue, JsonHelper::GetUtilityString(UnsupportedQueryParameters)); + + return info; + } + catch (const std::exception& e) + { + AICLI_LOG(Repo, Error, << "Error encountered while deserializing Information. Reason: " << e.what()); + } + catch (...) + { + AICLI_LOG(Repo, Error, << "Received invalid information."); + } + + return {}; + } +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/InformationResponseDeserializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.h similarity index 87% rename from src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/InformationResponseDeserializer.h rename to src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.h index cb539735ed..5ddd5105c4 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/InformationResponseDeserializer.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.h @@ -4,7 +4,7 @@ #include #include "Rest/Schema/IRestClient.h" -namespace AppInstaller::Repository::Rest::Schema::V1_0::Json +namespace AppInstaller::Repository::Rest::Schema { // Information response Deserializer. struct InformationResponseDeserializer diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp index 6a467eb3bf..327f35d4b8 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp @@ -3,10 +3,9 @@ #include "pch.h" #include "RestHelper.h" #include "Rest/Schema/JsonHelper.h" -#include "Rest/Schema/1_0/Json/CommonJsonConstants.h" +#include "Rest/Schema/CommonRestConstants.h" using namespace AppInstaller::Repository::Rest::Schema; -using namespace AppInstaller::Repository::Rest::Schema::V1_0::Json; namespace AppInstaller::Repository::Rest::Schema { diff --git a/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp b/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp index 10161edc0d..2663e96a95 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp +++ b/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp @@ -12,7 +12,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation { m_sourceDetails = sourceDetails; } - ::AppInstaller::Repository::SourceDetails PackageCatalogInfo::GetSourceDetails() + ::AppInstaller::Repository::SourceDetails& PackageCatalogInfo::GetSourceDetails() { return m_sourceDetails; } diff --git a/src/Microsoft.Management.Deployment/PackageCatalogInfo.h b/src/Microsoft.Management.Deployment/PackageCatalogInfo.h index 8413253187..b9db7823bd 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalogInfo.h +++ b/src/Microsoft.Management.Deployment/PackageCatalogInfo.h @@ -11,7 +11,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(const ::AppInstaller::Repository::SourceDetails& sourceDetails); - ::AppInstaller::Repository::SourceDetails GetSourceDetails(); + ::AppInstaller::Repository::SourceDetails& GetSourceDetails(); #endif hstring Id(); diff --git a/src/Microsoft.Management.Deployment/PackageCatalogReference.cpp b/src/Microsoft.Management.Deployment/PackageCatalogReference.cpp index 75ac914cbd..f508881c11 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalogReference.cpp +++ b/src/Microsoft.Management.Deployment/PackageCatalogReference.cpp @@ -24,11 +24,10 @@ namespace winrt::Microsoft::Management::Deployment::implementation void PackageCatalogReference::Initialize(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions options) { m_compositePackageCatalogOptions = options; - m_isComposite = true; } bool PackageCatalogReference::IsComposite() { - return m_isComposite; + return (m_compositePackageCatalogOptions != nullptr); } winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalogReference::Info() { @@ -64,8 +63,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation { auto catalog = m_compositePackageCatalogOptions.Catalogs().GetAt(i); winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo* catalogInfoImpl = get_self(catalog.Info()); - ::AppInstaller::Repository::SourceDetails sourceDetails = catalogInfoImpl->GetSourceDetails(); - std::shared_ptr<::AppInstaller::Repository::ISource> remoteSource = ::AppInstaller::Repository::OpenSourceFromDetails(sourceDetails, progress).Source; + + std::shared_ptr<::AppInstaller::Repository::ISource> remoteSource = ::AppInstaller::Repository::OpenSourceFromDetails(catalogInfoImpl->GetSourceDetails(), progress).Source; if (!remoteSource) { // If source is null, return the error. There's no way to get the hresult that caused the error right now. @@ -88,8 +87,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation else { winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo* catalogInfoImpl = get_self(m_info); - ::AppInstaller::Repository::SourceDetails sourceDetails = catalogInfoImpl->GetSourceDetails(); - source = ::AppInstaller::Repository::OpenSourceFromDetails(sourceDetails, progress).Source; + source = ::AppInstaller::Repository::OpenSourceFromDetails(catalogInfoImpl->GetSourceDetails(), progress).Source; } if (!source) @@ -115,4 +113,33 @@ namespace winrt::Microsoft::Management::Deployment::implementation connectResult->Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus::CatalogError, nullptr); return *connectResult; } + + hstring PackageCatalogReference::AdditionalPackageCatalogArguments() + { + if (!IsComposite()) + { + winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo* catalogInfoImpl = get_self(m_info); + ::AppInstaller::Repository::SourceDetails sourceDetails = catalogInfoImpl->GetSourceDetails(); + auto customHeader = catalogInfoImpl->GetSourceDetails().CustomHeader; + if (customHeader.has_value()) + { + return winrt::to_hstring(customHeader.value()); + } + } + + return {}; + } + void PackageCatalogReference::AdditionalPackageCatalogArguments(hstring const& value) + { + if (IsComposite()) + { + // Can't set AdditionalPackageCatalogArguments on a composite. Callers should set it on each non-composite PackageCatalogReference in the composite. + throw winrt::hresult_illegal_state_change(); + } + else + { + winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo* catalogInfoImpl = get_self(m_info); + catalogInfoImpl->GetSourceDetails().CustomHeader = ::AppInstaller::Utility::ConvertToUTF8(value); + } + } } diff --git a/src/Microsoft.Management.Deployment/PackageCatalogReference.h b/src/Microsoft.Management.Deployment/PackageCatalogReference.h index e15669b75a..3804830d6b 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalogReference.h +++ b/src/Microsoft.Management.Deployment/PackageCatalogReference.h @@ -18,6 +18,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); winrt::Windows::Foundation::IAsyncOperation ConnectAsync(); winrt::Microsoft::Management::Deployment::ConnectResult Connect(); + hstring AdditionalPackageCatalogArguments(); + void AdditionalPackageCatalogArguments(hstring const& value); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: diff --git a/src/Microsoft.Management.Deployment/PackageManager.cpp b/src/Microsoft.Management.Deployment/PackageManager.cpp index 999a1c0d36..13f75a7016 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment/PackageManager.cpp @@ -123,13 +123,19 @@ namespace winrt::Microsoft::Management::Deployment::implementation } manifest.ApplyLocale(targetLocale); - ::AppInstaller::Logging::Telemetry().LogManifestFields(manifest.Id, manifest.DefaultLocalization.Get<::AppInstaller::Manifest::Localization::PackageName>(), manifest.Version); + context->GetThreadGlobals().GetTelemetryLogger().LogManifestFields(manifest.Id, manifest.DefaultLocalization.Get<::AppInstaller::Manifest::Localization::PackageName>(), manifest.Version); context->Add<::AppInstaller::CLI::Execution::Data::Manifest>(std::move(manifest)); context->Add<::AppInstaller::CLI::Execution::Data::PackageVersion>(std::move(internalPackageVersion)); } winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options) { + if (!options) + { + // Can't make a composite source if the options aren't specified. + throw hresult_invalid_argument(); + } + for (uint32_t i = 0; i < options.Catalogs().Size(); ++i) { auto catalog = options.Catalogs().GetAt(i); @@ -265,7 +271,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation { std::unique_ptr context = std::make_unique(); hstring correlationData = (options) ? options.CorrelationData() : L""; - context->SetLoggerContext(correlationData, ::AppInstaller::Utility::ConvertToUTF8(callerProcessInfoString)); + context->SetContextLoggers(correlationData, ::AppInstaller::Utility::ConvertToUTF8(callerProcessInfoString)); // Convert the options to arguments for the installer. if (options) diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index 1882b39824..690b60a319 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -419,6 +419,12 @@ namespace Microsoft.Management.Deployment /// may require downloading information from a server. Windows.Foundation.IAsyncOperation ConnectAsync(); ConnectResult Connect(); + + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 2)] + { + /// A string that will be passed to the source server if using a REST source + String AdditionalPackageCatalogArguments; + } } /// Catalogs with PackageCatalogOrigin Predefined diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 03d1f28f21..1a4ce09f65 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -30,13 +30,6 @@ static void _releaseNotifier() noexcept // Check whether the packaged api is enabled and the overarching winget group policy is enabled. bool IsServerEnabled() { - ::AppInstaller::Utility::Version version("10.0.22000.0"); - - if (!::AppInstaller::Runtime::IsCurrentOSVersionGreaterThanOrEqual(version) && - !::AppInstaller::Settings::ExperimentalFeature::IsEnabled(::AppInstaller::Settings::ExperimentalFeature::Feature::PackagedAPI)) - { - return false; - } if (!::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::WinGet)) { return false; From 097cc586eb4fe63d1b1f3b0fb8e2633cddbcf7c5 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Tue, 31 Aug 2021 13:18:52 -0700 Subject: [PATCH 27/53] Remove unneccessary cpp files --- .../CatalogPackage.cpp | 37 --------------- .../ConnectResult.cpp | 17 ------- .../FindPackagesResult.cpp | 21 --------- .../InstallResult.cpp | 25 ----------- .../MatchResult.cpp | 17 ------- ...osoft.Management.Deployment.Client.vcxproj | 10 ----- .../PackageCatalog.cpp | 25 ----------- .../PackageCatalogInfo.cpp | 37 --------------- .../PackageCatalogReference.cpp | 25 ----------- .../PackageVersionId.cpp | 21 --------- .../PackageVersionInfo.cpp | 45 ------------------- 11 files changed, 280 deletions(-) delete mode 100644 src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/ConnectResult.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/InstallResult.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/MatchResult.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp delete mode 100644 src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp diff --git a/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp b/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp deleted file mode 100644 index 8146ef966b..0000000000 --- a/src/Microsoft.Management.Deployment.Client/CatalogPackage.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "CatalogPackage.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring CatalogPackage::Id() - { - throw hresult_not_implemented(); - } - hstring CatalogPackage::Name() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::InstalledVersion() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::Collections::IVectorView CatalogPackage::AvailableVersions() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::DefaultInstallVersion() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const&) - { - throw hresult_not_implemented(); - } - bool CatalogPackage::IsUpdateAvailable() - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp b/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp deleted file mode 100644 index 68bffbba01..0000000000 --- a/src/Microsoft.Management.Deployment.Client/ConnectResult.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "ConnectResult.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - winrt::Microsoft::Management::Deployment::ConnectResultStatus ConnectResult::Status() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalog ConnectResult::PackageCatalog() - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp b/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp deleted file mode 100644 index 8a674b87a9..0000000000 --- a/src/Microsoft.Management.Deployment.Client/FindPackagesResult.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "FindPackagesResult.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResult::Status() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::Collections::IVectorView FindPackagesResult::Matches() - { - throw hresult_not_implemented(); - } - bool FindPackagesResult::WasLimitExceeded() - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/InstallResult.cpp b/src/Microsoft.Management.Deployment.Client/InstallResult.cpp deleted file mode 100644 index 18b06b4e5c..0000000000 --- a/src/Microsoft.Management.Deployment.Client/InstallResult.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "InstallResult.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring InstallResult::CorrelationData() - { - throw hresult_not_implemented(); - } - bool InstallResult::RebootRequired() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::InstallResultStatus InstallResult::Status() - { - throw hresult_not_implemented(); - } - winrt::hresult InstallResult::ExtendedErrorCode() - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/MatchResult.cpp b/src/Microsoft.Management.Deployment.Client/MatchResult.cpp deleted file mode 100644 index cf514c00c9..0000000000 --- a/src/Microsoft.Management.Deployment.Client/MatchResult.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "MatchResult.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - winrt::Microsoft::Management::Deployment::CatalogPackage MatchResult::CatalogPackage() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchResult::MatchCriteria() - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj index 9edd61d1ca..279b359810 100644 --- a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj +++ b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj @@ -134,20 +134,10 @@ - - - - - - - - - - Create diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp deleted file mode 100644 index aa7adf22d1..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalog.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "PackageCatalog.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - bool PackageCatalog::IsComposite() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalog::Info() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::IAsyncOperation PackageCatalog::FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions) - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::FindPackagesResult PackageCatalog::FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const&) - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp deleted file mode 100644 index 11beb2415b..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogInfo.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "PackageCatalogInfo.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring PackageCatalogInfo::Id() - { - throw hresult_not_implemented(); - } - hstring PackageCatalogInfo::Name() - { - throw hresult_not_implemented(); - } - hstring PackageCatalogInfo::Type() - { - throw hresult_not_implemented(); - } - hstring PackageCatalogInfo::Argument() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::DateTime PackageCatalogInfo::LastUpdateTime() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalogOrigin PackageCatalogInfo::Origin() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel PackageCatalogInfo::TrustLevel() - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp b/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp deleted file mode 100644 index 62447e1ca9..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageCatalogReference.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "PackageCatalogReference.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - bool PackageCatalogReference::IsComposite() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalogReference::Info() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::IAsyncOperation PackageCatalogReference::ConnectAsync() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::ConnectResult PackageCatalogReference::Connect() - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp b/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp deleted file mode 100644 index ce887cfe29..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionId.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "PackageVersionId.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring PackageVersionId::PackageCatalogId() - { - throw hresult_not_implemented(); - } - hstring PackageVersionId::Version() - { - throw hresult_not_implemented(); - } - hstring PackageVersionId::Channel() - { - throw hresult_not_implemented(); - } -} diff --git a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp b/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp deleted file mode 100644 index 3fa6e9b5b3..0000000000 --- a/src/Microsoft.Management.Deployment.Client/PackageVersionInfo.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" -#include -#include "PackageVersionInfo.g.cpp" - -namespace winrt::Microsoft::Management::Deployment::implementation -{ - hstring PackageVersionInfo::GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const&) - { - throw hresult_not_implemented(); - } - hstring PackageVersionInfo::Id() - { - throw hresult_not_implemented(); - } - hstring PackageVersionInfo::DisplayName() - { - throw hresult_not_implemented(); - } - hstring PackageVersionInfo::Version() - { - throw hresult_not_implemented(); - } - hstring PackageVersionInfo::Channel() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::Collections::IVectorView PackageVersionInfo::PackageFamilyNames() - { - throw hresult_not_implemented(); - } - winrt::Windows::Foundation::Collections::IVectorView PackageVersionInfo::ProductCodes() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::PackageCatalog PackageVersionInfo::PackageCatalog() - { - throw hresult_not_implemented(); - } - winrt::Microsoft::Management::Deployment::CompareResult PackageVersionInfo::CompareToVersion(hstring versionString) - { - throw hresult_not_implemented(); - } -} From e32bf8d763f6396430c2bb1b9124a299d1ef7765 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:04:03 -0700 Subject: [PATCH 28/53] Run Com Interface tests --- azure-pipelines.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 592561ff71..b0fdc7a9b8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -228,7 +228,7 @@ jobs: name: HTTPSDevCert displayName: 'Download Kestrel Certificate' inputs: - secureFile: 'HTTPSDevCert.pfx' + secureFile: 'HTTPSDevCertV2.pfx' - task: MSBuild@1 displayName: Build MSIX Test Installer File @@ -300,6 +300,17 @@ jobs: -PackageCertificatePath $(AppInstallerTest.secureFilePath)' condition: succeededOrFailed() + - task: VSTest@2 + displayName: Run Com Interface Tests + inputs: + testRunTitle: 'Com Interface Tests' + platform: 'x64' + testSelector: 'testAssemblies' + testAssemblyVer2: | + src\x64\Release\PackagedTests.build.appxrecipe + src\x64\Release\*TestAdapter.dll + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 displayName: Publish E2E Tests Packaged x86 Log inputs: From f9b603245c32491133194e633e04f52771a7de38 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:08:41 -0700 Subject: [PATCH 29/53] Add appxrecipe to spelling --- .github/actions/spelling/allow.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index e340400180..6031bc1906 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -17,6 +17,7 @@ apps appx appxbundle appxmanifest +appxrecipe appxsdk APSTUDIO argc From 345100b6a5345d963be4db2fc0ecff29f78683c3 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 3 Sep 2021 16:29:12 -0700 Subject: [PATCH 30/53] Update test path --- azure-pipelines.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b0fdc7a9b8..a036636d9f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -300,6 +300,14 @@ jobs: -PackageCertificatePath $(AppInstallerTest.secureFilePath)' condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: Publish E2E Tests Packaged x86 Log + inputs: + PathtoPublish: 'C:\Users\VssAdministrator\AppData\Local\Packages\WinGetDevCLI_8wekyb3d8bbwe\LocalState\DiagOutputDir' + ArtifactName: 'E2ETestPackagedx86Log' + publishLocation: 'Container' + condition: succeededOrFailed() + - task: VSTest@2 displayName: Run Com Interface Tests inputs: @@ -307,18 +315,10 @@ jobs: platform: 'x64' testSelector: 'testAssemblies' testAssemblyVer2: | - src\x64\Release\PackagedTests.build.appxrecipe - src\x64\Release\*TestAdapter.dll + src\x64\Release\PackagedTests\PackagedTests.build.appxrecipe + src\x64\Release\PackagedTests\*TestAdapter.dll condition: succeededOrFailed() - - task: PublishBuildArtifacts@1 - displayName: Publish E2E Tests Packaged x86 Log - inputs: - PathtoPublish: 'C:\Users\VssAdministrator\AppData\Local\Packages\WinGetDevCLI_8wekyb3d8bbwe\LocalState\DiagOutputDir' - ArtifactName: 'E2ETestPackagedx86Log' - publishLocation: 'Container' - condition: succeededOrFailed() - - task: PublishBuildArtifacts@1 displayName: Publish CLI Binary inputs: From ee6ac78a9ab59754991b47777c04fc656fe14ae4 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Tue, 7 Sep 2021 12:49:14 -0700 Subject: [PATCH 31/53] Update test paths. --- azure-pipelines.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a036636d9f..27d954e4ec 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -308,6 +308,7 @@ jobs: publishLocation: 'Container' condition: succeededOrFailed() + # Run the tests from the x64 package. - task: VSTest@2 displayName: Run Com Interface Tests inputs: @@ -315,8 +316,8 @@ jobs: platform: 'x64' testSelector: 'testAssemblies' testAssemblyVer2: | - src\x64\Release\PackagedTests\PackagedTests.build.appxrecipe - src\x64\Release\PackagedTests\*TestAdapter.dll + src\x86\Release\PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe + src\x86\Release\PackagedTests\x64\PackagedTests\*TestAdapter.dll condition: succeededOrFailed() - task: PublishBuildArtifacts@1 From 2681ebc3694f92f174926e301709d4cdd43749ec Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Tue, 7 Sep 2021 15:06:51 -0700 Subject: [PATCH 32/53] Remove test adapter dll from testassembly --- azure-pipelines.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 27d954e4ec..a335465a32 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -317,7 +317,6 @@ jobs: testSelector: 'testAssemblies' testAssemblyVer2: | src\x86\Release\PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe - src\x86\Release\PackagedTests\x64\PackagedTests\*TestAdapter.dll condition: succeededOrFailed() - task: PublishBuildArtifacts@1 From 0ed4c0c11c33f8a8101176a54b8e71742ce34385 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 8 Sep 2021 03:28:43 -0700 Subject: [PATCH 33/53] Add powershell task to install wingetdev --- azure-pipelines.yml | 17 ++++++++- src/PackagedTests/Run-InstallPackage.ps1 | 44 ++++++++++++++++++++++++ src/PackagedTests/Run-RemovePackage.ps1 | 9 +++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/PackagedTests/Run-InstallPackage.ps1 create mode 100644 src/PackagedTests/Run-RemovePackage.ps1 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a335465a32..eaff0c5007 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -308,7 +308,15 @@ jobs: publishLocation: 'Container' condition: succeededOrFailed() - # Run the tests from the x64 package. + - task: PowerShell@2 + displayName: Install WinGetDev package + inputs: + filePath: 'src\PackagedTests\Run-InstallPackage.ps1' + arguments: '-BuildRoot x86\Release -PackageRoot AppInstallerCLIPackage\bin\x86\Release' + workingDirectory: 'src' + condition: succeededOrFailed() + + # Run the tests from the x64 package. These tests make cross package com calls to the previously installed WinGetDev package. - task: VSTest@2 displayName: Run Com Interface Tests inputs: @@ -319,6 +327,13 @@ jobs: src\x86\Release\PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe condition: succeededOrFailed() + - task: PowerShell@2 + displayName: Remove WinGetDev package + inputs: + filePath: 'src\PackagedTests\Run-RemovePackage.ps1' + workingDirectory: 'src' + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 displayName: Publish CLI Binary inputs: diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 new file mode 100644 index 0000000000..5c920eb73c --- /dev/null +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -0,0 +1,44 @@ +<# +.SYNOPSIS + Registers the AppInstallerCLI package. +.DESCRIPTION + Registers the loose files generated by the AppInstallerCLIPackage project +.PARAMETER BuildRoot + The root of the build output directory. If not provided, assumed to be the local default + location relative to this script. +.PARAMETER PackageRoot + The root of the package build output directory. If not provided, assumed to be the local default + location relative to this script. +#> +param( + [Parameter(Mandatory=$false)] + [string]$BuildRoot, + + [Parameter(Mandatory=$false)] + [string]$PackageRoot +) + +if ([String]::IsNullOrEmpty($BuildRoot)) +{ + $BuildRoot = Split-Path -Parent $PSCommandPath; + $BuildRoot = Join-Path $BuildRoot "..\x64\Debug"; +} +$BuildRoot = Resolve-Path $BuildRoot +Write-Host "Using BuildRoot = $BuildRoot" + +if ([String]::IsNullOrEmpty($PackageRoot)) +{ + $PackageRoot = Split-Path -Parent $PSCommandPath; + $PackageRoot = Join-Path $PackageRoot "..\AppInstallerCLIPackage\bin\x64\Debug"; +} +$PackageRoot = Resolve-Path $PackageRoot +Write-Host "Using PackageRoot = $PackageRoot" + +# Register the package; this requires the local package to have been deployed at least once or it won't be built. +$Local:ManifestPath = Join-Path $PackageRoot "AppxManifest.xml" +if (-not (Test-Path $Local:ManifestPath)) +{ + $Local:ManifestPath = Join-Path $PackageRoot "AppX\AppxManifest.xml" +} +Write-Host "Registering manifest at path: $Local:ManifestPath" +Add-AppxPackage -Register $Local:ManifestPath diff --git a/src/PackagedTests/Run-RemovePackage.ps1 b/src/PackagedTests/Run-RemovePackage.ps1 new file mode 100644 index 0000000000..fafcdec5f6 --- /dev/null +++ b/src/PackagedTests/Run-RemovePackage.ps1 @@ -0,0 +1,9 @@ +<# +.SYNOPSIS + Removes the AppInstallerCLI package. +.DESCRIPTION + Removes the loose files generated by the AppInstallerCLIPackage project +#> + +Write-Host "Remove registered package" +Get-AppxPackage WinGetDevCLI | Remove-AppxPackage \ No newline at end of file From 6934b833907e371992c3fd43a62af3b1963953ac Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 8 Sep 2021 13:14:27 -0700 Subject: [PATCH 34/53] Add runsettings file to publish logs. --- azure-pipelines.yml | 1 + src/PackagedTests/PackagedTests.csproj | 5 ++++ src/PackagedTests/Run-InstallPackage.ps1 | 2 ++ src/PackagedTests/Test.runsettings | 32 ++++++++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 src/PackagedTests/Test.runsettings diff --git a/azure-pipelines.yml b/azure-pipelines.yml index eaff0c5007..6649d55252 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -325,6 +325,7 @@ jobs: testSelector: 'testAssemblies' testAssemblyVer2: | src\x86\Release\PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe + runSettingsFile: 'src\x86\Release\PackagedTests\Test.runsettings' condition: succeededOrFailed() - task: PowerShell@2 diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index ff2442475e..0fa5f6c14a 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -106,6 +106,11 @@ Microsoft.Management.Deployment.Client + + + PreserveNewest + + 14.0 diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index 5c920eb73c..b8a5385462 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -40,5 +40,7 @@ if (-not (Test-Path $Local:ManifestPath)) { $Local:ManifestPath = Join-Path $PackageRoot "AppX\AppxManifest.xml" } +Get-AppxPackage WinGetDevCLI Write-Host "Registering manifest at path: $Local:ManifestPath" Add-AppxPackage -Register $Local:ManifestPath +Get-AppxPackage WinGetDevCLI diff --git a/src/PackagedTests/Test.runsettings b/src/PackagedTests/Test.runsettings new file mode 100644 index 0000000000..69a4dbab5c --- /dev/null +++ b/src/PackagedTests/Test.runsettings @@ -0,0 +1,32 @@ + + + + + + + + true + + + + + + + + quiet + + + + + PackagedTestsResults.trx + + + + + PackagedTestsResults.html + + + + + + \ No newline at end of file From 33dc1fe9ac64b6a6d83141ebfdfeb7886c23a460 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 8 Sep 2021 19:13:45 -0700 Subject: [PATCH 35/53] Test installing package in vstest --- azure-pipelines.yml | 1 + src/PackagedTests/ComInterfaceUnitTest.cs | 48 +++++++++++++++++++++++ src/PackagedTests/Package.appxmanifest | 2 + src/PackagedTests/Test.runsettings | 8 +++- 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6649d55252..a907355e0a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -326,6 +326,7 @@ jobs: testAssemblyVer2: | src\x86\Release\PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe runSettingsFile: 'src\x86\Release\PackagedTests\Test.runsettings' + overrideTestrunParameters: '-AICLIPackagePath $(appxPackageDir)AppInstallerCLIPackage_0.0.2.0_Test\AppInstallerCLIPackage_0.0.2.0_x86_x64.msixbundle' condition: succeededOrFailed() - task: PowerShell@2 diff --git a/src/PackagedTests/ComInterfaceUnitTest.cs b/src/PackagedTests/ComInterfaceUnitTest.cs index 31807e88e9..abfe4038db 100644 --- a/src/PackagedTests/ComInterfaceUnitTest.cs +++ b/src/PackagedTests/ComInterfaceUnitTest.cs @@ -1,6 +1,7 @@  using System; using System.Collections.Generic; +using System.Diagnostics; using Microsoft.Management.Deployment; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -9,6 +10,53 @@ namespace PackagedUnitTests [TestClass] public class ComInterfaceUnitTests { + [AssemblyInitialize] + public static void AssemblyInitialize(TestContext context) + { + string path = context.Properties["AICLIPackagePath"].ToString(); + Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("Checking for package"); + Windows.Management.Deployment.PackageManager pm = new Windows.Management.Deployment.PackageManager(); + var packages = pm.FindPackagesForUser("", "WinGetDevCLI_8wekyb3d8bbwe"); + var enumerator = packages.GetEnumerator(); + bool hasMoreItems = enumerator.MoveNext(); + if (hasMoreItems) + { + Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("Found package already installed"); + } + Uri uri = new Uri(path); + Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("Adding package: " + path); + var task = pm.AddPackageAsync(uri, null, Windows.Management.Deployment.DeploymentOptions.None).AsTask(); + task.Wait(); + var result = task.Result; + if (result.ExtendedErrorCode != null) + { + Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("AddPackage result: " + result.ExtendedErrorCode + " " + result.ErrorText); + throw result.ExtendedErrorCode; + } + } + + [AssemblyCleanup] + public static void AssemblyCleanup() + { + Windows.Management.Deployment.PackageManager pm = new Windows.Management.Deployment.PackageManager(); + var packages = pm.FindPackagesForUser("", "WinGetDevCLI_8wekyb3d8bbwe"); + var enumerator = packages.GetEnumerator(); + bool hasMoreItems = enumerator.MoveNext(); + if (hasMoreItems) + { + string fullName = enumerator.Current.Id.FullName; + Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("Removing package: " + fullName); + var task = pm.RemovePackageAsync(fullName).AsTask(); + task.Wait(); + var result = task.Result; + if (result.ExtendedErrorCode != null) + { + Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("RemovePackage result: " + result.ExtendedErrorCode + " " + result.ErrorText); + throw result.ExtendedErrorCode; + } + } + } + [TestMethod] public void OpenPredefinedCatalog() { diff --git a/src/PackagedTests/Package.appxmanifest b/src/PackagedTests/Package.appxmanifest index c9be52023f..39a0ba3519 100644 --- a/src/PackagedTests/Package.appxmanifest +++ b/src/PackagedTests/Package.appxmanifest @@ -3,6 +3,7 @@ xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" + xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp"> + diff --git a/src/PackagedTests/Test.runsettings b/src/PackagedTests/Test.runsettings index 69a4dbab5c..cdaa7aa4f0 100644 --- a/src/PackagedTests/Test.runsettings +++ b/src/PackagedTests/Test.runsettings @@ -1,7 +1,13 @@  - + + + + From d112dc527052f80d255e3dacec1d381a7cc68fcd Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 8 Sep 2021 23:22:37 -0700 Subject: [PATCH 36/53] Try newer windows server. --- azure-pipelines.yml | 2 +- src/PackagedTests/ComInterfaceUnitTest.cs | 47 ----------------------- 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a907355e0a..49321ad7a0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -13,7 +13,7 @@ pr: - src/* pool: - vmImage: 'windows-latest' + vmImage: 'windows-2022' variables: solution: 'src/AppInstallerCLI.sln' diff --git a/src/PackagedTests/ComInterfaceUnitTest.cs b/src/PackagedTests/ComInterfaceUnitTest.cs index abfe4038db..1c62b940c5 100644 --- a/src/PackagedTests/ComInterfaceUnitTest.cs +++ b/src/PackagedTests/ComInterfaceUnitTest.cs @@ -10,53 +10,6 @@ namespace PackagedUnitTests [TestClass] public class ComInterfaceUnitTests { - [AssemblyInitialize] - public static void AssemblyInitialize(TestContext context) - { - string path = context.Properties["AICLIPackagePath"].ToString(); - Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("Checking for package"); - Windows.Management.Deployment.PackageManager pm = new Windows.Management.Deployment.PackageManager(); - var packages = pm.FindPackagesForUser("", "WinGetDevCLI_8wekyb3d8bbwe"); - var enumerator = packages.GetEnumerator(); - bool hasMoreItems = enumerator.MoveNext(); - if (hasMoreItems) - { - Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("Found package already installed"); - } - Uri uri = new Uri(path); - Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("Adding package: " + path); - var task = pm.AddPackageAsync(uri, null, Windows.Management.Deployment.DeploymentOptions.None).AsTask(); - task.Wait(); - var result = task.Result; - if (result.ExtendedErrorCode != null) - { - Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("AddPackage result: " + result.ExtendedErrorCode + " " + result.ErrorText); - throw result.ExtendedErrorCode; - } - } - - [AssemblyCleanup] - public static void AssemblyCleanup() - { - Windows.Management.Deployment.PackageManager pm = new Windows.Management.Deployment.PackageManager(); - var packages = pm.FindPackagesForUser("", "WinGetDevCLI_8wekyb3d8bbwe"); - var enumerator = packages.GetEnumerator(); - bool hasMoreItems = enumerator.MoveNext(); - if (hasMoreItems) - { - string fullName = enumerator.Current.Id.FullName; - Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("Removing package: " + fullName); - var task = pm.RemovePackageAsync(fullName).AsTask(); - task.Wait(); - var result = task.Result; - if (result.ExtendedErrorCode != null) - { - Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage("RemovePackage result: " + result.ExtendedErrorCode + " " + result.ErrorText); - throw result.ExtendedErrorCode; - } - } - } - [TestMethod] public void OpenPredefinedCatalog() { From 893724e4f6dd336defde4ae1c648ed1e6c9647a4 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 9 Sep 2021 15:22:18 -0700 Subject: [PATCH 37/53] Try enable com tracing for tests. --- .github/actions/spelling/allow.txt | 1 + azure-pipelines.yml | 10 ++++++- src/PackagedTests/Run-InstallPackage.ps1 | 2 ++ src/PackagedTests/Run-RemovePackage.ps1 | 4 ++- src/PackagedTests/Test.runsettings | 7 ----- tools/wpr/ComTrace.wprp | 35 +++++++++++++++++++++++ tools/wpr/wpr.config.xml | 11 +++++++ tools/wpr/wpr.exe | Bin 0 -> 385312 bytes 8 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 tools/wpr/ComTrace.wprp create mode 100644 tools/wpr/wpr.config.xml create mode 100644 tools/wpr/wpr.exe diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 6031bc1906..2c4fa6864e 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -504,6 +504,7 @@ TRACELOGGING triaged trunc TRUSTEDPEOPLE +trx tt ttl typedef diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 49321ad7a0..a7eabe8eb5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -13,7 +13,7 @@ pr: - src/* pool: - vmImage: 'windows-2022' + vmImage: 'windows-latest' variables: solution: 'src/AppInstallerCLI.sln' @@ -335,6 +335,14 @@ jobs: filePath: 'src\PackagedTests\Run-RemovePackage.ps1' workingDirectory: 'src' condition: succeededOrFailed() + + - task: PublishBuildArtifacts@1 + displayName: Publish Com Trace from Interface tests + inputs: + PathtoPublish: 'tools\wpr\comTrace.etl' + ArtifactName: 'ComTraceFromInterfaceTest' + publishLocation: 'Container' + condition: succeededOrFailed() - task: PublishBuildArtifacts@1 displayName: Publish CLI Binary diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index b8a5385462..efa9b6dec6 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -41,6 +41,8 @@ if (-not (Test-Path $Local:ManifestPath)) $Local:ManifestPath = Join-Path $PackageRoot "AppX\AppxManifest.xml" } Get-AppxPackage WinGetDevCLI +Write-Host "Enabling com tracing." +..\tools\wpr\wpr.exe -start ..\tools\wpr\ComTrace.wprp -filemode Write-Host "Registering manifest at path: $Local:ManifestPath" Add-AppxPackage -Register $Local:ManifestPath Get-AppxPackage WinGetDevCLI diff --git a/src/PackagedTests/Run-RemovePackage.ps1 b/src/PackagedTests/Run-RemovePackage.ps1 index fafcdec5f6..52001c7697 100644 --- a/src/PackagedTests/Run-RemovePackage.ps1 +++ b/src/PackagedTests/Run-RemovePackage.ps1 @@ -6,4 +6,6 @@ #> Write-Host "Remove registered package" -Get-AppxPackage WinGetDevCLI | Remove-AppxPackage \ No newline at end of file +Get-AppxPackage WinGetDevCLI | Remove-AppxPackage +Write-Host "Ending com trace" +..\tools\wpr\wpr.exe -stop ..\tools\wpr\comTrace.etl \ No newline at end of file diff --git a/src/PackagedTests/Test.runsettings b/src/PackagedTests/Test.runsettings index cdaa7aa4f0..45bf65ffba 100644 --- a/src/PackagedTests/Test.runsettings +++ b/src/PackagedTests/Test.runsettings @@ -1,13 +1,6 @@  - - - - diff --git a/tools/wpr/ComTrace.wprp b/tools/wpr/ComTrace.wprp new file mode 100644 index 0000000000..b7f3c9d700 --- /dev/null +++ b/tools/wpr/ComTrace.wprp @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/wpr/wpr.config.xml b/tools/wpr/wpr.config.xml new file mode 100644 index 0000000000..08443dd819 --- /dev/null +++ b/tools/wpr/wpr.config.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tools/wpr/wpr.exe b/tools/wpr/wpr.exe new file mode 100644 index 0000000000000000000000000000000000000000..e49b6b307da9ec4a3436a360a194434737dc367b GIT binary patch literal 385312 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%0Ap-b=sQRyCmugn9R{3YqZ2LD#KA5PR5cpQtb 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%0DdTP}woWk}=`x=1r^2Lj2-0(o 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 literal 0 HcmV?d00001 From 9d3cf616ead15bfd925fe11fb86534ba491c3fdd Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 9 Sep 2021 17:20:32 -0700 Subject: [PATCH 38/53] Try direct run of vstest --- azure-pipelines.yml | 15 +-------------- src/PackagedTests/Run-InstallPackage.ps1 | 10 +++++++++- src/PackagedTests/Run-RemovePackage.ps1 | 4 +--- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a7eabe8eb5..f1127c8871 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -316,19 +316,6 @@ jobs: workingDirectory: 'src' condition: succeededOrFailed() - # Run the tests from the x64 package. These tests make cross package com calls to the previously installed WinGetDev package. - - task: VSTest@2 - displayName: Run Com Interface Tests - inputs: - testRunTitle: 'Com Interface Tests' - platform: 'x64' - testSelector: 'testAssemblies' - testAssemblyVer2: | - src\x86\Release\PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe - runSettingsFile: 'src\x86\Release\PackagedTests\Test.runsettings' - overrideTestrunParameters: '-AICLIPackagePath $(appxPackageDir)AppInstallerCLIPackage_0.0.2.0_Test\AppInstallerCLIPackage_0.0.2.0_x86_x64.msixbundle' - condition: succeededOrFailed() - - task: PowerShell@2 displayName: Remove WinGetDev package inputs: @@ -339,7 +326,7 @@ jobs: - task: PublishBuildArtifacts@1 displayName: Publish Com Trace from Interface tests inputs: - PathtoPublish: 'tools\wpr\comTrace.etl' + PathtoPublish: 'tools\wpr\traces' ArtifactName: 'ComTraceFromInterfaceTest' publishLocation: 'Container' condition: succeededOrFailed() diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index efa9b6dec6..5453e6685d 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -42,7 +42,15 @@ if (-not (Test-Path $Local:ManifestPath)) } Get-AppxPackage WinGetDevCLI Write-Host "Enabling com tracing." -..\tools\wpr\wpr.exe -start ..\tools\wpr\ComTrace.wprp -filemode +D:\a\1\s\tools\wpr\wpr.exe -start D:\a\1\s\tools\wpr\ComTrace.wprp -filemode Write-Host "Registering manifest at path: $Local:ManifestPath" Add-AppxPackage -Register $Local:ManifestPath Get-AppxPackage WinGetDevCLI + +$Local:AppxRecipePath = Join-Path $BuildRoot "PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe" +Write-Host "Running tests: $Local:AppxRecipePath" +"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" $Local:AppxRecipePath /logger:trx;LogFileName=D:\a\1\s\tools\wpr\traces\comTestRun.trx +Write-Host "Finished Tests" +Write-Host "Ending com trace" +D:\a\1\s\tools\wpr\wpr.exe -stop D:\a\1\s\tools\wpr\traces\comTrace.etl +Write-Host "Ended com trace" diff --git a/src/PackagedTests/Run-RemovePackage.ps1 b/src/PackagedTests/Run-RemovePackage.ps1 index 52001c7697..fafcdec5f6 100644 --- a/src/PackagedTests/Run-RemovePackage.ps1 +++ b/src/PackagedTests/Run-RemovePackage.ps1 @@ -6,6 +6,4 @@ #> Write-Host "Remove registered package" -Get-AppxPackage WinGetDevCLI | Remove-AppxPackage -Write-Host "Ending com trace" -..\tools\wpr\wpr.exe -stop ..\tools\wpr\comTrace.etl \ No newline at end of file +Get-AppxPackage WinGetDevCLI | Remove-AppxPackage \ No newline at end of file From 729a22c45f11584da43d9646180092da43c4103a Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 9 Sep 2021 19:24:32 -0700 Subject: [PATCH 39/53] Fix install script to call add script. --- azure-pipelines.yml | 2 +- src/PackagedTests/Run-InstallPackage.ps1 | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f1127c8871..032304bd28 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -312,7 +312,7 @@ jobs: displayName: Install WinGetDev package inputs: filePath: 'src\PackagedTests\Run-InstallPackage.ps1' - arguments: '-BuildRoot x86\Release -PackageRoot AppInstallerCLIPackage\bin\x86\Release' + arguments: '-BuildRoot x86\Release -PackageRoot AppInstallerCLIPackage\AppPackages\*' workingDirectory: 'src' condition: succeededOrFailed() diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index 5453e6685d..2199d6218a 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -41,15 +41,18 @@ if (-not (Test-Path $Local:ManifestPath)) $Local:ManifestPath = Join-Path $PackageRoot "AppX\AppxManifest.xml" } Get-AppxPackage WinGetDevCLI +Write-Host "Remove registered package" +Get-AppxPackage WinGetDevCLI | Remove-AppxPackage Write-Host "Enabling com tracing." D:\a\1\s\tools\wpr\wpr.exe -start D:\a\1\s\tools\wpr\ComTrace.wprp -filemode -Write-Host "Registering manifest at path: $Local:ManifestPath" -Add-AppxPackage -Register $Local:ManifestPath +$Local:AddScript = Join-Path $PackageRoot "Add-AppDevPackage.ps1" +Write-Host "Installing package at path: $Local:AddScript" +& $Local:AddScript -Force Get-AppxPackage WinGetDevCLI $Local:AppxRecipePath = Join-Path $BuildRoot "PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe" Write-Host "Running tests: $Local:AppxRecipePath" -"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" $Local:AppxRecipePath /logger:trx;LogFileName=D:\a\1\s\tools\wpr\traces\comTestRun.trx +& "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" "$Local:AppxRecipePath" "/logger:trx;LogFileName=D:\a\1\s\tools\wpr\traces\comTestRun.trx" Write-Host "Finished Tests" Write-Host "Ending com trace" D:\a\1\s\tools\wpr\wpr.exe -stop D:\a\1\s\tools\wpr\traces\comTrace.etl From c14f1d8529a879ca73e655f60a2dd017bfcd4468 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 9 Sep 2021 20:27:44 -0700 Subject: [PATCH 40/53] Fix appxpackages path. --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 032304bd28..5575b6bc31 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -312,7 +312,7 @@ jobs: displayName: Install WinGetDev package inputs: filePath: 'src\PackagedTests\Run-InstallPackage.ps1' - arguments: '-BuildRoot x86\Release -PackageRoot AppInstallerCLIPackage\AppPackages\*' + arguments: '-BuildRoot x86\Release -PackageRoot $(appxPackageDir)\*' workingDirectory: 'src' condition: succeededOrFailed() From c125c0c01a060dfcc0fb6c5dd32e2a3fe816819e Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 9 Sep 2021 22:04:13 -0700 Subject: [PATCH 41/53] Fix path again, remove trace --- azure-pipelines.yml | 22 ++++++++++------- src/PackagedTests/Run-InstallPackage.ps1 | 30 ------------------------ 2 files changed, 13 insertions(+), 39 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5575b6bc31..19e0708111 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -312,24 +312,28 @@ jobs: displayName: Install WinGetDev package inputs: filePath: 'src\PackagedTests\Run-InstallPackage.ps1' - arguments: '-BuildRoot x86\Release -PackageRoot $(appxPackageDir)\*' + arguments: '-PackageRoot $(appxPackageDir)\AppInstallerCLIPackage_*_Test' workingDirectory: 'src' condition: succeededOrFailed() +# Run the tests from the x64 package. These tests make cross package com calls to the previously installed WinGetDev package. + - task: VSTest@2 + displayName: Run Com Interface Tests + inputs: + testRunTitle: 'Com Interface Tests' + platform: 'x64' + testSelector: 'testAssemblies' + testAssemblyVer2: | + src\x86\Release\PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe + runSettingsFile: 'src\x86\Release\PackagedTests\Test.runsettings' + condition: succeededOrFailed() + - task: PowerShell@2 displayName: Remove WinGetDev package inputs: filePath: 'src\PackagedTests\Run-RemovePackage.ps1' workingDirectory: 'src' condition: succeededOrFailed() - - - task: PublishBuildArtifacts@1 - displayName: Publish Com Trace from Interface tests - inputs: - PathtoPublish: 'tools\wpr\traces' - ArtifactName: 'ComTraceFromInterfaceTest' - publishLocation: 'Container' - condition: succeededOrFailed() - task: PublishBuildArtifacts@1 displayName: Publish CLI Binary diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index 2199d6218a..6ba7f6e971 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -3,29 +3,14 @@ Registers the AppInstallerCLI package. .DESCRIPTION Registers the loose files generated by the AppInstallerCLIPackage project -.PARAMETER BuildRoot - The root of the build output directory. If not provided, assumed to be the local default - location relative to this script. .PARAMETER PackageRoot The root of the package build output directory. If not provided, assumed to be the local default location relative to this script. #> param( - [Parameter(Mandatory=$false)] - [string]$BuildRoot, - [Parameter(Mandatory=$false)] [string]$PackageRoot ) - -if ([String]::IsNullOrEmpty($BuildRoot)) -{ - $BuildRoot = Split-Path -Parent $PSCommandPath; - $BuildRoot = Join-Path $BuildRoot "..\x64\Debug"; -} -$BuildRoot = Resolve-Path $BuildRoot -Write-Host "Using BuildRoot = $BuildRoot" - if ([String]::IsNullOrEmpty($PackageRoot)) { $PackageRoot = Split-Path -Parent $PSCommandPath; @@ -34,26 +19,11 @@ if ([String]::IsNullOrEmpty($PackageRoot)) $PackageRoot = Resolve-Path $PackageRoot Write-Host "Using PackageRoot = $PackageRoot" -# Register the package; this requires the local package to have been deployed at least once or it won't be built. -$Local:ManifestPath = Join-Path $PackageRoot "AppxManifest.xml" -if (-not (Test-Path $Local:ManifestPath)) -{ - $Local:ManifestPath = Join-Path $PackageRoot "AppX\AppxManifest.xml" -} Get-AppxPackage WinGetDevCLI Write-Host "Remove registered package" Get-AppxPackage WinGetDevCLI | Remove-AppxPackage -Write-Host "Enabling com tracing." -D:\a\1\s\tools\wpr\wpr.exe -start D:\a\1\s\tools\wpr\ComTrace.wprp -filemode $Local:AddScript = Join-Path $PackageRoot "Add-AppDevPackage.ps1" Write-Host "Installing package at path: $Local:AddScript" & $Local:AddScript -Force Get-AppxPackage WinGetDevCLI -$Local:AppxRecipePath = Join-Path $BuildRoot "PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe" -Write-Host "Running tests: $Local:AppxRecipePath" -& "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" "$Local:AppxRecipePath" "/logger:trx;LogFileName=D:\a\1\s\tools\wpr\traces\comTestRun.trx" -Write-Host "Finished Tests" -Write-Host "Ending com trace" -D:\a\1\s\tools\wpr\wpr.exe -stop D:\a\1\s\tools\wpr\traces\comTrace.etl -Write-Host "Ended com trace" From e088c8cba6045c4cc446dbdb48027f5c4029e739 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 10 Sep 2021 01:07:01 -0700 Subject: [PATCH 42/53] Extract unsigned package for loose register --- src/PackagedTests/Run-InstallPackage.ps1 | 26 ++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index 6ba7f6e971..4c0a2917a7 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -19,11 +19,29 @@ if ([String]::IsNullOrEmpty($PackageRoot)) $PackageRoot = Resolve-Path $PackageRoot Write-Host "Using PackageRoot = $PackageRoot" -Get-AppxPackage WinGetDevCLI +Get-AppxPackage WinGetDevCLI Write-Host "Remove registered package" Get-AppxPackage WinGetDevCLI | Remove-AppxPackage -$Local:AddScript = Join-Path $PackageRoot "Add-AppDevPackage.ps1" -Write-Host "Installing package at path: $Local:AddScript" -& $Local:AddScript -Force + +$Local:BundlePackageFormat = Join-Path $PackageRoot "AppInstallerCLIPackage*.msixbundle" +$Local:ResolvedPackagePath = Resolve-Path $Local:BundlePackageFormat +$Local:ExtractedBundlePath = Join-Path $PackageRoot "ExtractedBundle" +$Local:BundleCopyPath = Join-Path $PackageRoot "bundle.zip" +Copy-Item -Path $Local:ResolvedPackagePath -Destination $Local:BundleCopyPath +Write-Host "Expanding bundle at: $Local:ResolvedPackagePath" +Expand-Archive -Path $Local:BundleCopyPath -DestinationPath $Local:ExtractedBundlePath + +$Local:MainPackageFormat = Join-Path $Local:ExtractedBundlePath "AppInstallerCLIPackage*x86*.msix" +$Local:ResolvedMainPackagePath = Resolve-Path $Local:MainPackageFormat +$Local:ExtractedMainPath = Join-Path $PackageRoot "ExtractedMain" +$Local:MainCopyPath = Join-Path $PackageRoot "main.zip" +Copy-Item -Path $Local:ResolvedMainPackagePath -Destination $Local:MainCopyPath +Write-Host "Expanding package at: $Local:ResolvedMainPackagePath" +Expand-Archive -Path $Local:MainCopyPath -DestinationPath $Local:ExtractedMainPath + +$Local:ManifestPath = Join-Path $ExtractedMainPath "AppxManifest.xml" +Write-Host "Registering manifest at path: $Local:ManifestPath" +Add-AppxPackage -Register $Local:ManifestPath + Get-AppxPackage WinGetDevCLI From ed0a486612a0c73122366214c4b28e9a62c85991 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 10 Sep 2021 02:06:38 -0700 Subject: [PATCH 43/53] reenable tracing --- azure-pipelines.yml | 10 +++++++++- src/PackagedTests/Run-InstallPackage.ps1 | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 19e0708111..3623a5bd13 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -312,7 +312,7 @@ jobs: displayName: Install WinGetDev package inputs: filePath: 'src\PackagedTests\Run-InstallPackage.ps1' - arguments: '-PackageRoot $(appxPackageDir)\AppInstallerCLIPackage_*_Test' + arguments: '-BuildRoot x86\Release -PackageRoot $(appxPackageDir)\AppInstallerCLIPackage_*_Test' workingDirectory: 'src' condition: succeededOrFailed() @@ -335,6 +335,14 @@ jobs: workingDirectory: 'src' condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: Publish Com Trace from Interface tests + inputs: + PathtoPublish: 'tools\wpr\traces' + ArtifactName: 'ComTraceFromInterfaceTest' + publishLocation: 'Container' + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 displayName: Publish CLI Binary inputs: diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index 4c0a2917a7..3d7bb50c54 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -3,14 +3,28 @@ Registers the AppInstallerCLI package. .DESCRIPTION Registers the loose files generated by the AppInstallerCLIPackage project +.PARAMETER BuildRoot + The root of the build output directory. If not provided, assumed to be the local default + location relative to this script. .PARAMETER PackageRoot The root of the package build output directory. If not provided, assumed to be the local default location relative to this script. #> param( + [Parameter(Mandatory=$false)] + [string]$BuildRoot, + [Parameter(Mandatory=$false)] [string]$PackageRoot ) +if ([String]::IsNullOrEmpty($BuildRoot)) +{ + $BuildRoot = Split-Path -Parent $PSCommandPath; + $BuildRoot = Join-Path $BuildRoot "..\x64\Debug"; +} +$BuildRoot = Resolve-Path $BuildRoot +Write-Host "Using BuildRoot = $BuildRoot" + if ([String]::IsNullOrEmpty($PackageRoot)) { $PackageRoot = Split-Path -Parent $PSCommandPath; @@ -45,3 +59,13 @@ Add-AppxPackage -Register $Local:ManifestPath Get-AppxPackage WinGetDevCLI +Write-Host "Enabling com tracing." +D:\a\1\s\tools\wpr\wpr.exe -start D:\a\1\s\tools\wpr\ComTrace.wprp -filemode + +$Local:AppxRecipePath = Join-Path $BuildRoot "PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe" +Write-Host "Running tests: $Local:AppxRecipePath" +& "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" "$Local:AppxRecipePath" "/logger:trx;LogFileName=D:\a\1\s\tools\wpr\traces\comTestRun.trx" +Write-Host "Finished Tests" +Write-Host "Ending com trace" +D:\a\1\s\tools\wpr\wpr.exe -stop D:\a\1\s\tools\wpr\traces\comTrace.etl +Write-Host "Ended com trace" \ No newline at end of file From d5bf1dfb5501696465d0c50e1fd81c7b335688ac Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 10 Sep 2021 03:45:38 -0700 Subject: [PATCH 44/53] Include server in packagedtests --- azure-pipelines.yml | 7 +++---- src/PackagedTests.sln | 18 ++++++++++++++++++ src/PackagedTests/Package.appxmanifest | 20 ++++++++++++++++++++ src/PackagedTests/PackagedTests.csproj | 5 +++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3623a5bd13..a4a4af0178 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -309,10 +309,9 @@ jobs: condition: succeededOrFailed() - task: PowerShell@2 - displayName: Install WinGetDev package + displayName: Remove WinGetDev package inputs: - filePath: 'src\PackagedTests\Run-InstallPackage.ps1' - arguments: '-BuildRoot x86\Release -PackageRoot $(appxPackageDir)\AppInstallerCLIPackage_*_Test' + filePath: 'src\PackagedTests\Run-RemovePackage.ps1' workingDirectory: 'src' condition: succeededOrFailed() @@ -342,7 +341,7 @@ jobs: ArtifactName: 'ComTraceFromInterfaceTest' publishLocation: 'Container' condition: succeededOrFailed() - + - task: PublishBuildArtifacts@1 displayName: Publish CLI Binary inputs: diff --git a/src/PackagedTests.sln b/src/PackagedTests.sln index 42e13aa9e3..83f1e05b5a 100644 --- a/src/PackagedTests.sln +++ b/src/PackagedTests.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTe EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServer\WinGetServer.vcxproj", "{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -59,6 +61,22 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.ActiveCfg = Debug|ARM + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.Build.0 = Debug|ARM + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.Build.0 = Debug|ARM64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.ActiveCfg = Debug|x64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.Build.0 = Debug|x64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.ActiveCfg = Debug|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.Build.0 = Debug|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.ActiveCfg = Release|ARM + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.Build.0 = Release|ARM + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.ActiveCfg = Release|ARM64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.Build.0 = Release|ARM64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.ActiveCfg = Release|x64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.Build.0 = Release|x64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.ActiveCfg = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/PackagedTests/Package.appxmanifest b/src/PackagedTests/Package.appxmanifest index 39a0ba3519..3ffd14e38d 100644 --- a/src/PackagedTests/Package.appxmanifest +++ b/src/PackagedTests/Package.appxmanifest @@ -4,6 +4,7 @@ xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" + xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" IgnorableNamespaces="uap mp"> + + + + + + + + + + + + + + + + + + + diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 0fa5f6c14a..480f6545f5 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -28,6 +28,8 @@ false true TRACE;NETFX_CORE;WINDOWS_UWP + Always + x64 x86 @@ -85,6 +87,9 @@ + + PreserveNewest + From 22468d0cc329ec61288f2ee66818dca20fc704a1 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 10 Sep 2021 12:45:19 -0700 Subject: [PATCH 45/53] Remove build dependency on wingetserver project --- src/PackagedTests.sln | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/PackagedTests.sln b/src/PackagedTests.sln index 83f1e05b5a..42e13aa9e3 100644 --- a/src/PackagedTests.sln +++ b/src/PackagedTests.sln @@ -7,8 +7,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTe EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServer\WinGetServer.vcxproj", "{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -61,22 +59,6 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.ActiveCfg = Debug|ARM - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.Build.0 = Debug|ARM - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.Build.0 = Debug|ARM64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.ActiveCfg = Debug|x64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.Build.0 = Debug|x64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.ActiveCfg = Debug|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.Build.0 = Debug|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.ActiveCfg = Release|ARM - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.Build.0 = Release|ARM - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.ActiveCfg = Release|ARM64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.Build.0 = Release|ARM64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.ActiveCfg = Release|x64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.Build.0 = Release|x64 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.ActiveCfg = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 225ce50e8307d0df23d55d5549649d8a0c15ddd9 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 10 Sep 2021 15:06:48 -0700 Subject: [PATCH 46/53] Try tracelog comtracing. --- azure-pipelines.yml | 4 ++-- .../Client.PackageManager.h | 4 +++- src/PackagedTests/Package.appxmanifest | 19 ------------------- src/PackagedTests/PackagedTests.csproj | 3 --- src/PackagedTests/Run-InstallPackage.ps1 | 14 +++++++++++--- src/PackagedTests/Run-RemovePackage.ps1 | 5 +++++ 6 files changed, 21 insertions(+), 28 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a4a4af0178..e1b04d7ca2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -309,9 +309,9 @@ jobs: condition: succeededOrFailed() - task: PowerShell@2 - displayName: Remove WinGetDev package + displayName: Install WinGetDev package inputs: - filePath: 'src\PackagedTests\Run-RemovePackage.ps1' + filePath: 'src\PackagedTests\Run-InstallPackage.ps1' workingDirectory: 'src' condition: succeededOrFailed() diff --git a/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h b/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h index 2fb60f0a39..8e588957d4 100644 --- a/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h +++ b/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h @@ -3,11 +3,13 @@ namespace winrt::Microsoft::Management::Deployment::factory_implementation { + const CLSID CLSID_PackageManager2 = { 0x74CB3139, 0xB7C5, 0x4B9E, { 0x93, 0x88, 0xE6, 0x61, 0x6D, 0xEA, 0x28, 0x8C } }; //74CB3139-B7C5-4B9E-9388-E6616DEA288C + struct PackageManager : PackageManagerT { auto ActivateInstance() const { - return winrt::create_instance(__uuidof(implementation::PackageManager), CLSCTX_ALL); + return winrt::create_instance(CLSID_PackageManager2, CLSCTX_ALL); } }; } diff --git a/src/PackagedTests/Package.appxmanifest b/src/PackagedTests/Package.appxmanifest index 3ffd14e38d..1ae0ed5408 100644 --- a/src/PackagedTests/Package.appxmanifest +++ b/src/PackagedTests/Package.appxmanifest @@ -39,31 +39,12 @@ - - - - - - - - - - - - - - - - - - - diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index 480f6545f5..dedc9be585 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -87,9 +87,6 @@ - - PreserveNewest - diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index 3d7bb50c54..9c1fc94edb 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -50,6 +50,7 @@ $Local:ResolvedMainPackagePath = Resolve-Path $Local:MainPackageFormat $Local:ExtractedMainPath = Join-Path $PackageRoot "ExtractedMain" $Local:MainCopyPath = Join-Path $PackageRoot "main.zip" Copy-Item -Path $Local:ResolvedMainPackagePath -Destination $Local:MainCopyPath +Copy-Item -Path $Local:ResolvedMainPackagePath -Destination "D:\a\1\s\tools\wpr\traces\main.zip" Write-Host "Expanding package at: $Local:ResolvedMainPackagePath" Expand-Archive -Path $Local:MainCopyPath -DestinationPath $Local:ExtractedMainPath @@ -60,12 +61,19 @@ Add-AppxPackage -Register $Local:ManifestPath Get-AppxPackage WinGetDevCLI Write-Host "Enabling com tracing." -D:\a\1\s\tools\wpr\wpr.exe -start D:\a\1\s\tools\wpr\ComTrace.wprp -filemode +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "COMBASE" -guid "#bda92ae8-9f11-4d49-ba1d-a4c2abca692e" -flags "7" -f "D:\a\1\s\tools\wpr\traces\COMBASE.etl" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "DCOMSCM" -guid "#9474a749-a98d-4f52-9f45-5b20247e4f01" -flags "7" -f "D:\a\1\s\tools\wpr\traces\DCOMSCM.etl" $Local:AppxRecipePath = Join-Path $BuildRoot "PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe" Write-Host "Running tests: $Local:AppxRecipePath" & "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" "$Local:AppxRecipePath" "/logger:trx;LogFileName=D:\a\1\s\tools\wpr\traces\comTestRun.trx" Write-Host "Finished Tests" Write-Host "Ending com trace" -D:\a\1\s\tools\wpr\wpr.exe -stop D:\a\1\s\tools\wpr\traces\comTrace.etl -Write-Host "Ended com trace" \ No newline at end of file +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "COMBASE" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "DCOMSCM" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "COMBASE" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "DCOMSCM" +Write-Host "Ended com trace" +Write-Host "Started com trace again" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "COMBASE" -guid "#bda92ae8-9f11-4d49-ba1d-a4c2abca692e" -flags "7" -f "D:\a\1\s\tools\wpr\traces\COMBASEVS.etl" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "DCOMSCM" -guid "#9474a749-a98d-4f52-9f45-5b20247e4f01" -flags "7" -f "D:\a\1\s\tools\wpr\traces\DCOMSCMVS.etl" diff --git a/src/PackagedTests/Run-RemovePackage.ps1 b/src/PackagedTests/Run-RemovePackage.ps1 index fafcdec5f6..57a3490e92 100644 --- a/src/PackagedTests/Run-RemovePackage.ps1 +++ b/src/PackagedTests/Run-RemovePackage.ps1 @@ -5,5 +5,10 @@ Removes the loose files generated by the AppInstallerCLIPackage project #> +Write-Host "Ending com trace" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "COMBASE" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "DCOMSCM" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "COMBASE" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "DCOMSCM" Write-Host "Remove registered package" Get-AppxPackage WinGetDevCLI | Remove-AppxPackage \ No newline at end of file From 6d68e6fac13fffa4bbb76ee27462312a684c9cb5 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 10 Sep 2021 18:29:44 -0700 Subject: [PATCH 47/53] Fix powershell args. --- azure-pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e1b04d7ca2..0d340b8bdb 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -312,6 +312,7 @@ jobs: displayName: Install WinGetDev package inputs: filePath: 'src\PackagedTests\Run-InstallPackage.ps1' + arguments: '-BuildRoot x86\Release -PackageRoot $(appxPackageDir)\AppInstallerCLIPackage_*_Test' workingDirectory: 'src' condition: succeededOrFailed() From f76488325b9ed75e31d41af598a33672a8659d09 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Fri, 10 Sep 2021 20:25:04 -0700 Subject: [PATCH 48/53] Handle variable azure src dir paths. --- src/PackagedTests/Run-InstallPackage.ps1 | 26 ++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 index 9c1fc94edb..90bd862004 100644 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ b/src/PackagedTests/Run-InstallPackage.ps1 @@ -50,7 +50,14 @@ $Local:ResolvedMainPackagePath = Resolve-Path $Local:MainPackageFormat $Local:ExtractedMainPath = Join-Path $PackageRoot "ExtractedMain" $Local:MainCopyPath = Join-Path $PackageRoot "main.zip" Copy-Item -Path $Local:ResolvedMainPackagePath -Destination $Local:MainCopyPath -Copy-Item -Path $Local:ResolvedMainPackagePath -Destination "D:\a\1\s\tools\wpr\traces\main.zip" +$Local:WorkingDirSrc = Get-Location +Write-Host "Dir at: $Local:WorkingDirSrc" +$Local:WorkingDir = Split-Path $Local:WorkingDirSrc -Parent +Write-Host "Dir at: $Local:WorkingDir" +$Local:TraceOutputDir = Join-Path $Local:WorkingDir "tools\wpr\traces" +$Local:MainCopyArtifactPath = Join-Path $Local:TraceOutputDir "main.zip" +New-Item -Force $Local:MainCopyArtifactPath +Copy-Item -Path $Local:ResolvedMainPackagePath -Destination $Local:MainCopyArtifactPath Write-Host "Expanding package at: $Local:ResolvedMainPackagePath" Expand-Archive -Path $Local:MainCopyPath -DestinationPath $Local:ExtractedMainPath @@ -61,12 +68,17 @@ Add-AppxPackage -Register $Local:ManifestPath Get-AppxPackage WinGetDevCLI Write-Host "Enabling com tracing." -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "COMBASE" -guid "#bda92ae8-9f11-4d49-ba1d-a4c2abca692e" -flags "7" -f "D:\a\1\s\tools\wpr\traces\COMBASE.etl" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "DCOMSCM" -guid "#9474a749-a98d-4f52-9f45-5b20247e4f01" -flags "7" -f "D:\a\1\s\tools\wpr\traces\DCOMSCM.etl" + +$Local:ComTracePath = Join-Path $Local:TraceOutputDir "COMBASE.etl" +$Local:DComTracePath = Join-Path $Local:TraceOutputDir "DCOMSCM.etl" +Write-Host "Enabling com tracing. $Local:ComTracePath" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "COMBASE" -guid "#bda92ae8-9f11-4d49-ba1d-a4c2abca692e" -flags "7" -f "$Local:ComTracePath" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "DCOMSCM" -guid "#9474a749-a98d-4f52-9f45-5b20247e4f01" -flags "7" -f "$Local:DComTracePath" $Local:AppxRecipePath = Join-Path $BuildRoot "PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe" Write-Host "Running tests: $Local:AppxRecipePath" -& "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" "$Local:AppxRecipePath" "/logger:trx;LogFileName=D:\a\1\s\tools\wpr\traces\comTestRun.trx" +$Local:TRXFilePath = Join-Path $Local:TraceOutputDir "comTestRun.trx" +& "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" "$Local:AppxRecipePath" "/logger:trx;LogFileName=$Local:TRXFilePath" Write-Host "Finished Tests" Write-Host "Ending com trace" & "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "COMBASE" @@ -75,5 +87,7 @@ Write-Host "Ending com trace" & "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "DCOMSCM" Write-Host "Ended com trace" Write-Host "Started com trace again" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "COMBASE" -guid "#bda92ae8-9f11-4d49-ba1d-a4c2abca692e" -flags "7" -f "D:\a\1\s\tools\wpr\traces\COMBASEVS.etl" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "DCOMSCM" -guid "#9474a749-a98d-4f52-9f45-5b20247e4f01" -flags "7" -f "D:\a\1\s\tools\wpr\traces\DCOMSCMVS.etl" +$Local:ComTraceVSPath = Join-Path $Local:TraceOutputDir "COMBASEVS.etl" +$Local:DComTraceVSPath = Join-Path $Local:TraceOutputDir "DCOMSCMVS.etl" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "COMBASE" -guid "#bda92ae8-9f11-4d49-ba1d-a4c2abca692e" -flags "7" -f "$Local:ComTraceVSPath" +& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "DCOMSCM" -guid "#9474a749-a98d-4f52-9f45-5b20247e4f01" -flags "7" -f "$Local:DComTraceVSPath" From 4a226d11accb082cc98f2b1f45c558819c2fa223 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 22 Sep 2021 21:37:11 -0700 Subject: [PATCH 49/53] Make Dll version of com server and use for tests --- src/AppInstallerCLI.sln | 26 +++ ....Management.Deployment.Server.Test.vcxproj | 173 ++++++++++++++++++ ...ent.Deployment.Server.Test.vcxproj.filters | 28 +++ ...soft_Management_Deployment_Server_Test.def | 3 + .../dllmain.cpp | 65 +++++++ src/PackagedTests/Package.appxmanifest | 15 +- src/PackagedTests/PackagedTests.csproj | 5 + 7 files changed, 302 insertions(+), 13 deletions(-) create mode 100644 src/Microsoft.Management.Deployment.Server.Test/Microsoft.Management.Deployment.Server.Test.vcxproj create mode 100644 src/Microsoft.Management.Deployment.Server.Test/Microsoft.Management.Deployment.Server.Test.vcxproj.filters create mode 100644 src/Microsoft.Management.Deployment.Server.Test/Microsoft_Management_Deployment_Server_Test.def create mode 100644 src/Microsoft.Management.Deployment.Server.Test/dllmain.cpp diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index c82a9c06be..6ccd811fb7 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -127,6 +127,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServe EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Server.Test", "Microsoft.Management.Deployment.Server.Test\Microsoft.Management.Deployment.Server.Test.vcxproj", "{7DE2CFC7-5AAE-4F89-BF42-8D231E389687}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ManifestSchema\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4 @@ -556,6 +558,30 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM.ActiveCfg = Debug|ARM + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM.Build.0 = Debug|ARM + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM64.Build.0 = Debug|ARM64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x64.ActiveCfg = Debug|x64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x64.Build.0 = Debug|x64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x86.ActiveCfg = Debug|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x86.Build.0 = Debug|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM.ActiveCfg = Debug|ARM + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM.Build.0 = Debug|ARM + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM64.Build.0 = Debug|ARM64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x64.ActiveCfg = Debug|x64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x64.Build.0 = Debug|x64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x86.Build.0 = Debug|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM.ActiveCfg = Release|ARM + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM.Build.0 = Release|ARM + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM64.ActiveCfg = Release|ARM64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM64.Build.0 = Release|ARM64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x64.ActiveCfg = Release|x64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x64.Build.0 = Release|x64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x86.ActiveCfg = Release|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Microsoft.Management.Deployment.Server.Test/Microsoft.Management.Deployment.Server.Test.vcxproj b/src/Microsoft.Management.Deployment.Server.Test/Microsoft.Management.Deployment.Server.Test.vcxproj new file mode 100644 index 0000000000..c644266b9e --- /dev/null +++ b/src/Microsoft.Management.Deployment.Server.Test/Microsoft.Management.Deployment.Server.Test.vcxproj @@ -0,0 +1,173 @@ + + + + + true + true + true + true + 15.0 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687} + Win32Proj + Microsoft.Management.Deployment.Server.Test + 10.0.18362.0 + 10.0.17763.0 + true + true + Microsoft.Management.Deployment.Server.Test + Microsoft.Management.Deployment.Server.Test + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + DynamicLibrary + v140 + v141 + v142 + Unicode + + + true + true + + + false + true + false + Spectre + + + + + + + + + + + + $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + $(PlatformTarget)\$(Configuration)\ + $(OutDir)..\Microsoft.Management.Deployment;$(OutDir)..\AppInstallerCLICore;$(OutDir)..\JsonCppLib;$(OutDir)..\AppInstallerRepositoryCore;$(OutDir)..\YamlCppLib;$(OutDir)..\AppInstallerCommonCore;$(OutDir)..\cpprestsdk;$(LibraryPath) + true + false + ..\CodeAnalysis.ruleset + + + + NotUsing + pch.h + $(IntDir)pch.pch + WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + Level4 + %(AdditionalOptions) /permissive- /bigobj + true + true + true + $(ProjectDir)..\AppInstallerCLICore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories) + + + Windows + false + Microsoft_Management_Deployment_Server_Test.def + $(OutDir)..\Microsoft.Management.Deployment;$(OutDir)..\AppInstallerCLICore;$(OutDir)..\JsonCppLib;$(OutDir)..\AppInstallerRepositoryCore;$(OutDir)..\YamlCppLib;$(OutDir)..\AppInstallerCommonCore;$(OutDir)..\cpprestsdk;%(AdditionalLibraryDirectories) + Microsoft.Management.Deployment.Server.lib;AppInstallerCLICore.lib;AppInstallerCommonCore.lib;AppInstallerRepositoryCore.lib;JsonCppLib.lib;YamlCppLib.lib;cpprestsdk.lib;wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies) + + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + + + + + WIN32;%(PreprocessorDefinitions) + + + + + MaxSpeed + true + true + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + + + + {5890d6ed-7c3b-40f3-b436-b54f640d9e65} + + + {5eb88068-5fb9-4e69-89b2-72dbc5e068f9} + + + {866c3f06-636f-4be8-bc24-5f86ecc606a1} + + + {82b39fda-e86b-4713-a873-9d56de00247a} + + + {8bb94bb8-374f-4294-bca1-c7811514a6b7} + + + {1cc41a9a-ae66-459d-9210-1e572dd7be69} + + + + + + + + + + + + + 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}. + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment.Server.Test/Microsoft.Management.Deployment.Server.Test.vcxproj.filters b/src/Microsoft.Management.Deployment.Server.Test/Microsoft.Management.Deployment.Server.Test.vcxproj.filters new file mode 100644 index 0000000000..2c3e442cf4 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Server.Test/Microsoft.Management.Deployment.Server.Test.vcxproj.filters @@ -0,0 +1,28 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment.Server.Test/Microsoft_Management_Deployment_Server_Test.def b/src/Microsoft.Management.Deployment.Server.Test/Microsoft_Management_Deployment_Server_Test.def new file mode 100644 index 0000000000..24e7c1235c --- /dev/null +++ b/src/Microsoft.Management.Deployment.Server.Test/Microsoft_Management_Deployment_Server_Test.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/src/Microsoft.Management.Deployment.Server.Test/dllmain.cpp b/src/Microsoft.Management.Deployment.Server.Test/dllmain.cpp new file mode 100644 index 0000000000..fed4f3add3 --- /dev/null +++ b/src/Microsoft.Management.Deployment.Server.Test/dllmain.cpp @@ -0,0 +1,65 @@ +// dllmain.cpp : Defines the entry point for the DLL application. + +#include "winrt/base.h" +#include +#include + +void* __stdcall Microsoft_Management_Deployment_get_activation_factory(std::wstring_view const& name); +bool __stdcall Microsoft_Management_Deployment_can_unload_now(); + +BOOL APIENTRY DllMain( HMODULE, + DWORD ul_reason_for_call, + LPVOID + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +void* __stdcall winrt_get_activation_factory( + std::wstring_view const& name) +{ + return Microsoft_Management_Deployment_get_activation_factory(name); +} + +int32_t __stdcall WINRT_GetActivationFactory(void* classId, void** factory) noexcept try +{ + std::wstring_view const name{ *reinterpret_cast(&classId) }; + *factory = winrt_get_activation_factory(name); + + if (*factory) + { + return 0; +} + +#ifdef _WRL_MODULE_H_ + return ::Microsoft::WRL::Module<::Microsoft::WRL::InProc>::GetModule().GetActivationFactory(static_cast(classId), reinterpret_cast<::IActivationFactory**>(factory)); +#else + return winrt::hresult_class_not_available(name).to_abi(); +#endif +} +catch (...) { return winrt::to_hresult(); } + +bool __stdcall winrt_can_unload_now() noexcept +{ + return Microsoft_Management_Deployment_can_unload_now(); +} + +int32_t __stdcall WINRT_CanUnloadNow() noexcept +{ +#ifdef _WRL_MODULE_H_ + if (!::Microsoft::WRL::Module<::Microsoft::WRL::InProc>::GetModule().Terminate()) + { + return 1; + } +#endif + + return winrt_can_unload_now() ? 0 : 1; +} \ No newline at end of file diff --git a/src/PackagedTests/Package.appxmanifest b/src/PackagedTests/Package.appxmanifest index 1ae0ed5408..1c7ff2ed85 100644 --- a/src/PackagedTests/Package.appxmanifest +++ b/src/PackagedTests/Package.appxmanifest @@ -9,7 +9,7 @@ + Version="1.0.4.0" /> @@ -44,18 +44,7 @@ + - - - - Microsoft.Management.Deployment.dll - - - - - - - - \ No newline at end of file diff --git a/src/PackagedTests/PackagedTests.csproj b/src/PackagedTests/PackagedTests.csproj index dedc9be585..d3ace89322 100644 --- a/src/PackagedTests/PackagedTests.csproj +++ b/src/PackagedTests/PackagedTests.csproj @@ -87,6 +87,10 @@ + + %(RecursiveDir)Microsoft.Management.Deployment.dll + PreserveNewest + @@ -106,6 +110,7 @@ {4bc1f40b-36c2-4bbb-8306-76e490b13bbd} Microsoft.Management.Deployment.Client + False From 67206e1f4a721c77ee7f81fb4270bae53cfd715a Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 23 Sep 2021 11:47:56 -0700 Subject: [PATCH 50/53] Fix library name parameter. --- .../Microsoft.Management.Deployment.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj index d9c12c8f6d..d70b4709da 100644 --- a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj +++ b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj @@ -14,7 +14,7 @@ 10.0 10.0.18362.0 10.0.17763.0 - -lib + -library Microsoft_Management_Deployment From 750e0033d94ba7c3c0cf246646001d085380f4d4 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 23 Sep 2021 16:29:06 -0700 Subject: [PATCH 51/53] Remove com tracing. Fix test. --- azure-pipelines.yml | 16 ---- src/PackagedTests/ComInterfaceUnitTest.cs | 2 +- src/PackagedTests/Run-InstallPackage.ps1 | 93 ---------------------- src/PackagedTests/Run-RemovePackage.ps1 | 14 ---- tools/wpr/ComTrace.wprp | 35 -------- tools/wpr/wpr.config.xml | 11 --- tools/wpr/wpr.exe | Bin 385312 -> 0 bytes 7 files changed, 1 insertion(+), 170 deletions(-) delete mode 100644 src/PackagedTests/Run-InstallPackage.ps1 delete mode 100644 src/PackagedTests/Run-RemovePackage.ps1 delete mode 100644 tools/wpr/ComTrace.wprp delete mode 100644 tools/wpr/wpr.config.xml delete mode 100644 tools/wpr/wpr.exe diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0d340b8bdb..69fd44425a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -308,15 +308,6 @@ jobs: publishLocation: 'Container' condition: succeededOrFailed() - - task: PowerShell@2 - displayName: Install WinGetDev package - inputs: - filePath: 'src\PackagedTests\Run-InstallPackage.ps1' - arguments: '-BuildRoot x86\Release -PackageRoot $(appxPackageDir)\AppInstallerCLIPackage_*_Test' - workingDirectory: 'src' - condition: succeededOrFailed() - -# Run the tests from the x64 package. These tests make cross package com calls to the previously installed WinGetDev package. - task: VSTest@2 displayName: Run Com Interface Tests inputs: @@ -328,13 +319,6 @@ jobs: runSettingsFile: 'src\x86\Release\PackagedTests\Test.runsettings' condition: succeededOrFailed() - - task: PowerShell@2 - displayName: Remove WinGetDev package - inputs: - filePath: 'src\PackagedTests\Run-RemovePackage.ps1' - workingDirectory: 'src' - condition: succeededOrFailed() - - task: PublishBuildArtifacts@1 displayName: Publish Com Trace from Interface tests inputs: diff --git a/src/PackagedTests/ComInterfaceUnitTest.cs b/src/PackagedTests/ComInterfaceUnitTest.cs index 1c62b940c5..e046d06851 100644 --- a/src/PackagedTests/ComInterfaceUnitTest.cs +++ b/src/PackagedTests/ComInterfaceUnitTest.cs @@ -35,7 +35,7 @@ public void OpenPredefinedStoreCatalog() { PackageManager packageManager = new PackageManager(); PackageCatalogReference catalogRef = packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog.MicrosoftStore); - Assert.IsTrue(catalogRef.Info.Name.Equals("storepreview")); + Assert.IsTrue(catalogRef.Info.Name.Equals("msstore")); } } } diff --git a/src/PackagedTests/Run-InstallPackage.ps1 b/src/PackagedTests/Run-InstallPackage.ps1 deleted file mode 100644 index 90bd862004..0000000000 --- a/src/PackagedTests/Run-InstallPackage.ps1 +++ /dev/null @@ -1,93 +0,0 @@ -<# -.SYNOPSIS - Registers the AppInstallerCLI package. -.DESCRIPTION - Registers the loose files generated by the AppInstallerCLIPackage project -.PARAMETER BuildRoot - The root of the build output directory. If not provided, assumed to be the local default - location relative to this script. -.PARAMETER PackageRoot - The root of the package build output directory. If not provided, assumed to be the local default - location relative to this script. -#> -param( - [Parameter(Mandatory=$false)] - [string]$BuildRoot, - - [Parameter(Mandatory=$false)] - [string]$PackageRoot -) -if ([String]::IsNullOrEmpty($BuildRoot)) -{ - $BuildRoot = Split-Path -Parent $PSCommandPath; - $BuildRoot = Join-Path $BuildRoot "..\x64\Debug"; -} -$BuildRoot = Resolve-Path $BuildRoot -Write-Host "Using BuildRoot = $BuildRoot" - -if ([String]::IsNullOrEmpty($PackageRoot)) -{ - $PackageRoot = Split-Path -Parent $PSCommandPath; - $PackageRoot = Join-Path $PackageRoot "..\AppInstallerCLIPackage\bin\x64\Debug"; -} -$PackageRoot = Resolve-Path $PackageRoot -Write-Host "Using PackageRoot = $PackageRoot" - -Get-AppxPackage WinGetDevCLI -Write-Host "Remove registered package" -Get-AppxPackage WinGetDevCLI | Remove-AppxPackage - -$Local:BundlePackageFormat = Join-Path $PackageRoot "AppInstallerCLIPackage*.msixbundle" -$Local:ResolvedPackagePath = Resolve-Path $Local:BundlePackageFormat -$Local:ExtractedBundlePath = Join-Path $PackageRoot "ExtractedBundle" -$Local:BundleCopyPath = Join-Path $PackageRoot "bundle.zip" -Copy-Item -Path $Local:ResolvedPackagePath -Destination $Local:BundleCopyPath -Write-Host "Expanding bundle at: $Local:ResolvedPackagePath" -Expand-Archive -Path $Local:BundleCopyPath -DestinationPath $Local:ExtractedBundlePath - -$Local:MainPackageFormat = Join-Path $Local:ExtractedBundlePath "AppInstallerCLIPackage*x86*.msix" -$Local:ResolvedMainPackagePath = Resolve-Path $Local:MainPackageFormat -$Local:ExtractedMainPath = Join-Path $PackageRoot "ExtractedMain" -$Local:MainCopyPath = Join-Path $PackageRoot "main.zip" -Copy-Item -Path $Local:ResolvedMainPackagePath -Destination $Local:MainCopyPath -$Local:WorkingDirSrc = Get-Location -Write-Host "Dir at: $Local:WorkingDirSrc" -$Local:WorkingDir = Split-Path $Local:WorkingDirSrc -Parent -Write-Host "Dir at: $Local:WorkingDir" -$Local:TraceOutputDir = Join-Path $Local:WorkingDir "tools\wpr\traces" -$Local:MainCopyArtifactPath = Join-Path $Local:TraceOutputDir "main.zip" -New-Item -Force $Local:MainCopyArtifactPath -Copy-Item -Path $Local:ResolvedMainPackagePath -Destination $Local:MainCopyArtifactPath -Write-Host "Expanding package at: $Local:ResolvedMainPackagePath" -Expand-Archive -Path $Local:MainCopyPath -DestinationPath $Local:ExtractedMainPath - -$Local:ManifestPath = Join-Path $ExtractedMainPath "AppxManifest.xml" -Write-Host "Registering manifest at path: $Local:ManifestPath" -Add-AppxPackage -Register $Local:ManifestPath - -Get-AppxPackage WinGetDevCLI - -Write-Host "Enabling com tracing." - -$Local:ComTracePath = Join-Path $Local:TraceOutputDir "COMBASE.etl" -$Local:DComTracePath = Join-Path $Local:TraceOutputDir "DCOMSCM.etl" -Write-Host "Enabling com tracing. $Local:ComTracePath" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "COMBASE" -guid "#bda92ae8-9f11-4d49-ba1d-a4c2abca692e" -flags "7" -f "$Local:ComTracePath" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "DCOMSCM" -guid "#9474a749-a98d-4f52-9f45-5b20247e4f01" -flags "7" -f "$Local:DComTracePath" - -$Local:AppxRecipePath = Join-Path $BuildRoot "PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe" -Write-Host "Running tests: $Local:AppxRecipePath" -$Local:TRXFilePath = Join-Path $Local:TraceOutputDir "comTestRun.trx" -& "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe" "$Local:AppxRecipePath" "/logger:trx;LogFileName=$Local:TRXFilePath" -Write-Host "Finished Tests" -Write-Host "Ending com trace" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "COMBASE" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "DCOMSCM" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "COMBASE" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "DCOMSCM" -Write-Host "Ended com trace" -Write-Host "Started com trace again" -$Local:ComTraceVSPath = Join-Path $Local:TraceOutputDir "COMBASEVS.etl" -$Local:DComTraceVSPath = Join-Path $Local:TraceOutputDir "DCOMSCMVS.etl" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "COMBASE" -guid "#bda92ae8-9f11-4d49-ba1d-a4c2abca692e" -flags "7" -f "$Local:ComTraceVSPath" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -start "DCOMSCM" -guid "#9474a749-a98d-4f52-9f45-5b20247e4f01" -flags "7" -f "$Local:DComTraceVSPath" diff --git a/src/PackagedTests/Run-RemovePackage.ps1 b/src/PackagedTests/Run-RemovePackage.ps1 deleted file mode 100644 index 57a3490e92..0000000000 --- a/src/PackagedTests/Run-RemovePackage.ps1 +++ /dev/null @@ -1,14 +0,0 @@ -<# -.SYNOPSIS - Removes the AppInstallerCLI package. -.DESCRIPTION - Removes the loose files generated by the AppInstallerCLIPackage project -#> - -Write-Host "Ending com trace" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "COMBASE" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -flush "DCOMSCM" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "COMBASE" -& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\tracelog.exe" -stop "DCOMSCM" -Write-Host "Remove registered package" -Get-AppxPackage WinGetDevCLI | Remove-AppxPackage \ No newline at end of file diff --git a/tools/wpr/ComTrace.wprp b/tools/wpr/ComTrace.wprp deleted file mode 100644 index b7f3c9d700..0000000000 --- a/tools/wpr/ComTrace.wprp +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/wpr/wpr.config.xml b/tools/wpr/wpr.config.xml deleted file mode 100644 index 08443dd819..0000000000 --- a/tools/wpr/wpr.config.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/tools/wpr/wpr.exe b/tools/wpr/wpr.exe deleted file mode 100644 index e49b6b307da9ec4a3436a360a194434737dc367b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 385312 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%0Ap-b=sQRyCmugn9R{3YqZ2LD#KA5PR5cpQtb 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%0DdTP}woWk}=`x=1r^2Lj2-0(o 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 From 34bfab9a8c23bced11e8c38bc4e61a02a5362e7a Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Thu, 23 Sep 2021 18:25:13 -0700 Subject: [PATCH 52/53] Fix copyright and spelling. --- .github/actions/spelling/allow.txt | 3 +++ azure-pipelines.yml | 8 -------- .../Client.PackageManager.h | 4 +--- ...icrosoft.Management.Deployment.Client.vcxproj | 3 --- .../PackageManager.cpp | 2 ++ .../dllmain.cpp | 16 +++------------- src/PackagedTests/ComInterfaceUnitTest.cs | 4 +++- 7 files changed, 12 insertions(+), 28 deletions(-) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 997e57e3d7..310938f05b 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -9,6 +9,7 @@ alloc altform anonymize api +APIENTRY appdata appinst appinstaller @@ -107,6 +108,7 @@ DIRECTONLY distro dll dllexport +dllmain docx dotnet downlevel @@ -188,6 +190,7 @@ html http https Hyperlink +IActivation IApplication IAppx IAsync diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 69fd44425a..3034e8d9d0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -319,14 +319,6 @@ jobs: runSettingsFile: 'src\x86\Release\PackagedTests\Test.runsettings' condition: succeededOrFailed() - - task: PublishBuildArtifacts@1 - displayName: Publish Com Trace from Interface tests - inputs: - PathtoPublish: 'tools\wpr\traces' - ArtifactName: 'ComTraceFromInterfaceTest' - publishLocation: 'Container' - condition: succeededOrFailed() - - task: PublishBuildArtifacts@1 displayName: Publish CLI Binary inputs: diff --git a/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h b/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h index 8e588957d4..2fb60f0a39 100644 --- a/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h +++ b/src/Microsoft.Management.Deployment.Client/Client.PackageManager.h @@ -3,13 +3,11 @@ namespace winrt::Microsoft::Management::Deployment::factory_implementation { - const CLSID CLSID_PackageManager2 = { 0x74CB3139, 0xB7C5, 0x4B9E, { 0x93, 0x88, 0xE6, 0x61, 0x6D, 0xEA, 0x28, 0x8C } }; //74CB3139-B7C5-4B9E-9388-E6616DEA288C - struct PackageManager : PackageManagerT { auto ActivateInstance() const { - return winrt::create_instance(CLSID_PackageManager2, CLSCTX_ALL); + return winrt::create_instance(__uuidof(implementation::PackageManager), CLSCTX_ALL); } }; } diff --git a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj index 279b359810..035cf2e6f4 100644 --- a/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj +++ b/src/Microsoft.Management.Deployment.Client/Microsoft.Management.Deployment.Client.vcxproj @@ -153,9 +153,6 @@ - - false - diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp index e70a45d444..84ab4553de 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. #include "pch.h" #pragma warning( push ) #pragma warning ( disable : 4467 6388) diff --git a/src/Microsoft.Management.Deployment.Server.Test/dllmain.cpp b/src/Microsoft.Management.Deployment.Server.Test/dllmain.cpp index fed4f3add3..5ba735d341 100644 --- a/src/Microsoft.Management.Deployment.Server.Test/dllmain.cpp +++ b/src/Microsoft.Management.Deployment.Server.Test/dllmain.cpp @@ -1,4 +1,5 @@ -// dllmain.cpp : Defines the entry point for the DLL application. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. #include "winrt/base.h" #include @@ -37,13 +38,9 @@ int32_t __stdcall WINRT_GetActivationFactory(void* classId, void** factory) noex if (*factory) { return 0; -} + } -#ifdef _WRL_MODULE_H_ - return ::Microsoft::WRL::Module<::Microsoft::WRL::InProc>::GetModule().GetActivationFactory(static_cast(classId), reinterpret_cast<::IActivationFactory**>(factory)); -#else return winrt::hresult_class_not_available(name).to_abi(); -#endif } catch (...) { return winrt::to_hresult(); } @@ -54,12 +51,5 @@ bool __stdcall winrt_can_unload_now() noexcept int32_t __stdcall WINRT_CanUnloadNow() noexcept { -#ifdef _WRL_MODULE_H_ - if (!::Microsoft::WRL::Module<::Microsoft::WRL::InProc>::GetModule().Terminate()) - { - return 1; - } -#endif - return winrt_can_unload_now() ? 0 : 1; } \ No newline at end of file diff --git a/src/PackagedTests/ComInterfaceUnitTest.cs b/src/PackagedTests/ComInterfaceUnitTest.cs index e046d06851..696a3b4927 100644 --- a/src/PackagedTests/ComInterfaceUnitTest.cs +++ b/src/PackagedTests/ComInterfaceUnitTest.cs @@ -1,4 +1,6 @@ - +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Diagnostics; From c67af0e558c00b33ccceb53d57cc791968418ec2 Mon Sep 17 00:00:00 2001 From: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com> Date: Wed, 13 Oct 2021 03:30:00 -0700 Subject: [PATCH 53/53] Try decrease build disk size. --- azure-pipelines.yml | 19 ++++- src/AppInstallerCLI.sln | 172 ++++++++++++++++++++++++++++++++++++---- src/PackagedTests.sln | 69 ---------------- 3 files changed, 172 insertions(+), 88 deletions(-) delete mode 100644 src/PackagedTests.sln diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3034e8d9d0..c68258ed44 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -19,6 +19,8 @@ variables: solution: 'src/AppInstallerCLI.sln' buildPlatform: 'x86|x64' buildConfiguration: 'Release' + testBuildPlatform: 'x86' + testBuildConfiguration: 'TestRelease' appxPackageDir: '$(build.artifactStagingDirectory)\AppxPackages\\' # Do not set the build version for a PR build. @@ -91,13 +93,24 @@ jobs: displayName: Build Solution inputs: platform: 'x86' - solution: 'src\*.sln' + solution: '$(solution)' configuration: '$(buildConfiguration)' msbuildArgs: '/p:AppxBundlePlatforms="$(buildPlatform)" /p:AppxPackageDir="$(appxPackageDir)" /p:AppxBundle=Always /p:UapAppxPackageBuildMode=StoreUpload' + - task: VSBuild@1 + displayName: Build Test Project + inputs: + platform: 'x86' + solution: '$(solution)' + configuration: '$(testBuildConfiguration)' + msbuildArgs: '/p:AppxBundlePlatforms="$(testBuildPlatform)" + /p:AppxPackageDir="$(appxPackageDir)" + /p:AppxBundle=Always + /p:UapAppxPackageBuildMode=StoreUpload' + - task: PowerShell@2 displayName: Install Tests Dependencies inputs: @@ -312,10 +325,10 @@ jobs: displayName: Run Com Interface Tests inputs: testRunTitle: 'Com Interface Tests' - platform: 'x64' + platform: 'x86' testSelector: 'testAssemblies' testAssemblyVer2: | - src\x86\Release\PackagedTests\x64\PackagedTests\PackagedTests.build.appxrecipe + src\x86\Release\PackagedTests\PackagedTests.build.appxrecipe runSettingsFile: 'src\x86\Release\PackagedTests\Test.runsettings' condition: succeededOrFailed() diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index 6ccd811fb7..8f68fa1bc2 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -128,6 +128,14 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Server.Test", "Microsoft.Management.Deployment.Server.Test\Microsoft.Management.Deployment.Server.Test.vcxproj", "{7DE2CFC7-5AAE-4F89-BF42-8D231E389687}" + ProjectSection(ProjectDependencies) = postProject + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D} = {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTests\PackagedTests.csproj", "{8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}" + ProjectSection(ProjectDependencies) = postProject + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687} = {7DE2CFC7-5AAE-4F89-BF42-8D231E389687} + EndProjectSection EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution @@ -163,6 +171,10 @@ Global Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 + TestRelease|ARM = TestRelease|ARM + TestRelease|ARM64 = TestRelease|ARM64 + TestRelease|x64 = TestRelease|x64 + TestRelease|x86 = TestRelease|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.ActiveCfg = Debug|ARM @@ -193,6 +205,10 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.ActiveCfg = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Build.0 = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Deploy.0 = Release|x86 + {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|ARM.ActiveCfg = Release|ARM + {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|x64.ActiveCfg = Release|x64 + {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|x86.ActiveCfg = Release|x86 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.ActiveCfg = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.Build.0 = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -213,6 +229,10 @@ Global {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x64.Build.0 = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.ActiveCfg = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.Build.0 = Release|Win32 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|ARM.ActiveCfg = Release|ARM + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|x64.ActiveCfg = Release|x64 + {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|x86.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.ActiveCfg = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.Build.0 = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -233,6 +253,14 @@ Global {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x64.Build.0 = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.Build.0 = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM.ActiveCfg = Release|ARM + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM.Build.0 = Release|ARM + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM64.Build.0 = Release|ARM64 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x64.ActiveCfg = Release|x64 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x64.Build.0 = Release|x64 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x86.ActiveCfg = Release|Win32 + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x86.Build.0 = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.ActiveCfg = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.Build.0 = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -253,6 +281,14 @@ Global {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x64.Build.0 = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.Build.0 = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM.ActiveCfg = Release|ARM + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM.Build.0 = Release|ARM + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM64.Build.0 = Release|ARM64 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x64.ActiveCfg = Release|x64 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x64.Build.0 = Release|x64 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x86.ActiveCfg = Release|Win32 + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x86.Build.0 = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM64.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.ActiveCfg = Debug|x64 @@ -269,6 +305,10 @@ Global {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.Build.0 = Release|Win32 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|ARM.ActiveCfg = Release|x64 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|ARM64.ActiveCfg = Release|x64 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|x64.ActiveCfg = Release|x64 + {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|x86.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.ActiveCfg = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.Build.0 = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -290,6 +330,14 @@ Global {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x64.Build.0 = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.Build.0 = Release|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM.ActiveCfg = Release|ARM + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM.Build.0 = Release|ARM + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM64.Build.0 = Release|ARM64 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x64.ActiveCfg = Release|x64 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x64.Build.0 = Release|x64 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x86.ActiveCfg = Release|Win32 + {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x86.Build.0 = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.ActiveCfg = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.Build.0 = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -311,6 +359,14 @@ Global {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x64.Build.0 = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.Build.0 = Release|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM.ActiveCfg = Release|ARM + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM.Build.0 = Release|ARM + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM64.Build.0 = Release|ARM64 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x64.ActiveCfg = Release|x64 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x64.Build.0 = Release|x64 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x86.ActiveCfg = Release|Win32 + {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x86.Build.0 = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.ActiveCfg = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.Build.0 = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -331,6 +387,10 @@ Global {FB313532-38B0-4676-9303-AB200AA13576}.Release|x64.Build.0 = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.ActiveCfg = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.Build.0 = Release|Win32 + {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|ARM.ActiveCfg = Release|ARM + {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|x64.ActiveCfg = Release|x64 + {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|x86.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.ActiveCfg = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.Build.0 = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -351,6 +411,10 @@ Global {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x64.Build.0 = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.Build.0 = Release|Win32 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|ARM.ActiveCfg = Release|ARM + {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|x64.ActiveCfg = Release|x64 + {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|x86.ActiveCfg = Release|Win32 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM64.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.ActiveCfg = Debug|x64 @@ -367,6 +431,10 @@ Global {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.Build.0 = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.Build.0 = Release|x86 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|ARM.ActiveCfg = TestOnly|x64 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|ARM64.ActiveCfg = TestOnly|x64 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|x64.ActiveCfg = Release|x64 + {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|x86.ActiveCfg = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.ActiveCfg = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Build.0 = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Deploy.0 = Debug|ARM @@ -395,6 +463,10 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.ActiveCfg = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Build.0 = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Deploy.0 = Release|x86 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|ARM.ActiveCfg = Release|ARM + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|x64.ActiveCfg = Release|x64 + {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|x86.ActiveCfg = Release|x86 {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x64.ActiveCfg = Debug @@ -407,6 +479,10 @@ Global {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x86.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|ARM.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|ARM64.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|x64.ActiveCfg = Release + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|x86.ActiveCfg = Release {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM64.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.ActiveCfg = Debug|x64 @@ -423,6 +499,10 @@ Global {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.Build.0 = Release|x86 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|ARM.ActiveCfg = Release|x64 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|ARM64.ActiveCfg = Release|x64 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|x64.ActiveCfg = Release|x64 + {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|x86.ActiveCfg = Release|x86 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.ActiveCfg = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.Build.0 = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -444,6 +524,14 @@ Global {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x64.Build.0 = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.Build.0 = Release|Win32 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM.ActiveCfg = Release|ARM + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM.Build.0 = Release|ARM + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM64.Build.0 = Release|ARM64 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x64.ActiveCfg = Release|x64 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x64.Build.0 = Release|x64 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x86.ActiveCfg = Release|Win32 + {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x86.Build.0 = Release|Win32 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.ActiveCfg = Debug|x64 @@ -458,6 +546,10 @@ Global {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x86.ActiveCfg = Fuzzing|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|ARM.ActiveCfg = Debug|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|ARM64.ActiveCfg = Debug|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|x64.ActiveCfg = Debug|x64 + {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|x86.ActiveCfg = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM64.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.ActiveCfg = Debug|x64 @@ -474,6 +566,10 @@ Global {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.Build.0 = Release|x86 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|ARM.ActiveCfg = Release|x64 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|ARM64.ActiveCfg = Release|x64 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|x64.ActiveCfg = Release|x64 + {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|x86.ActiveCfg = Release|x86 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.ActiveCfg = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.Build.0 = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -494,6 +590,14 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x64.Build.0 = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.Build.0 = Release|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM.ActiveCfg = Release|ARM + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM.Build.0 = Release|ARM + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM64.Build.0 = Release|ARM64 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x64.ActiveCfg = Release|x64 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x64.Build.0 = Release|x64 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x86.ActiveCfg = Release|Win32 + {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x86.Build.0 = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.ActiveCfg = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.Build.0 = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -514,6 +618,14 @@ Global {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.Build.0 = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.Build.0 = Release|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM.ActiveCfg = Release|ARM + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM.Build.0 = Release|ARM + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM64.Build.0 = Release|ARM64 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x64.ActiveCfg = Release|x64 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x64.Build.0 = Release|x64 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x86.ActiveCfg = Release|Win32 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x86.Build.0 = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.ActiveCfg = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.Build.0 = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -534,6 +646,10 @@ Global {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.Build.0 = Release|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.ActiveCfg = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.Build.0 = Release|Win32 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|ARM.ActiveCfg = Release|ARM + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|x64.ActiveCfg = Release|x64 + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.ActiveCfg = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.Build.0 = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -543,13 +659,9 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.ActiveCfg = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.Build.0 = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM.ActiveCfg = Debug|ARM - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM.Build.0 = Debug|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|ARM64.Build.0 = Debug|ARM64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x64.ActiveCfg = Debug|x64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x64.Build.0 = Debug|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Fuzzing|x86.Build.0 = Debug|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.ActiveCfg = Release|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.Build.0 = Release|ARM {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.ActiveCfg = Release|ARM64 @@ -558,30 +670,58 @@ Global {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|ARM.ActiveCfg = Release|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|ARM.Build.0 = Release|ARM + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|ARM64.Build.0 = Release|ARM64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|x64.ActiveCfg = Release|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|x64.Build.0 = Release|x64 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|x86.ActiveCfg = Release|Win32 + {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.TestRelease|x86.Build.0 = Release|Win32 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM.ActiveCfg = Debug|ARM - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM.Build.0 = Debug|ARM {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|ARM64.Build.0 = Debug|ARM64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x64.ActiveCfg = Debug|x64 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x64.Build.0 = Debug|x64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x86.ActiveCfg = Debug|Win32 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Debug|x86.Build.0 = Debug|Win32 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM.ActiveCfg = Debug|ARM - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM.Build.0 = Debug|ARM {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|ARM64.Build.0 = Debug|ARM64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x64.ActiveCfg = Debug|x64 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x64.Build.0 = Debug|x64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Fuzzing|x86.Build.0 = Debug|Win32 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM.ActiveCfg = Release|ARM - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM.Build.0 = Release|ARM {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM64.ActiveCfg = Release|ARM64 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|ARM64.Build.0 = Release|ARM64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x64.ActiveCfg = Release|x64 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x64.Build.0 = Release|x64 {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x86.ActiveCfg = Release|Win32 - {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.Release|x86.Build.0 = Release|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|ARM.ActiveCfg = Release|ARM + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|ARM.Build.0 = Release|ARM + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|ARM64.Build.0 = Release|ARM64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|x64.ActiveCfg = Release|x64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|x64.Build.0 = Release|x64 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|x86.ActiveCfg = Release|Win32 + {7DE2CFC7-5AAE-4F89-BF42-8D231E389687}.TestRelease|x86.Build.0 = Release|Win32 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.ActiveCfg = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.ActiveCfg = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM.ActiveCfg = Debug|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x64.ActiveCfg = Debug|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Fuzzing|x86.ActiveCfg = Debug|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.ActiveCfg = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.ActiveCfg = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.ActiveCfg = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.ActiveCfg = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM.ActiveCfg = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM.Build.0 = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM.Deploy.0 = Release|ARM + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM64.Build.0 = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|ARM64.Deploy.0 = Release|ARM64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x64.ActiveCfg = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x64.Build.0 = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x64.Deploy.0 = Release|x64 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x86.ActiveCfg = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x86.Build.0 = Release|x86 + {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.TestRelease|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/PackagedTests.sln b/src/PackagedTests.sln deleted file mode 100644 index 42e13aa9e3..0000000000 --- a/src/PackagedTests.sln +++ /dev/null @@ -1,69 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31424.327 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackagedTests", "PackagedTests\PackagedTests.csproj", "{8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.Client", "Microsoft.Management.Deployment.Client\Microsoft.Management.Deployment.Client.vcxproj", "{4BC1F40B-36C2-4BBB-8306-76E490B13BBD}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|ARM64 = Debug|ARM64 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|ARM = Release|ARM - Release|ARM64 = Release|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.ActiveCfg = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Build.0 = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM.Deploy.0 = Debug|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.Build.0 = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.ActiveCfg = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.Build.0 = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x64.Deploy.0 = Debug|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.ActiveCfg = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Build.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Debug|x86.Deploy.0 = Debug|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.ActiveCfg = Release|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Build.0 = Release|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM.Deploy.0 = Release|ARM - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.ActiveCfg = Release|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.Build.0 = Release|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|ARM64.Deploy.0 = Release|ARM64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.ActiveCfg = Release|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.Build.0 = Release|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x64.Deploy.0 = Release|x64 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.ActiveCfg = Release|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.Build.0 = Release|x86 - {8A4A39C8-E0EF-42B4-B8D9-A73E1209A568}.Release|x86.Deploy.0 = Release|x86 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.ActiveCfg = Debug|ARM - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM.Build.0 = Debug|ARM - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|ARM64.Build.0 = Debug|ARM64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x64.ActiveCfg = Debug|x64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x64.Build.0 = Debug|x64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.ActiveCfg = Debug|Win32 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Debug|x86.Build.0 = Debug|Win32 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.ActiveCfg = Release|ARM - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM.Build.0 = Release|ARM - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.ActiveCfg = Release|ARM64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|ARM64.Build.0 = Release|ARM64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.ActiveCfg = Release|x64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x64.Build.0 = Release|x64 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.ActiveCfg = Release|Win32 - {4BC1F40B-36C2-4BBB-8306-76E490B13BBD}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {00EA47F7-6564-49A1-8CE7-E44A81373CC8} - EndGlobalSection -EndGlobal