winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 5d6b04b557d8485bcbe2a2accaac933d347f820f
parent 3d605e028ada109d3c684a8550a3fde76d166a17
Author: sreadingMSFT <74242768+sreadingMSFT@users.noreply.github.com>
Date:   Tue, 15 Jun 2021 11:21:57 -0700

Add support for callers using programmatic, non command line interface #888 (#984)

* Prototype of exposing winget to out of proc UWP apps.

Create com exe for wrapping a winrt interface with proof of concept call to winget.

* Com server changes

Support all architectures, progress callbacks.

* Update com api proposal

* Update samples.

* Update API to match review and fix build issues

* Update for draft api.

API definitions and partial hookup.

* Implement more of the api surface

Most of the sample code now implemented.

* Update with more api implementations.

* Fix project settings.

* More api implementations and fake vector class.

* Switch to new lifetime management for oop

* Lifetime management fixes.

* Add log parameter.

* Remove manual winmd post build generation.

* API updates

* Merge changes from main branch.

* API updates

* API updates and implementation

* Add support for callers using programmatic, non command line interface #888 (#9)

* Prototype of exposing winget to out of proc UWP apps.

Create com exe for wrapping a winrt interface with proof of concept call to winget.

* Com server changes

Support all architectures, progress callbacks.

* Update com api proposal

* Update samples.

* Update API to match review and fix build issues

* Update for draft api.

API definitions and partial hookup.

* Implement more of the api surface

Most of the sample code now implemented.

* Update with more api implementations.

* Fix project settings.

* More api implementations and fake vector class.

* Switch to new lifetime management for oop

* Lifetime management fixes.

* Add log parameter.

* Remove manual winmd post build generation.

* API updates

* Merge changes from main branch.

* API updates

* API updates and implementation

* Switch from Id to Name due to rest sources

* Copyright and project updates.

* Update project name.

* Add composite changes.

* Revert refactor due to locking issue.

* Move folder again, pr comment updates

* FIx comment.

* Remove GetSourceByIdentifier

* Match target versions on new projects to existing

* Fix percentage calculation.

* Add experimental feature.

* Fix signed\unsigned warning and progress values.

* Fix comments & CompositeSearch::AvailablePackages

* fix comment.

* Update cppwinrt again

* Remove unintended packaging change

* Remove pch to try to reduce disk usage in build

* Enable WPM Client Telemetry for COM Calls and Update Projects settings for succsesful inclusion in DesktopAppInstaller solution

* Add error mapping.

* Idl changes and error catching.

* Try using PackageES for build for disk space

* Rename the experimental feature.

* Revert pipeline test.

* Drop ARM from builds

* Use details to open source instead of name

* Fix source list updatetime metadata saving

Co-authored-by: Santosh Chintalapati <sachinta@ntdev.microsoft.com>
Co-authored-by: JohnMcPMS <johnmcp@microsoft.com>
Diffstat:
M.github/actions/spelling/allow.txt | 3+++
M.github/actions/spelling/expect.txt | 26++++++++++++++++++++++++++
Mazure-pipelines.yml | 2+-
Mdoc/Settings.md | 10++++++++++
Msrc/AppInstallerCLI.sln | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/AppInstallerCLI/AppInstallerCLI.vcxproj | 8++++----
Msrc/AppInstallerCLI/packages.config | 2+-
Msrc/AppInstallerCLICore/AppInstallerCLICore.vcxproj | 12++++++------
Msrc/AppInstallerCLICore/packages.config | 4++--
Msrc/AppInstallerCLIE2ETests/BaseCommand.cs | 1+
Msrc/AppInstallerCLIE2ETests/FeaturesCommand.cs | 1+
Msrc/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj | 18++++++++++++++++++
Msrc/AppInstallerCLIPackage/Package.appxmanifest | 103++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/AppInstallerCLITests/AppInstallerCLITests.vcxproj | 12++++++------
Msrc/AppInstallerCLITests/packages.config | 4++--
Msrc/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj | 12++++++------
Msrc/AppInstallerCommonCore/ExperimentalFeature.cpp | 4++++
Msrc/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h | 1+
Msrc/AppInstallerCommonCore/Public/winget/UserSettings.h | 2++
Msrc/AppInstallerCommonCore/UserSettings.cpp | 1+
Msrc/AppInstallerCommonCore/packages.config | 4++--
Msrc/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj | 12++++++------
Msrc/AppInstallerRepositoryCore/CompositeSource.cpp | 129+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/AppInstallerRepositoryCore/Public/AppInstallerRepositorySource.h | 22++++++++++++++++++++++
Msrc/AppInstallerRepositoryCore/RepositorySource.cpp | 95++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/AppInstallerRepositoryCore/packages.config | 4++--
Asrc/Microsoft.Management.Deployment/CatalogPackage.cpp | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/CatalogPackage.h | 33+++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/ConnectResult.cpp | 22++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/ConnectResult.h | 19+++++++++++++++++++
Asrc/Microsoft.Management.Deployment/Converters.cpp | 270+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/Converters.h | 18++++++++++++++++++
Asrc/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.cpp | 33+++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.h | 26++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/FindPackagesOptions.cpp | 37+++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/FindPackagesOptions.h | 29+++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/FindPackagesResult.cpp | 31+++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/FindPackagesResult.h | 26++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/Helpers.h | 7+++++++
Asrc/Microsoft.Management.Deployment/InstallOptions.cpp | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/InstallOptions.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/InstallResult.cpp | 37+++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/InstallResult.h | 27+++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/MatchResult.cpp | 27+++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/MatchResult.h | 19+++++++++++++++++++
Asrc/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj | 194+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/Microsoft_Management_Deployment.def | 3+++
Asrc/Microsoft.Management.Deployment/PackageCatalog.cpp | 175+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageCatalog.h | 26++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageCatalogInfo.cpp | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageCatalogInfo.h | 24++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageCatalogReference.cpp | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageCatalogReference.h | 23+++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageManager.cpp | 318+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageManager.h | 29+++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageManager.idl | 536+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageMatchFilter.cpp | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageMatchFilter.h | 31+++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageVersionId.cpp | 27+++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageVersionId.h | 19+++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageVersionInfo.cpp | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PackageVersionInfo.h | 27+++++++++++++++++++++++++++
Asrc/Microsoft.Management.Deployment/PropertySheet.props | 17+++++++++++++++++
Asrc/Microsoft.Management.Deployment/packages.config | 6++++++
Asrc/Microsoft.Management.Deployment/pch.cpp | 3+++
Asrc/Microsoft.Management.Deployment/pch.h | 6++++++
Asrc/WinGetServer/PropertySheet.props | 17+++++++++++++++++
Asrc/WinGetServer/WinGetServer.exe.manifest | 4++++
Asrc/WinGetServer/WinGetServer.rc | 0
Asrc/WinGetServer/WinGetServer.vcxproj | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetServer/WinGetServer.vcxproj.filters | 40++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetServer/WinMain.cpp | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WinGetServer/packages.config | 6++++++
Asrc/WinGetServer/resource.h | 15+++++++++++++++
Msrc/WinGetUtil/WinGetUtil.vcxproj | 12++++++------
Msrc/WinGetUtil/packages.config | 4++--
76 files changed, 3424 insertions(+), 156 deletions(-)

diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt @@ -330,6 +330,7 @@ PVOID pwa QCol RAII +rclsid rdbuf README READONLY @@ -337,6 +338,7 @@ READWRITE realloc REALTIME Redistributable +REFCLSID regex regexp removemanifest @@ -459,6 +461,7 @@ tt ttl typedef typename +UAC uap UBool UBreak diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt @@ -1,4 +1,5 @@ abcd +abifind adml admx affle @@ -11,6 +12,7 @@ amrutha anonymized APARTMENTTHREADED apfn +apicontract apiset appinstallertest appname @@ -19,8 +21,10 @@ argumentlist ARMNT arp arphelper +asm ASwitch Atest +ATL AType AUrl Aysnc @@ -60,14 +64,18 @@ CLIE cloudapp CLSID COINIT +combaseapi +COMGLB commandline compschema Concat contosa contosainstaller contoso +contractversion count'th countryregion +cppwinrtprocess createmanifestmetadata cstdint ctc @@ -127,12 +135,18 @@ hlocal hre HRESULTs htm +IApp IAttachment IConfiguration +idl idx +IFind +IGet +IGlobal IHelp IHost IID +iinstall IInstalled img IName @@ -185,12 +199,14 @@ MBH megamorf memcpy middleware +MIDL minexample minschema MMmmbbbb monicka MPNS msdownload +msdn MSFT msftrubengu MSIHASH @@ -211,10 +227,12 @@ normer nsis nuffing nullopt +NX objbase ofile oss Packagedx +Packageend pathparts pathpaths PCs @@ -228,6 +246,7 @@ PMS positionals powertoys productcode +pseudocode pvk pvm pwabuilder @@ -250,6 +269,7 @@ rosoft rowids RRF rrr +runtimeclass rzkzqaqjwj SARL schematab @@ -283,6 +303,8 @@ superstring suppy SUSE swervy +SYD +SYG sysrefcomp Tagit temppath @@ -305,6 +327,7 @@ uninstallation uninstaller uninstallprevious uninstalls +unknwn unparsable UNSCOPED UParse @@ -316,6 +339,7 @@ userfilesetting userprofile USHORT Utils +uuid UWP vamus VERSI @@ -341,7 +365,9 @@ WSL wsv wto Wunused +wwinmain WZDNCRFJ +Xaml XPLATSTR xsi zy diff --git a/azure-pipelines.yml b/azure-pipelines.yml @@ -17,7 +17,7 @@ pool: variables: solution: 'src/AppInstallerCLI.sln' - buildPlatform: 'x86|x64|ARM' + buildPlatform: 'x86|x64' buildConfiguration: 'Release' appxPackageDir: '$(build.artifactStagingDirectory)\AppxPackages\\' diff --git a/doc/Settings.md b/doc/Settings.md @@ -133,3 +133,13 @@ Microsoft Store App support in WinGet is currently implemented as an experimenta "experimentalMSStore": true }, ``` + +### packagedAPI + +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. + +```json + "experimentalFeatures": { + "packagedAPI": true + }, +``` diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln @@ -3,6 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 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 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppInstallerCLI", "AppInstallerCLI\AppInstallerCLI.vcxproj", "{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}" EndProject @@ -105,6 +108,21 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution CodeAnalysis.ruleset = CodeAnalysis.ruleset EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment", "Microsoft.Management.Deployment\Microsoft.Management.Deployment.vcxproj", "{1CC41A9A-AE66-459D-9210-1E572DD7BE69}" + ProjectSection(ProjectDependencies) = postProject + {866C3F06-636F-4BE8-BC24-5F86ECC606A1} = {866C3F06-636F-4BE8-BC24-5F86ECC606A1} + {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D} = {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D} + {5EB88068-5FB9-4E69-89B2-72DBC5E068F9} = {5EB88068-5FB9-4E69-89B2-72DBC5E068F9} + {8BB94BB8-374F-4294-BCA1-C7811514A6B7} = {8BB94BB8-374F-4294-BCA1-C7811514A6B7} + {82B39FDA-E86B-4713-A873-9D56DE00247A} = {82B39FDA-E86B-4713-A873-9D56DE00247A} + {5890D6ED-7C3B-40F3-B436-B54F640D9E65} = {5890D6ED-7C3B-40F3-B436-B54F640D9E65} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServer\WinGetServer.vcxproj", "{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}" + ProjectSection(ProjectDependencies) = postProject + {1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69} + EndProjectSection +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ManifestSchema\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4 @@ -470,6 +488,54 @@ 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|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 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.Build.0 = Debug|ARM64 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x64.ActiveCfg = Debug|x64 + {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|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 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.Build.0 = Release|ARM64 + {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.ActiveCfg = Release|x64 + {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|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}.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 + {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/AppInstallerCLI/AppInstallerCLI.vcxproj b/src/AppInstallerCLI/AppInstallerCLI.vcxproj @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" /> <PropertyGroup Label="Globals"> <CppWinRTOptimized>true</CppWinRTOptimized> <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge> @@ -291,13 +291,13 @@ </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> </ImportGroup> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets'))" /> </Target> </Project> \ No newline at end of file diff --git a/src/AppInstallerCLI/packages.config b/src/AppInstallerCLI/packages.config @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" /> + <package id="Microsoft.Windows.CppWinRT" version="2.0.210505.3" targetFramework="native" /> </packages> \ No newline at end of file diff --git a/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj b/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" /> <PropertyGroup Label="Globals"> <CppWinRTOptimized>true</CppWinRTOptimized> <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge> @@ -334,15 +334,15 @@ </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" /> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> </ImportGroup> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets'))" /> </Target> </Project> \ No newline at end of file diff --git a/src/AppInstallerCLICore/packages.config b/src/AppInstallerCLICore/packages.config @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" /> - <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200519.2" targetFramework="native" /> + <package id="Microsoft.Windows.CppWinRT" version="2.0.210505.3" targetFramework="native" /> + <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" /> </packages> \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/BaseCommand.cs b/src/AppInstallerCLIE2ETests/BaseCommand.cs @@ -61,6 +61,7 @@ namespace AppInstallerCLIE2ETests list = status, upgrade = status, uninstall = status, + packagedAPI = status, } }; diff --git a/src/AppInstallerCLIE2ETests/FeaturesCommand.cs b/src/AppInstallerCLIE2ETests/FeaturesCommand.cs @@ -38,6 +38,7 @@ namespace AppInstallerCLIE2ETests 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/AppInstallerCLIPackage.wapproj b/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj @@ -140,6 +140,7 @@ </ItemGroup> <ItemGroup> <ProjectReference Include="..\AppInstallerCLI\AppInstallerCLI.vcxproj" /> + <ProjectReference Include="..\WinGetServer\WinGetServer.vcxproj" /> </ItemGroup> <Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" /> <PropertyGroup Label="Configuration"> @@ -148,4 +149,21 @@ copy "$(TargetDir)\resources.pri" "$(TargetDir)\AppInstallerCLI\resources.pri" </PostBuildEvent> </PropertyGroup> + <Target Name="IncludeWinMdInPackage" AfterTargets="_ComputeAppxPackagePayload"> + <PropertyGroup> + <MicrosoftManagementDeploymentPath>$(OutputPath)\..\Microsoft.Management.Deployment\Microsoft.Management.Deployment.winmd</MicrosoftManagementDeploymentPath> + <MicrosoftManagementDeploymentPath Condition="!Exists('$(MicrosoftManagementDeploymentPath)')">$(TargetDir)..\..\..\..\$(PlatformTarget)\$(Configuration)\Microsoft.Management.Deployment\Microsoft.Management.Deployment.winmd</MicrosoftManagementDeploymentPath> + <MicrosoftManagementDeploymentFileName>Microsoft.Management.Deployment.winmd</MicrosoftManagementDeploymentFileName> + </PropertyGroup> + <ItemGroup> + <MicrosoftManagementDeploymentWinmd Include="$(MicrosoftManagementDeploymentPath)" /> + </ItemGroup> + <Error Condition="!Exists('$(MicrosoftManagementDeploymentPath)')" Text="$(MicrosoftManagementDeploymentPath) was not found" /> + <Message Importance="normal" Condition="Exists('$(MicrosoftManagementDeploymentPath)')" Text="$(MicrosoftManagementDeploymentPath) -&gt; $(MicrosoftManagementDeploymentFileName)" /> + <ItemGroup> + <AppxPackagePayload Include="@(MicrosoftManagementDeploymentWinmd)" KeepDuplicates="false"> + <TargetPath>$(MicrosoftManagementDeploymentFileName)</TargetPath> + </AppxPackagePayload> + </ItemGroup> + </Target> </Project> \ No newline at end of file diff --git a/src/AppInstallerCLIPackage/Package.appxmanifest b/src/AppInstallerCLIPackage/Package.appxmanifest @@ -1,44 +1,61 @@ -<?xml version="1.0" encoding="utf-8"?> -<Package - xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" - xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" - xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" - xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" - xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" - IgnorableNamespaces="uap uap3 uap5 rescap"> - <Identity Name="WinGetDevCLI" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="0.0.2.0" /> - <Properties> - <DisplayName>WinGet Dev CLI</DisplayName> - <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName> - <Logo>Images\StoreLogo.png</Logo> - </Properties> - <Dependencies> - <!-- Minimum supported version is 1809 (October 2018 Update, aka RS5) --> - <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19033.0" /> - <PackageDependency Name="Microsoft.VCLibs.140.00.UWPDesktop" MinVersion="14.0.25426.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" /> - </Dependencies> - <Resources> - <Resource Language="x-generate" /> - </Resources> - <Applications> - <Application Id="WinGetDev" Executable="AppInstallerCLI\AppInstallerCLI.exe" EntryPoint="Windows.FullTrustApplication"> - <uap:VisualElements DisplayName="WinGet Dev Client" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png" Description="The WinGet dev client." BackgroundColor="#0078d7" AppListEntry="none" /> - <Extensions> - <uap3:Extension Category="windows.appExtensionHost"> - <uap3:AppExtensionHost> - <uap3:Name>com.microsoft.winget.source</uap3:Name> - </uap3:AppExtensionHost> - </uap3:Extension> - <uap5:Extension Category="windows.appExecutionAlias"> - <uap5:AppExecutionAlias> - <uap5:ExecutionAlias Alias="WinGetDev.exe" /> - </uap5:AppExecutionAlias> - </uap5:Extension> - </Extensions> - </Application> - </Applications> - <Capabilities> - <rescap:Capability Name="runFullTrust" /> - <rescap:Capability Name="packageManagement" /> - </Capabilities> +<?xml version="1.0" encoding="utf-8"?> +<Package + xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" + xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" + xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" + xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" + xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" + xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" + IgnorableNamespaces="uap uap3 uap5 rescap"> + <Identity Name="WinGetDevCLI" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="0.0.2.0" /> + <Properties> + <DisplayName>WinGet Dev CLI</DisplayName> + <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName> + <Logo>Images\StoreLogo.png</Logo> + </Properties> + <Dependencies> + <!-- Minimum supported version is 1809 (October 2018 Update, aka RS5) --> + <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19033.0" /> + <PackageDependency Name="Microsoft.VCLibs.140.00.UWPDesktop" MinVersion="14.0.25426.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" /> + </Dependencies> + <Resources> + <Resource Language="x-generate" /> + </Resources> + <Applications> + <Application Id="WinGetDev" Executable="AppInstallerCLI\AppInstallerCLI.exe" EntryPoint="Windows.FullTrustApplication"> + <uap:VisualElements DisplayName="WinGet Dev Client" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png" Description="The WinGet dev client." BackgroundColor="#0078d7" AppListEntry="none" /> + <Extensions> + <uap3:Extension Category="windows.appExtensionHost"> + <uap3:AppExtensionHost> + <uap3:Name>com.microsoft.winget.source</uap3:Name> + </uap3:AppExtensionHost> + </uap3:Extension> + <uap5:Extension Category="windows.appExecutionAlias"> + <uap5:AppExecutionAlias> + <uap5:ExecutionAlias Alias="WinGetDev.exe" /> + </uap5:AppExecutionAlias> + </uap5:Extension> + <com:Extension Category="windows.comServer"> + <com:ComServer> + <com:ExeServer Executable="WinGetServer\WindowsPackageManagerServer.exe" DisplayName="Windows Package Manager Server" LaunchAndActivationPermission="O:SYG:SYD:(A;;11;;;WD)(A;;11;;;RC)(A;;11;;;AC)(A;;11;;;AN)S:P(ML;;NX;;;S-1-16-0)"> + <com:Class Id ="E65C7D5A-95AF-4A98-BE5F-A793029CEB56" DisplayName="PackageManager Server"> + </com:Class> + <com:Class Id ="2CAD6C15-DF8E-49DD-A748-96ADE0FE31B7" DisplayName="FindPackagesOptions Server"> + </com:Class> + <com:Class Id ="6444B10D-FE84-430F-932B-3D4FE5195BDF" DisplayName="CreateCompositePackageCatalogOptions Server"> + </com:Class> + <com:Class Id ="05F7019A-8FAC-4422-BCD5-4CB34FFB44A8" DisplayName="InstallOptions Server"> + </com:Class> + <com:Class Id ="ADBF3B4A-DB8A-496C-A579-62B58F5FB13F" DisplayName="PackageMatchFilter Server"> + </com:Class> + </com:ExeServer> + </com:ComServer> + </com:Extension> + </Extensions> + </Application> + </Applications> + <Capabilities> + <rescap:Capability Name="runFullTrust" /> + <rescap:Capability Name="packageManagement" /> + </Capabilities> </Package> \ No newline at end of file diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" /> <PropertyGroup Label="Globals"> <CppWinRTOptimized>true</CppWinRTOptimized> <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge> @@ -534,15 +534,15 @@ </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" /> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> </ImportGroup> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets'))" /> </Target> </Project> \ No newline at end of file diff --git a/src/AppInstallerCLITests/packages.config b/src/AppInstallerCLITests/packages.config @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" /> - <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200519.2" targetFramework="native" /> + <package id="Microsoft.Windows.CppWinRT" version="2.0.210505.3" targetFramework="native" /> + <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" /> </packages> \ No newline at end of file diff --git a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="'$(Configuration)'!='Fuzzing' And Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" /> <PropertyGroup Label="Globals"> <CppWinRTOptimized>true</CppWinRTOptimized> <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge> @@ -373,15 +373,15 @@ </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="'$(Configuration)'!='Fuzzing' And Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" /> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> </ImportGroup> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets'))" /> </Target> </Project> \ No newline at end of file diff --git a/src/AppInstallerCommonCore/ExperimentalFeature.cpp b/src/AppInstallerCommonCore/ExperimentalFeature.cpp @@ -44,6 +44,8 @@ namespace AppInstaller::Settings return userSettings.Get<Setting::EFExperimentalArg>(); case ExperimentalFeature::Feature::ExperimentalMSStore: return userSettings.Get<Setting::EFExperimentalMSStore>(); + case ExperimentalFeature::Feature::PackagedAPI: + return userSettings.Get<Setting::EFPackagedAPI>(); default: THROW_HR(E_UNEXPECTED); } @@ -72,6 +74,8 @@ 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 }; default: THROW_HR(E_UNEXPECTED); } diff --git a/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h b/src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h @@ -21,6 +21,7 @@ namespace AppInstaller::Settings { None = 0x0, ExperimentalMSStore = 0x1, + PackagedAPI = 0x2, 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/UserSettings.h b/src/AppInstallerCommonCore/Public/winget/UserSettings.h @@ -75,6 +75,7 @@ namespace AppInstaller::Settings NetworkDOProgressTimeoutInSeconds, InstallLocalePreference, InstallLocaleRequirement, + EFPackagedAPI, Max }; @@ -120,6 +121,7 @@ namespace AppInstaller::Settings SETTINGMAPPING_SPECIALIZATION(Setting::NetworkDOProgressTimeoutInSeconds, uint32_t, std::chrono::seconds, 60s, ".network.doProgressTimeoutInSeconds"sv); SETTINGMAPPING_SPECIALIZATION(Setting::InstallLocalePreference, std::vector<std::string>, std::vector<std::string>, {}, ".installBehavior.preferences.locale"sv); SETTINGMAPPING_SPECIALIZATION(Setting::InstallLocaleRequirement, std::vector<std::string>, std::vector<std::string>, {}, ".installBehavior.requirements.locale"sv); + SETTINGMAPPING_SPECIALIZATION(Setting::EFPackagedAPI, bool, bool, false, ".experimentalFeatures.packagedAPI"sv); // Used to deduce the SettingVariant type; making a variant that includes std::monostate and all SettingMapping types. template <size_t... I> diff --git a/src/AppInstallerCommonCore/UserSettings.cpp b/src/AppInstallerCommonCore/UserSettings.cpp @@ -226,6 +226,7 @@ namespace AppInstaller::Settings WINGET_VALIDATE_PASS_THROUGH(EFExperimentalArg) WINGET_VALIDATE_PASS_THROUGH(EFExperimentalMSStore) WINGET_VALIDATE_PASS_THROUGH(TelemetryDisable) + WINGET_VALIDATE_PASS_THROUGH(EFPackagedAPI) WINGET_VALIDATE_SIGNATURE(InstallScopePreference) { diff --git a/src/AppInstallerCommonCore/packages.config b/src/AppInstallerCommonCore/packages.config @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" /> - <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200519.2" targetFramework="native" /> + <package id="Microsoft.Windows.CppWinRT" version="2.0.210505.3" targetFramework="native" /> + <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" /> </packages> \ No newline at end of file diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" /> <PropertyGroup Label="Globals"> <CppWinRTOptimized>true</CppWinRTOptimized> <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge> @@ -337,15 +337,15 @@ </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" /> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> </ImportGroup> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets'))" /> </Target> </Project> \ No newline at end of file diff --git a/src/AppInstallerRepositoryCore/CompositeSource.cpp b/src/AppInstallerRepositoryCore/CompositeSource.cpp @@ -436,92 +436,97 @@ namespace AppInstaller::Repository { CompositeResult result; - // Search installed source - SearchResult installedResult = m_installedSource->Search(request); - result.Truncated = installedResult.Truncated; - - for (auto&& match : installedResult.Matches) + // If the search behavior is for AllPackages or Installed then the result can contain packages that are + // only in the Installed source, but do not have an AvailableVersion. + if (m_searchBehavior == CompositeSearchBehavior::AllPackages || m_searchBehavior == CompositeSearchBehavior::Installed) { - auto compositePackage = std::make_shared<CompositePackage>(std::move(match.Package)); - - // Create a search request to run against all available sources - // TODO: Determine if we should create a single search or one for each installed package. - SearchRequest systemReferenceSearch; + // Search installed source + SearchResult installedResult = m_installedSource->Search(request); + result.Truncated = installedResult.Truncated; - auto installedVersion = compositePackage->GetInstalledVersion(); - auto installedPackageData = result.GetSystemReferenceStrings(installedVersion.get()); - - if (!installedPackageData.SystemReferenceStrings.empty()) + for (auto&& match : installedResult.Matches) { - for (const auto& srs : installedPackageData.SystemReferenceStrings) - { - srs.AddToFilters(systemReferenceSearch.Inclusions); - } + auto compositePackage = std::make_shared<CompositePackage>(std::move(match.Package)); - std::shared_ptr<IPackage> availablePackage; + // Create a search request to run against all available sources + // TODO: Determine if we should create a single search or one for each installed package. + SearchRequest systemReferenceSearch; - // Search sources and add to result - for (const auto& source : m_availableSources) - { - SearchResult availableResult = source->Search(systemReferenceSearch); + auto installedVersion = compositePackage->GetInstalledVersion(); + auto installedPackageData = result.GetSystemReferenceStrings(installedVersion.get()); - if (availableResult.Matches.empty()) + if (!installedPackageData.SystemReferenceStrings.empty()) + { + for (const auto& srs : installedPackageData.SystemReferenceStrings) { - continue; + srs.AddToFilters(systemReferenceSearch.Inclusions); } - if (availableResult.Matches.size() == 1) - { - availablePackage = std::move(availableResult.Matches[0].Package); - } - else // availableResult.Matches.size() > 1 + std::shared_ptr<IPackage> availablePackage; + + // Search sources and add to result + for (const auto& source : m_availableSources) { - AICLI_LOG(Repo, Info, - << "Found multiple matches for installed package [" << installedVersion->GetProperty(PackageVersionProperty::Id) << - "] in source [" << source->GetIdentifier() << "] when searching for [" << systemReferenceSearch.ToString() << "]"); + SearchResult availableResult = source->Search(systemReferenceSearch); - // More than one match found for the system reference; run some heuristics to check for a match - for (auto&& availableMatch : availableResult.Matches) + if (availableResult.Matches.empty()) + { + continue; + } + + if (availableResult.Matches.size() == 1) + { + availablePackage = std::move(availableResult.Matches[0].Package); + } + else // availableResult.Matches.size() > 1 { - AICLI_LOG(Repo, Info, << " Checking match with package id: " << - availableMatch.Package->GetLatestAvailableVersion()->GetProperty(PackageVersionProperty::Id)); + AICLI_LOG(Repo, Info, + << "Found multiple matches for installed package [" << installedVersion->GetProperty(PackageVersionProperty::Id) << + "] in source [" << source->GetIdentifier() << "] when searching for [" << systemReferenceSearch.ToString() << "]"); - if (IsStrongMatchField(availableMatch.MatchCriteria.Field)) + // More than one match found for the system reference; run some heuristics to check for a match + for (auto&& availableMatch : availableResult.Matches) { - if (!availablePackage) - { - availablePackage = std::move(availableMatch.Package); - } - else + AICLI_LOG(Repo, Info, << " Checking match with package id: " << + availableMatch.Package->GetLatestAvailableVersion()->GetProperty(PackageVersionProperty::Id)); + + if (IsStrongMatchField(availableMatch.MatchCriteria.Field)) { - AICLI_LOG(Repo, Info, << " Found multiple packages with strong match fields"); - availablePackage.reset(); - break; + if (!availablePackage) + { + availablePackage = std::move(availableMatch.Package); + } + else + { + AICLI_LOG(Repo, Info, << " Found multiple packages with strong match fields"); + availablePackage.reset(); + break; + } } } - } - if (!availablePackage) - { - AICLI_LOG(Repo, Warning, << " Appropriate available package could not be determined"); + if (!availablePackage) + { + AICLI_LOG(Repo, Warning, << " Appropriate available package could not be determined"); + } } + + // We found some matching packages here, don't keep going + break; } - // We found some matching packages here, don't keep going - break; + compositePackage->SetAvailablePackage(std::move(availablePackage)); } - compositePackage->SetAvailablePackage(std::move(availablePackage)); + // Move the installed result into the composite result + result.Matches.emplace_back(std::move(compositePackage), std::move(match.MatchCriteria)); } - // Move the installed result into the composite result - result.Matches.emplace_back(std::move(compositePackage), std::move(match.MatchCriteria)); - } - - // Optimization for the "everything installed" case, no need to allow for reverse correlations - if (request.IsForEverything()) - { - return std::move(result); + // Optimization for the "everything installed" case, no need to allow for reverse correlations + if (request.IsForEverything() && m_searchBehavior == CompositeSearchBehavior::Installed) + { + return std::move(result); + } } // Search available sources @@ -559,7 +564,7 @@ namespace AppInstaller::Repository } // If there was no correlation for this package, add it without one. - if (m_searchBehavior == CompositeSearchBehavior::AllPackages && !foundInstalledMatch) + if ((m_searchBehavior == CompositeSearchBehavior::AllPackages || m_searchBehavior == CompositeSearchBehavior::AvailablePackages) && !foundInstalledMatch) { result.Matches.emplace_back(std::make_shared<CompositePackage>(std::shared_ptr<IPackage>{}, std::move(match.Package)), match.MatchCriteria); } diff --git a/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySource.h b/src/AppInstallerRepositoryCore/Public/AppInstallerRepositorySource.h @@ -117,6 +117,9 @@ namespace AppInstaller::Repository // Passing an empty string as the name of the source will return a source that aggregates all others. OpenSourceResult OpenSource(std::string_view name, IProgressCallback& progress); + // Opens an existing source. + OpenSourceResult OpenSourceFromDetails(SourceDetails& details, IProgressCallback& progress); + // A predefined source. // These sources are not under the direct control of the user, such as packages installed on the system. enum class PredefinedSource @@ -126,6 +129,16 @@ namespace AppInstaller::Repository MSIX, }; + // A well known source. + // These come with the app and can be disabled but not removed. + enum class WellKnownSource + { + WinGet, + }; + + SourceDetails GetPredefinedSourceDetails(PredefinedSource source); + SourceDetails GetWellKnownSourceDetails(WellKnownSource source); + // Opens a predefined source. // These sources are not under the direct control of the user, such as packages installed on the system. std::shared_ptr<ISource> OpenPredefinedSource(PredefinedSource source, IProgressCallback& progress); @@ -139,6 +152,8 @@ namespace AppInstaller::Repository Installed, // Search both installed and available packages. AllPackages, + // Search only available packages. + AvailablePackages, }; // Creates a source that merges the installed packages with the given available packages. @@ -148,6 +163,13 @@ namespace AppInstaller::Repository const std::shared_ptr<ISource>& availableSource, CompositeSearchBehavior searchBehavior = CompositeSearchBehavior::Installed); + // Creates a source that merges the installed packages with the given available packages from multiple sources. + // The source can search for installed packages only, or also include non-installed available packages. + std::shared_ptr<ISource> CreateCompositeSource( + const std::shared_ptr<ISource>& installedSource, + const std::vector<std::shared_ptr<ISource>>& availableSources, + CompositeSearchBehavior searchBehavior = CompositeSearchBehavior::Installed); + // Updates an existing source. // Return value indicates whether the named source was found. bool UpdateSource(std::string_view name, IProgressCallback& progress); diff --git a/src/AppInstallerRepositoryCore/RepositorySource.cpp b/src/AppInstallerRepositoryCore/RepositorySource.cpp @@ -42,7 +42,7 @@ namespace AppInstaller::Repository namespace { - // SourceDetails with additional data used by this file. + // SourceDetails with additional data. struct SourceDetailsInternal : public SourceDetails { // If true, this is a tombstone, marking the deletion of a source at a lower priority origin. @@ -684,6 +684,8 @@ 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; @@ -901,10 +903,10 @@ namespace AppInstaller::Repository OpenSourceResult OpenSource(std::string_view name, IProgressCallback& progress) { SourceListInternal sourceList; - auto currentSources = sourceList.GetCurrentSourceRefs(); if (name.empty()) { + auto currentSources = sourceList.GetCurrentSourceRefs(); if (currentSources.empty()) { AICLI_LOG(Repo, Info, << "Default source requested, but no sources configured"); @@ -988,8 +990,52 @@ namespace AppInstaller::Repository } } + OpenSourceResult OpenSourceFromDetails(SourceDetails& details, IProgressCallback& progress) + { + OpenSourceResult result; + + // Get the details again by name from the source list because SaveMetadata only updates the LastUpdateTime + // if the details came from the same instance of the list that's being saved. + SourceListInternal sourceList; + auto source = sourceList.GetSource(details.Name); + if (!source) + { + AICLI_LOG(Repo, Info, << "Named source no longer found. Source may have been removed by the user: " << details.Name); + return {}; + } + else if (source->IsTombstone) + { + AICLI_LOG(Repo, Info, << "Named source no longer found. Source was tombstoned: " << details.Name); + return {}; + } + if (ShouldUpdateBeforeOpen(*source)) + { + try + { + if (BackgroundUpdateSourceFromDetails(*source, progress)) + { + sourceList.SaveMetadata(); + } + } + catch (...) + { + AICLI_LOG(Repo, Warning, << "Failed to update source: " << details.Name); + result.SourcesWithUpdateFailure.emplace_back(*source); + } + } + + result.Source = CreateSourceFromDetails(details, progress); + return result; + } + std::shared_ptr<ISource> OpenPredefinedSource(PredefinedSource source, IProgressCallback& progress) { + SourceDetails details = GetPredefinedSourceDetails(source); + return CreateSourceFromDetails(details, progress); + } + + SourceDetails GetPredefinedSourceDetails(PredefinedSource source) + { SourceDetails details; details.Origin = SourceOrigin::Predefined; @@ -998,15 +1044,34 @@ namespace AppInstaller::Repository case PredefinedSource::Installed: details.Type = Microsoft::PredefinedInstalledSourceFactory::Type(); details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::None); - return CreateSourceFromDetails(details, progress); + return details; case PredefinedSource::ARP: details.Type = Microsoft::PredefinedInstalledSourceFactory::Type(); details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::ARP); - return CreateSourceFromDetails(details, progress); + return details; case PredefinedSource::MSIX: details.Type = Microsoft::PredefinedInstalledSourceFactory::Type(); details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::MSIX); - return CreateSourceFromDetails(details, progress); + return details; + } + + THROW_HR(E_UNEXPECTED); + } + + SourceDetails GetWellKnownSourceDetails(WellKnownSource source) + { + switch (source) + { + case WellKnownSource::WinGet: + SourceDetailsInternal details; + details.Origin = SourceOrigin::Default; + details.Name = s_Source_WingetCommunityDefault_Name; + details.Type = Microsoft::PreIndexedPackageSourceFactory::Type(); + details.Arg = s_Source_WingetCommunityDefault_Arg; + details.Data = s_Source_WingetCommunityDefault_Data; + details.Identifier = s_Source_WingetCommunityDefault_Identifier; + details.TrustLevel = SourceTrustLevel::Trusted | SourceTrustLevel::StoreOrigin; + return details; } THROW_HR(E_UNEXPECTED); @@ -1027,6 +1092,26 @@ namespace AppInstaller::Repository return result; } + std::shared_ptr<ISource> CreateCompositeSource( + const std::shared_ptr<ISource>& installedSource, + const std::vector<std::shared_ptr<ISource>>& availableSources, + CompositeSearchBehavior searchBehavior) + { + std::shared_ptr<CompositeSource> result = std::make_shared<CompositeSource>("*CompositeSource"); + + for (const auto& availableSource : availableSources) + { + result->AddAvailableSource(availableSource); + } + + if (installedSource) + { + result->SetInstalledSource(installedSource, searchBehavior); + } + + return result; + } + bool UpdateSource(std::string_view name, IProgressCallback& progress) { THROW_HR_IF(E_INVALIDARG, name.empty()); diff --git a/src/AppInstallerRepositoryCore/packages.config b/src/AppInstallerRepositoryCore/packages.config @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" /> - <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200519.2" targetFramework="native" /> + <package id="Microsoft.Windows.CppWinRT" version="2.0.210505.3" targetFramework="native" /> + <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" /> </packages> \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/CatalogPackage.cpp b/src/Microsoft.Management.Deployment/CatalogPackage.cpp @@ -0,0 +1,100 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <mutex> +#include <AppInstallerRepositorySource.h> +#include <AppInstallerRepositorySearch.h> +#include "CatalogPackage.h" +#include "CatalogPackage.g.cpp" +#include "PackageCatalog.h" +#include "PackageVersionInfo.h" +#include "PackageVersionId.h" +#include <wil\cppwinrt_wrl.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void CatalogPackage::Initialize( + std::shared_ptr<const ::AppInstaller::Repository::ISource> source, + std::shared_ptr<::AppInstaller::Repository::IPackage> package) + { + m_source = std::move(source); + m_package = std::move(package); + } + hstring CatalogPackage::Id() + { + return winrt::to_hstring(m_package->GetProperty(::AppInstaller::Repository::PackageProperty::Id).get()); + } + hstring CatalogPackage::Name() + { + return winrt::to_hstring(m_package->GetProperty(::AppInstaller::Repository::PackageProperty::Name)); + } + Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::InstalledVersion() + { + std::call_once(m_installedVersionOnceFlag, + [&]() + { + std::shared_ptr<::AppInstaller::Repository::IPackageVersion> installedVersion = m_package.get()->GetInstalledVersion(); + if (installedVersion) + { + auto installedVersionImpl = winrt::make_self<wil::details::module_count_wrapper< + winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo>>(); + installedVersionImpl->Initialize(std::move(installedVersion)); + m_installedVersion = *installedVersionImpl; + } + }); + return m_installedVersion; + } + Windows::Foundation::Collections::IVectorView<Microsoft::Management::Deployment::PackageVersionId> CatalogPackage::AvailableVersions() + { + std::call_once(m_availableVersionsOnceFlag, + [&]() + { + // Vector hasn't been populated yet. + for (auto const& versionKey : m_package.get()->GetAvailableVersionKeys()) + { + auto packageVersionId = winrt::make_self<wil::details::module_count_wrapper< + winrt::Microsoft::Management::Deployment::implementation::PackageVersionId>>(); + packageVersionId->Initialize(versionKey); + m_availableVersions.Append(*packageVersionId); + } + }); + return m_availableVersions.GetView(); + } + Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::DefaultInstallVersion() + { + std::call_once(m_defaultInstallVersionOnceFlag, + [&]() + { + std::shared_ptr<::AppInstaller::Repository::IPackageVersion> latestVersion = m_package.get()->GetLatestAvailableVersion(); + if (latestVersion) + { + // DefaultInstallVersion hasn't been created yet, create and populate it. + // DefaultInstallVersion is the LatestAvailableVersion of the internal package object. + auto latestVersionImpl = winrt::make_self<wil::details::module_count_wrapper< + winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo>>(); + latestVersionImpl->Initialize(std::move(latestVersion)); + m_defaultInstallVersion = *latestVersionImpl; + } + }); + return m_defaultInstallVersion; + } + Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::GetPackageVersionInfo(Microsoft::Management::Deployment::PackageVersionId const& versionKey) + { + winrt::Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo{ nullptr }; + + ::AppInstaller::Repository::PackageVersionKey internalVersionKey(winrt::to_string(versionKey.PackageCatalogId()), winrt::to_string(versionKey.Version()), winrt::to_string(versionKey.Channel())); + std::shared_ptr<::AppInstaller::Repository::IPackageVersion> availableVersion = m_package.get()->GetAvailableVersion(internalVersionKey); + if (availableVersion) + { + auto packageVersionInfoImpl = winrt::make_self<wil::details::module_count_wrapper< + winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo>>(); + packageVersionInfoImpl->Initialize(std::move(availableVersion)); + packageVersionInfo =*packageVersionInfoImpl; + } + return packageVersionInfo; + } + bool CatalogPackage::IsUpdateAvailable() + { + return m_package->IsUpdateAvailable(); + } +} diff --git a/src/Microsoft.Management.Deployment/CatalogPackage.h b/src/Microsoft.Management.Deployment/CatalogPackage.h @@ -0,0 +1,32 @@ +// 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> + { + CatalogPackage() = default; + void Initialize( + std::shared_ptr<const ::AppInstaller::Repository::ISource> source, + std::shared_ptr<::AppInstaller::Repository::IPackage> package); + + hstring Id(); + hstring Name(); + winrt::Microsoft::Management::Deployment::PackageVersionInfo InstalledVersion(); + winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageVersionId> AvailableVersions(); + winrt::Microsoft::Management::Deployment::PackageVersionInfo DefaultInstallVersion(); + winrt::Microsoft::Management::Deployment::PackageVersionInfo GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey); + bool IsUpdateAvailable(); + private: + std::shared_ptr<const ::AppInstaller::Repository::ISource> m_source; + std::shared_ptr<::AppInstaller::Repository::IPackage> m_package; + Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageVersionId> m_availableVersions{ winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::PackageVersionId>() }; + winrt::Microsoft::Management::Deployment::PackageVersionInfo m_installedVersion{ nullptr }; + winrt::Microsoft::Management::Deployment::PackageVersionInfo m_defaultInstallVersion{ nullptr }; + std::once_flag m_installedVersionOnceFlag; + std::once_flag m_availableVersionsOnceFlag; + std::once_flag m_defaultInstallVersionOnceFlag; + }; +}+ \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/ConnectResult.cpp b/src/Microsoft.Management.Deployment/ConnectResult.cpp @@ -0,0 +1,22 @@ +// 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 +{ + void ConnectResult::Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus status, winrt::Microsoft::Management::Deployment::PackageCatalog packageCatalog) + { + m_status = status; + m_packageCatalog = packageCatalog; + } + winrt::Microsoft::Management::Deployment::ConnectResultStatus ConnectResult::Status() + { + return m_status; + } + winrt::Microsoft::Management::Deployment::PackageCatalog ConnectResult::PackageCatalog() + { + return m_packageCatalog; + } +} diff --git a/src/Microsoft.Management.Deployment/ConnectResult.h b/src/Microsoft.Management.Deployment/ConnectResult.h @@ -0,0 +1,19 @@ +// 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> + { + ConnectResult() = default; + void Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus status, winrt::Microsoft::Management::Deployment::PackageCatalog packageCatalog); + + winrt::Microsoft::Management::Deployment::ConnectResultStatus Status(); + winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); + private: + winrt::Microsoft::Management::Deployment::ConnectResultStatus m_status = winrt::Microsoft::Management::Deployment::ConnectResultStatus::Ok; + winrt::Microsoft::Management::Deployment::PackageCatalog m_packageCatalog{ nullptr }; + }; +} diff --git a/src/Microsoft.Management.Deployment/Converters.cpp b/src/Microsoft.Management.Deployment/Converters.cpp @@ -0,0 +1,269 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <AppInstallerErrors.h> +#include <AppInstallerRepositorySearch.h> +#include <AppInstallerRepositorySource.h> +#include "Microsoft/PredefinedInstalledSourceFactory.h" +#include "Converters.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + Microsoft::Management::Deployment::PackageMatchField GetDeploymentMatchField(::AppInstaller::Repository::PackageMatchField field) + { + Microsoft::Management::Deployment::PackageMatchField matchField = Microsoft::Management::Deployment::PackageMatchField::Id; + switch (field) + { + case ::AppInstaller::Repository::PackageMatchField::Command: + matchField = Microsoft::Management::Deployment::PackageMatchField::Command; + break; + case ::AppInstaller::Repository::PackageMatchField::Id: + matchField = Microsoft::Management::Deployment::PackageMatchField::Id; + break; + case ::AppInstaller::Repository::PackageMatchField::Moniker: + matchField = Microsoft::Management::Deployment::PackageMatchField::Moniker; + break; + case ::AppInstaller::Repository::PackageMatchField::Name: + matchField = Microsoft::Management::Deployment::PackageMatchField::Name; + break; + case ::AppInstaller::Repository::PackageMatchField::Tag: + matchField = Microsoft::Management::Deployment::PackageMatchField::Tag; + break; + default: + matchField = Microsoft::Management::Deployment::PackageMatchField::Id; + break; + } + return matchField; + } + + ::AppInstaller::Repository::PackageMatchField GetRepositoryMatchField(Microsoft::Management::Deployment::PackageMatchField field) + { + ::AppInstaller::Repository::PackageMatchField matchField = ::AppInstaller::Repository::PackageMatchField::Id; + switch (field) + { + case Microsoft::Management::Deployment::PackageMatchField::Command: + matchField = ::AppInstaller::Repository::PackageMatchField::Command; + break; + case Microsoft::Management::Deployment::PackageMatchField::Id: + matchField = ::AppInstaller::Repository::PackageMatchField::Id; + break; + case Microsoft::Management::Deployment::PackageMatchField::Moniker: + matchField = ::AppInstaller::Repository::PackageMatchField::Moniker; + break; + case Microsoft::Management::Deployment::PackageMatchField::Name: + matchField = ::AppInstaller::Repository::PackageMatchField::Name; + break; + case Microsoft::Management::Deployment::PackageMatchField::Tag: + matchField = ::AppInstaller::Repository::PackageMatchField::Tag; + break; + default: + matchField = ::AppInstaller::Repository::PackageMatchField::Id; + break; + } + return matchField; + } + + Microsoft::Management::Deployment::PackageFieldMatchOption GetDeploymentMatchOption(::AppInstaller::Repository::MatchType type) + { + Microsoft::Management::Deployment::PackageFieldMatchOption matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::Equals; + switch (type) + { + case ::AppInstaller::Repository::MatchType::CaseInsensitive: + matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::EqualsCaseInsensitive; + break; + case ::AppInstaller::Repository::MatchType::Exact: + matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::Equals; + break; + case ::AppInstaller::Repository::MatchType::StartsWith: + matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::StartsWithCaseInsensitive; + break; + case ::AppInstaller::Repository::MatchType::Substring: + matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::ContainsCaseInsensitive; + break; + default: + matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::Equals; + break; + } + return matchOption; + } + + ::AppInstaller::Repository::MatchType GetRepositoryMatchType(Microsoft::Management::Deployment::PackageFieldMatchOption option) + { + ::AppInstaller::Repository::MatchType packageFieldMatchOption = ::AppInstaller::Repository::MatchType::Exact; + switch (option) + { + case Microsoft::Management::Deployment::PackageFieldMatchOption::EqualsCaseInsensitive: + packageFieldMatchOption = ::AppInstaller::Repository::MatchType::CaseInsensitive; + break; + case Microsoft::Management::Deployment::PackageFieldMatchOption::Equals: + packageFieldMatchOption = ::AppInstaller::Repository::MatchType::Exact; + break; + case Microsoft::Management::Deployment::PackageFieldMatchOption::StartsWithCaseInsensitive: + packageFieldMatchOption = ::AppInstaller::Repository::MatchType::StartsWith; + break; + case Microsoft::Management::Deployment::PackageFieldMatchOption::ContainsCaseInsensitive: + packageFieldMatchOption = ::AppInstaller::Repository::MatchType::Substring; + break; + default: + packageFieldMatchOption = ::AppInstaller::Repository::MatchType::Exact; + break; + } + return packageFieldMatchOption; + } + + ::AppInstaller::Repository::CompositeSearchBehavior GetRepositoryCompositeSearchBehavior(Microsoft::Management::Deployment::CompositeSearchBehavior searchBehavior) + { + ::AppInstaller::Repository::CompositeSearchBehavior repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::AllPackages; + switch (searchBehavior) + { + case Microsoft::Management::Deployment::CompositeSearchBehavior::LocalCatalogs: + repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::Installed; + break; + case Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromRemoteCatalogs: + repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::AvailablePackages; + break; + case Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromAllCatalogs: + repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::AvailablePackages; + break; + case Microsoft::Management::Deployment::CompositeSearchBehavior::AllCatalogs: + default: + repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::AllPackages; + break; + } + return repositorySearchBehavior; + } + + ::AppInstaller::Repository::PackageVersionMetadata GetRepositoryPackageVersionMetadata(Microsoft::Management::Deployment::PackageVersionMetadataField packageVersionMetadataField) + { + ::AppInstaller::Repository::PackageVersionMetadata metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::InstalledLocation; + switch (packageVersionMetadataField) + { + case Microsoft::Management::Deployment::PackageVersionMetadataField::InstalledLocation: + metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::InstalledLocation; + break; + case Microsoft::Management::Deployment::PackageVersionMetadataField::InstalledScope: + metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::InstalledScope; + break; + case Microsoft::Management::Deployment::PackageVersionMetadataField::InstallerType: + metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::InstalledType; + break; + case Microsoft::Management::Deployment::PackageVersionMetadataField::PublisherDisplayName: + metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::Publisher; + break; + case Microsoft::Management::Deployment::PackageVersionMetadataField::SilentUninstallCommand: + metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::SilentUninstallCommand; + break; + case Microsoft::Management::Deployment::PackageVersionMetadataField::StandardUninstallCommand: + metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::StandardUninstallCommand; + break; + } + return metadataKey; + } + + winrt::Microsoft::Management::Deployment::InstallResultStatus GetInstallResultStatus(winrt::hresult hresult) + { + winrt::Microsoft::Management::Deployment::InstallResultStatus resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::Ok; + switch (hresult) + { + case(S_OK): + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::Ok; + break; + case APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY: + case APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY: + case APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED: + case APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::BlockedByPolicy; + break; + case APPINSTALLER_CLI_ERROR_MANIFEST_FAILED: + case APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION: + case APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE: + case APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING: + case APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE: + case APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA: + case APPINSTALLER_CLI_ERROR_RESTSOURCE_INTERNAL_ERROR: + case APPINSTALLER_CLI_ERROR_RESTSOURCE_UNSUPPORTED_MIME_TYPE: + case APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION: + case APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE: + case APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST: + case APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND: + case APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED: + case APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::CatalogError; + break; + case E_INVALIDARG: + case APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::InvalidOptions; + break; + case APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED: + case APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH: + case APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED: + case APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::DownloadError; + break; + case APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED: + case APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::InstallError; + break; + case APPINSTALLER_CLI_ERROR_INVALID_MANIFEST: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::ManifestError; + break; + case APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::NoApplicableInstallers; + break; + case APPINSTALLER_CLI_ERROR_COMMAND_FAILED: + case APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX: + case APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED: + case APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED: + case APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY: + case APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY: + case APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION: + case APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED: + case APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE: + case APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA: + case APPINSTALLER_CLI_ERROR_LIBYAML_ERROR: + case APPINSTALLER_CLI_ERROR_INTERNAL_ERROR: + default: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::InternalError; + break; + } + return resultStatus; + } + + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResultStatus(winrt::hresult hresult) + { + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::Ok; + switch (hresult) + { + case(S_OK): + resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::Ok; + break; + case APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY: + resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::BlockedByPolicy; + break; + case APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE: + case APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA: + case APPINSTALLER_CLI_ERROR_RESTSOURCE_INTERNAL_ERROR: + case APPINSTALLER_CLI_ERROR_RESTSOURCE_UNSUPPORTED_MIME_TYPE: + case APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION: + case APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE: + resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::CatalogError; + break; + case E_INVALIDARG: + case APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS: + resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::InvalidOptions; + break; + case APPINSTALLER_CLI_ERROR_COMMAND_FAILED: + case APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX: + case APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED: + default: + resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::InternalError; + break; + } + return resultStatus; + } + + bool IsLocalPackageCatalog(winrt::Microsoft::Management::Deployment::PackageCatalogInfo info) + { + return (winrt::to_string(info.Type()).compare(::AppInstaller::Repository::Microsoft::PredefinedInstalledSourceFactory::Type()) == 0); + } +}+ \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/Converters.h b/src/Microsoft.Management.Deployment/Converters.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageMatchFilter.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::PackageMatchField GetDeploymentMatchField(::AppInstaller::Repository::PackageMatchField field); + ::AppInstaller::Repository::PackageMatchField GetRepositoryMatchField(winrt::Microsoft::Management::Deployment::PackageMatchField field); + winrt::Microsoft::Management::Deployment::PackageFieldMatchOption GetDeploymentMatchOption(::AppInstaller::Repository::MatchType type); + ::AppInstaller::Repository::MatchType GetRepositoryMatchType(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption option); + ::AppInstaller::Repository::CompositeSearchBehavior GetRepositoryCompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior searchBehavior); + ::AppInstaller::Repository::PackageVersionMetadata GetRepositoryPackageVersionMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField packageVersionMetadataField); + winrt::Microsoft::Management::Deployment::InstallResultStatus GetInstallResultStatus(winrt::hresult hresult); + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResultStatus(winrt::hresult hresult); + bool IsLocalPackageCatalog(winrt::Microsoft::Management::Deployment::PackageCatalogInfo info); +}+ \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.cpp b/src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.cpp @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +// 6388 Allow CreateInstance. +#include <wil\cppwinrt_wrl.h> +// 4467 Allow use of uuid attribute for com object creation. +#include "CreateCompositePackageCatalogOptions.h" +#pragma warning( pop ) +#include "CreateCompositePackageCatalogOptions.g.cpp" +#include "Helpers.h" + +const GUID CreateCompositePackageCatalogOptionsCLSID1 = { 0x526534B8, 0x7E46, 0x47C8, { 0x84, 0x16, 0xB1, 0x68, 0x5C, 0x32, 0x7D, 0x37 } }; //526534B8-7E46-47C8-8416-B1685C327D37 +const GUID CreateCompositePackageCatalogOptionsCLSID2 = { 0x6444B10D, 0xFE84, 0x430F, { 0x93, 0x2B, 0x3D, 0x4F, 0xE5, 0x19, 0x5B, 0xDF } }; //6444B10D-FE84-430F-932B-3D4FE5195BDF + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageCatalogReference> CreateCompositePackageCatalogOptions::Catalogs() + { + return m_catalogs; + } + winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CreateCompositePackageCatalogOptions::CompositeSearchBehavior() + { + return m_compositeSearchBehavior; + } + void CreateCompositePackageCatalogOptions::CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value) + { + m_compositeSearchBehavior = value; + } + CoCreatableCppWinRtClassWithCLSID(CreateCompositePackageCatalogOptions, 1, &CreateCompositePackageCatalogOptionsCLSID1); + CoCreatableCppWinRtClassWithCLSID(CreateCompositePackageCatalogOptions, 2, &CreateCompositePackageCatalogOptionsCLSID2); +} diff --git a/src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.h b/src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.h @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "CreateCompositePackageCatalogOptions.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + [uuid("526534B8-7E46-47C8-8416-B1685C327D37")] + struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT<CreateCompositePackageCatalogOptions> + { + CreateCompositePackageCatalogOptions() = default; + + winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageCatalogReference> Catalogs(); + winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CompositeSearchBehavior(); + void CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value); + private: + winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageCatalogReference> m_catalogs{ winrt::single_threaded_vector<Microsoft::Management::Deployment::PackageCatalogReference>() }; + winrt::Microsoft::Management::Deployment::CompositeSearchBehavior m_compositeSearchBehavior = winrt::Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromAllCatalogs; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT<CreateCompositePackageCatalogOptions, implementation::CreateCompositePackageCatalogOptions> + { + }; +} diff --git a/src/Microsoft.Management.Deployment/FindPackagesOptions.cpp b/src/Microsoft.Management.Deployment/FindPackagesOptions.cpp @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +// 6388 Allow CreateInstance. +#include <wil\cppwinrt_wrl.h> +// 4467 Allow use of uuid attribute for com object creation. +#include "FindPackagesOptions.h" +#pragma warning( pop ) +#include "FindPackagesOptions.g.cpp" +#include "Helpers.h" + +const GUID FindPackagesOptionsCLSID1 = { 0x572DED96, 0x9C60, 0x4526, { 0x8F, 0x92, 0xEE, 0x7D, 0x91, 0xD3, 0x8C, 0x1A } }; //572DED96-9C60-4526-8F92-EE7D91D38C1A +const GUID FindPackagesOptionsCLSID2 = { 0x2CAD6C15, 0xDF8E, 0x49DD, { 0xA7, 0x48, 0x96, 0xAD, 0xE0, 0xFE, 0x31, 0xB7 } }; //2CAD6C15-DF8E-49DD-A748-96ADE0FE31B7 + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageMatchFilter> FindPackagesOptions::Selectors() + { + return m_selectors; + } + winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageMatchFilter> FindPackagesOptions::Filters() + { + return m_filters; + } + uint32_t FindPackagesOptions::ResultLimit() + { + return m_resultLimit; + } + void FindPackagesOptions::ResultLimit(uint32_t value) + { + m_resultLimit = value; + } + CoCreatableCppWinRtClassWithCLSID(FindPackagesOptions, 1, &FindPackagesOptionsCLSID1); + CoCreatableCppWinRtClassWithCLSID(FindPackagesOptions, 2, &FindPackagesOptionsCLSID2); +} diff --git a/src/Microsoft.Management.Deployment/FindPackagesOptions.h b/src/Microsoft.Management.Deployment/FindPackagesOptions.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "FindPackagesOptions.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct FindPackagesOptions : FindPackagesOptionsT<FindPackagesOptions> + { + FindPackagesOptions() = default; + + winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageMatchFilter> Selectors(); + winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageMatchFilter> Filters(); + uint32_t ResultLimit(); + void ResultLimit(uint32_t value); + private: + uint32_t m_resultLimit = 0; + Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageMatchFilter> m_selectors{ + winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::PackageMatchFilter>() }; + Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageMatchFilter> m_filters{ + winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::PackageMatchFilter>() }; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct FindPackagesOptions : FindPackagesOptionsT<FindPackagesOptions, implementation::FindPackagesOptions> + { + }; +} diff --git a/src/Microsoft.Management.Deployment/FindPackagesResult.cpp b/src/Microsoft.Management.Deployment/FindPackagesResult.cpp @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "FindPackagesResult.h" +#include "FindPackagesResult.g.cpp" +#include <wil\cppwinrt_wrl.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void FindPackagesResult::Initialize( + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus status, + bool wasLimitExceeded, + Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::MatchResult> matches) + { + m_status = status; + m_matches = matches; + m_wasLimitExceeded = wasLimitExceeded; + } + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResult::Status() + { + return m_status; + } + winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::MatchResult> FindPackagesResult::Matches() + { + return m_matches.GetView(); + } + bool FindPackagesResult::WasLimitExceeded() + { + return m_wasLimitExceeded; + } +} diff --git a/src/Microsoft.Management.Deployment/FindPackagesResult.h b/src/Microsoft.Management.Deployment/FindPackagesResult.h @@ -0,0 +1,26 @@ +// 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> + { + FindPackagesResult() = default; + void Initialize( + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus errorCode, + bool wasLimitExceeded, + Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::MatchResult> matches); + + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus Status(); + winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::MatchResult> Matches(); + bool WasLimitExceeded(); + + private: + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus m_status = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::Ok; + Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::MatchResult> m_matches{ + winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::MatchResult>() }; + bool m_wasLimitExceeded = false; + }; +} diff --git a/src/Microsoft.Management.Deployment/Helpers.h b/src/Microsoft.Management.Deployment/Helpers.h @@ -0,0 +1,6 @@ +#pragma once + +//A version of CoCreatableCppWinRtClass that lets you pass in a uuid rather than getting it from a class property. +#define CoCreatableClassWithCLSIDWithFactory(className, instance, clsid, factory) \ + InternalWrlCreateCreatorMap(className##instance##_COM, clsid, nullptr, ::Microsoft::WRL::Details::CreateClassFactory<factory>, "minATL$__f") +#define CoCreatableCppWinRtClassWithCLSID(className, instance, clsid) CoCreatableClassWithCLSIDWithFactory(className, instance, clsid, ::wil::wrl_factory_for_winrt_com_class<className>)+ \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/InstallOptions.cpp b/src/Microsoft.Management.Deployment/InstallOptions.cpp @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +// 6388 Allow CreateInstance. +#include <wil\cppwinrt_wrl.h> +// 4467 Allow use of uuid attribute for com object creation. +#include "InstallOptions.h" +#pragma warning( pop ) +#include "InstallOptions.g.cpp" +#include "Helpers.h" + +const GUID InstallOptionsCLSID1 = { 0x1095F097, 0xEB96, 0x453B, 0xB4, 0xE6, 0x16, 0x13, 0x63, 0x7F, 0x3B, 0x14 }; //1095F097-EB96-453B-B4E6-1613637F3B14 +const GUID InstallOptionsCLSID2 = { 0x05F7019A, 0x8FAC, 0x4422, 0xBC, 0xD5, 0x4C, 0xB3, 0x4F, 0xFB, 0x44, 0xA8 }; //05F7019A-8FAC-4422-BCD5-4CB34FFB44A8 + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Microsoft::Management::Deployment::PackageVersionId InstallOptions::PackageVersionId() + { + return m_packageVersionId; + } + void InstallOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value) + { + m_packageVersionId = value; + } + hstring InstallOptions::PreferredInstallLocation() + { + return hstring(m_preferredInstallLocation); + } + void InstallOptions::PreferredInstallLocation(hstring const& value) + { + m_preferredInstallLocation = value; + } + winrt::Microsoft::Management::Deployment::PackageInstallScope InstallOptions::PackageInstallScope() + { + return m_packageInstallScope; + } + void InstallOptions::PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value) + { + m_packageInstallScope = value; + } + winrt::Microsoft::Management::Deployment::PackageInstallMode InstallOptions::PackageInstallMode() + { + return m_packageInstallMode; + } + void InstallOptions::PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const& value) + { + m_packageInstallMode = value; + } + hstring InstallOptions::LogOutputPath() + { + return hstring(m_logOutputPath); + } + void InstallOptions::LogOutputPath(hstring const& value) + { + m_logOutputPath = value; + } + bool InstallOptions::AllowHashMismatch() + { + return m_allowHashMismatch; + } + void InstallOptions::AllowHashMismatch(bool value) + { + m_allowHashMismatch = value; + } + hstring InstallOptions::ReplacementInstallerArguments() + { + return hstring(m_replacementInstallerArguments); + } + void InstallOptions::ReplacementInstallerArguments(hstring const& value) + { + m_replacementInstallerArguments = value; + } + hstring InstallOptions::CorrelationData() + { + return hstring(m_correlationData); + } + void InstallOptions::CorrelationData(hstring const& value) + { + m_correlationData = value; + } + hstring InstallOptions::AdditionalPackageCatalogArguments() + { + return hstring(m_additionalPackageCatalogArguments); + } + void InstallOptions::AdditionalPackageCatalogArguments(hstring const& value) + { + m_additionalPackageCatalogArguments = value; + } + CoCreatableCppWinRtClassWithCLSID(InstallOptions, 1, &InstallOptionsCLSID1); + CoCreatableCppWinRtClassWithCLSID(InstallOptions, 2, &InstallOptionsCLSID2); +} diff --git a/src/Microsoft.Management.Deployment/InstallOptions.h b/src/Microsoft.Management.Deployment/InstallOptions.h @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "InstallOptions.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + struct InstallOptions : InstallOptionsT<InstallOptions> + { + 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); + private: + winrt::Microsoft::Management::Deployment::PackageVersionId m_packageVersionId{ nullptr }; + std::wstring m_preferredInstallLocation = L""; + winrt::Microsoft::Management::Deployment::PackageInstallScope m_packageInstallScope = winrt::Microsoft::Management::Deployment::PackageInstallScope::User; + winrt::Microsoft::Management::Deployment::PackageInstallMode m_packageInstallMode = winrt::Microsoft::Management::Deployment::PackageInstallMode::Default; + std::wstring m_logOutputPath = L""; + bool m_allowHashMismatch = false; + std::wstring m_replacementInstallerArguments = L""; + std::wstring m_correlationData = L""; + std::wstring m_additionalPackageCatalogArguments = L""; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct InstallOptions : InstallOptionsT<InstallOptions, implementation::InstallOptions> + { + }; +} diff --git a/src/Microsoft.Management.Deployment/InstallResult.cpp b/src/Microsoft.Management.Deployment/InstallResult.cpp @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "InstallResult.h" +#include "InstallResult.g.cpp" +#include <wil\cppwinrt_wrl.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void InstallResult::Initialize( + winrt::Microsoft::Management::Deployment::InstallResultStatus status, + winrt::hresult extendedErrorCode, + hstring const& correlationData, + bool rebootRequired) + { + m_status = status; + m_extendedErrorCode = extendedErrorCode; + m_correlationData = correlationData; + m_rebootRequired = rebootRequired; + } + hstring InstallResult::CorrelationData() + { + return hstring(m_correlationData); + } + bool InstallResult::RebootRequired() + { + return m_rebootRequired; + } + winrt::Microsoft::Management::Deployment::InstallResultStatus InstallResult::Status() + { + return m_status; + } + winrt::hresult InstallResult::ExtendedErrorCode() + { + return m_extendedErrorCode; + } +} diff --git a/src/Microsoft.Management.Deployment/InstallResult.h b/src/Microsoft.Management.Deployment/InstallResult.h @@ -0,0 +1,27 @@ +// 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> + { + InstallResult() = default; + void Initialize( + winrt::Microsoft::Management::Deployment::InstallResultStatus status, + winrt::hresult extendedErrorCode, + hstring const& correlationData, + bool rebootRequired); + + hstring CorrelationData(); + bool RebootRequired(); + winrt::Microsoft::Management::Deployment::InstallResultStatus Status(); + winrt::hresult ExtendedErrorCode(); + 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; + }; +} diff --git a/src/Microsoft.Management.Deployment/MatchResult.cpp b/src/Microsoft.Management.Deployment/MatchResult.cpp @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <mutex> +#include <AppInstallerRepositorySource.h> +#include <AppInstallerRepositorySearch.h> +#include "MatchResult.h" +#include "MatchResult.g.cpp" +#include "CatalogPackage.h" +#include <wil\cppwinrt_wrl.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void MatchResult::Initialize(Microsoft::Management::Deployment::CatalogPackage package, Microsoft::Management::Deployment::PackageMatchFilter matchCriteria) + { + m_catalogPackage = package; + m_matchCriteria = matchCriteria; + } + winrt::Microsoft::Management::Deployment::CatalogPackage MatchResult::CatalogPackage() + { + return m_catalogPackage; + } + winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchResult::MatchCriteria() + { + return m_matchCriteria; + } +} diff --git a/src/Microsoft.Management.Deployment/MatchResult.h b/src/Microsoft.Management.Deployment/MatchResult.h @@ -0,0 +1,19 @@ +// 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> + { + MatchResult() = default; + void Initialize(Microsoft::Management::Deployment::CatalogPackage package, Microsoft::Management::Deployment::PackageMatchFilter matchCriteria); + + winrt::Microsoft::Management::Deployment::CatalogPackage CatalogPackage(); + winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchCriteria(); + private: + Microsoft::Management::Deployment::CatalogPackage m_catalogPackage{ nullptr }; + Microsoft::Management::Deployment::PackageMatchFilter m_matchCriteria{ nullptr }; + }; +} diff --git a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj @@ -0,0 +1,193 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" /> + <PropertyGroup Label="Globals"> + <CppWinRTOptimized>true</CppWinRTOptimized> + <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge> + <CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata> + <MinimalCoreWin>true</MinimalCoreWin> + <ProjectGuid>{1cc41a9a-ae66-459d-9210-1e572dd7be69}</ProjectGuid> + <ProjectName>Microsoft.Management.Deployment</ProjectName> + <RootNamespace>Microsoft.Management.Deployment</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> + <ApplicationTypeRevision>10.0</ApplicationTypeRevision> + <WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion> + <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion> + <CppWinRTParameters>-lib Microsoft_Management_Deployment</CppWinRTParameters> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset> + <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration"> + <UseDebugLibraries>true</UseDebugLibraries> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration"> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <LinkIncremental>false</LinkIncremental> + <SpectreMitigation>Spectre</SpectreMitigation> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="PropertySheet.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath> + <OutDir>$(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> + <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors> + <RunCodeAnalysis>false</RunCodeAnalysis> + <CodeAnalysisRuleSet>..\CodeAnalysis.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile> + <WarningLevel>Level4</WarningLevel> + <AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions> + <TreatWarningAsError>true</TreatWarningAsError> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>_WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories> + <AdditionalIncludeDirectories>$(ProjectDir)..\AppInstallerCLICore;$(ProjectDir);$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <ModuleDefinitionFile>Microsoft_Management_Deployment.def</ModuleDefinitionFile> + <WindowsMetadataFile>$(OutDir)$(ProjectName).winmd</WindowsMetadataFile> + <AdditionalDependencies>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;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'"> + <ClCompile> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ProgramDataBaseFileName>$(OutDir)$(TargetName)Debug.pdb</ProgramDataBaseFileName> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> + <ClCompile> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="CatalogPackage.h" /> + <ClInclude Include="ConnectResult.h" /> + <ClInclude Include="Converters.h" /> + <ClInclude Include="CreateCompositePackageCatalogOptions.h" /> + <ClInclude Include="FindPackagesOptions.h" /> + <ClInclude Include="FindPackagesResult.h" /> + <ClInclude Include="Helpers.h" /> + <ClInclude Include="InstallOptions.h" /> + <ClInclude Include="InstallResult.h" /> + <ClInclude Include="MatchResult.h" /> + <ClInclude Include="PackageCatalog.h" /> + <ClInclude Include="PackageCatalogInfo.h" /> + <ClInclude Include="PackageCatalogReference.h" /> + <ClInclude Include="PackageManager.h" /> + <ClInclude Include="PackageMatchFilter.h" /> + <ClInclude Include="PackageVersionId.h" /> + <ClInclude Include="PackageVersionInfo.h" /> + <ClInclude Include="pch.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="CatalogPackage.cpp" /> + <ClCompile Include="ConnectResult.cpp" /> + <ClCompile Include="Converters.cpp" /> + <ClCompile Include="CreateCompositePackageCatalogOptions.cpp" /> + <ClCompile Include="FindPackagesOptions.cpp" /> + <ClCompile Include="FindPackagesResult.cpp" /> + <ClCompile Include="InstallOptions.cpp" /> + <ClCompile Include="InstallResult.cpp" /> + <ClCompile Include="MatchResult.cpp" /> + <ClCompile Include="PackageCatalog.cpp" /> + <ClCompile Include="PackageCatalogInfo.cpp" /> + <ClCompile Include="PackageCatalogReference.cpp" /> + <ClCompile Include="PackageManager.cpp" /> + <ClCompile Include="PackageMatchFilter.cpp" /> + <ClCompile Include="PackageVersionId.cpp" /> + <ClCompile Include="PackageVersionInfo.cpp" /> + <ClCompile Include="pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="$(GeneratedFilesDir)module.g.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="Microsoft_Management_Deployment.def" /> + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> + <None Include="PropertySheet.props" /> + </ItemGroup> + <ItemGroup> + <Midl Include="PackageManager.idl" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + </ImportGroup> + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> + <PropertyGroup> + <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> + </PropertyGroup> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + </Target> +</Project>+ \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/Microsoft_Management_Deployment.def b/src/Microsoft.Management.Deployment/Microsoft_Management_Deployment.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/src/Microsoft.Management.Deployment/PackageCatalog.cpp b/src/Microsoft.Management.Deployment/PackageCatalog.cpp @@ -0,0 +1,175 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <mutex> +#include <AppInstallerRepositorySource.h> +#include "Converters.h" +#include "PackageCatalog.h" +#include "PackageCatalog.g.cpp" +#include "PackageCatalogInfo.h" +#include "FindPackagesResult.h" +#include "MatchResult.h" +#include "CatalogPackage.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +// 6388 Allow CreateInstance. +#include <wil\cppwinrt_wrl.h> +// 4467 Allow use of uuid attribute for com object creation. +#include "PackageMatchFilter.h" +#pragma warning( pop ) +#include "Microsoft/PredefinedInstalledSourceFactory.h" +#include <winget/GroupPolicy.h> +#include <AppInstallerErrors.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void PackageCatalog::Initialize( + winrt::Microsoft::Management::Deployment::PackageCatalogInfo info, + std::shared_ptr<const ::AppInstaller::Repository::ISource> source, + bool isComposite) + { + m_info = info; + m_source = std::move(source); + m_isComposite = isComposite; + } + bool PackageCatalog::IsComposite() + { + // Can't use m_source->IsComposite for this because all remote sources are turned into composite sources + // behind the scenes when being opened in PackageCatalogReference.cpp so that CatalogPackage.IsInstalled works. + return m_isComposite; + } + winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalog::Info() + { + return m_info; + } + winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::FindPackagesResult> PackageCatalog::FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options) + { + co_return FindPackages(options); + } + + HRESULT PopulateSearchRequestFromVector( + ::AppInstaller::Repository::SearchRequest* searchRequest, + Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageMatchFilter> vector, + bool isSelector) + { + // Populates either the Filters vector of a searchRequest (if isSelector is false), + // or the Inclusions and Query (if true) + for (uint32_t i = 0; i < vector.Size(); ++i) + { + Microsoft::Management::Deployment::PackageMatchFilter filter = vector.GetAt(i); + + if (filter.Value().size() == 0) + { + // If the caller did not add a value it can't actually be used to filter or include anything so just ignore it. + continue; + } + ::AppInstaller::Repository::MatchType packageFieldMatchOption = GetRepositoryMatchType(filter.Option()); + ::AppInstaller::Repository::PackageMatchField matchField = GetRepositoryMatchField(filter.Field()); + + if (isSelector) + { + if (filter.Field() == Microsoft::Management::Deployment::PackageMatchField::CatalogDefault) + { + if (searchRequest->Query.has_value()) + { + // CatalogDefault match field can't be used twice. + return E_INVALIDARG; + } + searchRequest->Query = ::AppInstaller::Repository::RequestMatch(packageFieldMatchOption, winrt::to_string(filter.Value())); + } + else + { + auto matchFilter = ::AppInstaller::Repository::PackageMatchFilter(matchField, packageFieldMatchOption, winrt::to_string(filter.Value())); + searchRequest->Inclusions.emplace_back(matchFilter); + } + } + else + { + if (filter.Field() == Microsoft::Management::Deployment::PackageMatchField::CatalogDefault) + { + // CatalogDefault match fields can't be used in the Filters. + return E_INVALIDARG; + } + auto matchFilter = ::AppInstaller::Repository::PackageMatchFilter(matchField, packageFieldMatchOption, winrt::to_string(filter.Value())); + searchRequest->Filters.emplace_back(matchFilter); + } + } + return S_OK; + } + + HRESULT PopulateSearchRequest( + ::AppInstaller::Repository::SearchRequest* searchRequest, + winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options) + { + RETURN_IF_FAILED(PopulateSearchRequestFromVector(searchRequest, options.Filters(), false)); + RETURN_IF_FAILED(PopulateSearchRequestFromVector(searchRequest, options.Selectors(), true)); + return S_OK; + } + + winrt::Microsoft::Management::Deployment::FindPackagesResult PackageCatalog::FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options) + { + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::Ok; + bool isTruncated = false; + Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::MatchResult> matches{ winrt::single_threaded_vector<Microsoft::Management::Deployment::MatchResult>() }; + ::AppInstaller::Repository::SearchRequest searchRequest; + + HRESULT hr = PopulateSearchRequest(&searchRequest, options); + if (SUCCEEDED(hr)) + { + searchRequest.MaximumResults = options.ResultLimit(); + try + { + auto searchResult = m_source->Search(searchRequest); + + // Build the result object from the searchResult + for (size_t i = 0; i < searchResult.Matches.size(); ++i) + { + auto match = searchResult.Matches[i]; + auto catalogPackage = winrt::make_self<wil::details::module_count_wrapper< + winrt::Microsoft::Management::Deployment::implementation::CatalogPackage>>(); + catalogPackage->Initialize(m_source, match.Package); + + auto packageMatchFilter = winrt::make_self<wil::details::module_count_wrapper< + winrt::Microsoft::Management::Deployment::implementation::PackageMatchFilter>>(); + packageMatchFilter->Initialize(match.MatchCriteria); + + auto matchResult = winrt::make_self<wil::details::module_count_wrapper< + winrt::Microsoft::Management::Deployment::implementation::MatchResult>>(); + matchResult->Initialize(*catalogPackage, *packageMatchFilter); + + matches.Append(*matchResult); + } + isTruncated = searchResult.Truncated; + } + // Exceptions that may occur in the process of executing an arbitrary command + catch (const wil::ResultException& re) + { + hr = re.GetErrorCode(); + } + catch (const winrt::hresult_error& hre) + { + hr = hre.code(); + } + catch (const ::AppInstaller::Settings::GroupPolicyException&) + { + // Policy could have changed since server started. + hr = APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY; + } + catch (const std::exception&) + { + hr = APPINSTALLER_CLI_ERROR_COMMAND_FAILED; + } + catch (...) + { + hr = APPINSTALLER_CLI_ERROR_COMMAND_FAILED; + } + } + auto findPackagesResult = winrt::make_self<wil::details::module_count_wrapper< + winrt::Microsoft::Management::Deployment::implementation::FindPackagesResult>>(); + // TODO: Add search timeout and error code. + winrt::Microsoft::Management::Deployment::FindPackagesResultStatus status = FindPackagesResultStatus(hr); + findPackagesResult->Initialize(status, isTruncated, matches); + + return *findPackagesResult; + } +} diff --git a/src/Microsoft.Management.Deployment/PackageCatalog.h b/src/Microsoft.Management.Deployment/PackageCatalog.h @@ -0,0 +1,26 @@ +// 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> + { + PackageCatalog() = default; + void Initialize( + winrt::Microsoft::Management::Deployment::PackageCatalogInfo info, + std::shared_ptr<const ::AppInstaller::Repository::ISource> source, + bool isComposite); + + bool IsComposite(); + winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); + winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::FindPackagesResult> FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options); + winrt::Microsoft::Management::Deployment::FindPackagesResult FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options); + private: + winrt::Microsoft::Management::Deployment::PackageCatalogInfo m_info{ nullptr }; + std::shared_ptr<const ::AppInstaller::Repository::ISource> m_source; + bool m_isComposite = false; + + }; +} diff --git a/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp b/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <AppInstallerRepositorySource.h> +#include "PackageCatalogInfo.h" +#include "PackageCatalogInfo.g.cpp" +#include <wil\cppwinrt_wrl.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void PackageCatalogInfo::Initialize(const ::AppInstaller::Repository::SourceDetails& sourceDetails) + { + m_sourceDetails = sourceDetails; + } + ::AppInstaller::Repository::SourceDetails PackageCatalogInfo::GetSourceDetails() + { + return m_sourceDetails; + } + hstring PackageCatalogInfo::Id() + { + return winrt::to_hstring(m_sourceDetails.Identifier); + } + hstring PackageCatalogInfo::Name() + { + return winrt::to_hstring(m_sourceDetails.Name); + } + hstring PackageCatalogInfo::Type() + { + return winrt::to_hstring(m_sourceDetails.Type); + } + hstring PackageCatalogInfo::Argument() + { + return winrt::to_hstring(m_sourceDetails.Arg); + } + winrt::Windows::Foundation::DateTime PackageCatalogInfo::LastUpdateTime() + { + return winrt::clock::from_time_t(std::chrono::system_clock::to_time_t(m_sourceDetails.LastUpdateTime)); + } + winrt::Microsoft::Management::Deployment::PackageCatalogOrigin PackageCatalogInfo::Origin() + { + switch (m_sourceDetails.Origin) + { + case ::AppInstaller::Repository::SourceOrigin::Default : + case ::AppInstaller::Repository::SourceOrigin::Predefined: + return PackageCatalogOrigin::Predefined; + case ::AppInstaller::Repository::SourceOrigin::User: + case ::AppInstaller::Repository::SourceOrigin::GroupPolicy: + default: + return PackageCatalogOrigin::User; + } + } + winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel PackageCatalogInfo::TrustLevel() + { + switch (m_sourceDetails.TrustLevel) + { + case ::AppInstaller::Repository::SourceTrustLevel::Trusted: + return PackageCatalogTrustLevel::Trusted; + case ::AppInstaller::Repository::SourceTrustLevel::None: + default: + return PackageCatalogTrustLevel::None; + } + } +} diff --git a/src/Microsoft.Management.Deployment/PackageCatalogInfo.h b/src/Microsoft.Management.Deployment/PackageCatalogInfo.h @@ -0,0 +1,24 @@ +// 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> + { + PackageCatalogInfo() = default; + void Initialize(const ::AppInstaller::Repository::SourceDetails& sourceDetails); + ::AppInstaller::Repository::SourceDetails GetSourceDetails(); + + 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(); + private: + ::AppInstaller::Repository::SourceDetails m_sourceDetails{}; + }; +} diff --git a/src/Microsoft.Management.Deployment/PackageCatalogReference.cpp b/src/Microsoft.Management.Deployment/PackageCatalogReference.cpp @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <AppInstallerRepositorySource.h> +#include "PackageCatalogReference.h" +#include "PackageCatalogReference.g.cpp" +#include "PackageCatalogInfo.h" +#include "PackageCatalog.h" +#include "ConnectResult.h" +#include "Converters.h" +#include "Microsoft/PredefinedInstalledSourceFactory.h" +#include <wil\cppwinrt_wrl.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void PackageCatalogReference::Initialize(winrt::Microsoft::Management::Deployment::PackageCatalogInfo packageCatalogInfo) + { + m_info = packageCatalogInfo; + } + void PackageCatalogReference::Initialize(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions options) + { + m_compositePackageCatalogOptions = options; + m_isComposite = true; + } + bool PackageCatalogReference::IsComposite() + { + return m_isComposite; + } + winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalogReference::Info() + { + return m_info; + } + winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::ConnectResult> PackageCatalogReference::ConnectAsync() + { + co_return Connect(); + } + winrt::Microsoft::Management::Deployment::ConnectResult PackageCatalogReference::Connect() + { + ::AppInstaller::ProgressCallback progress; + std::shared_ptr<::AppInstaller::Repository::ISource> source; + if (m_compositePackageCatalogOptions) + { + std::vector<std::shared_ptr<::AppInstaller::Repository::ISource>> remoteSources; + + for (uint32_t i = 0; i < m_compositePackageCatalogOptions.Catalogs().Size(); ++i) + { + auto catalog = m_compositePackageCatalogOptions.Catalogs().GetAt(i); + winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo* catalogInfoImpl = get_self<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>(catalog.Info()); + ::AppInstaller::Repository::SourceDetails sourceDetails = catalogInfoImpl->GetSourceDetails(); + std::shared_ptr<::AppInstaller::Repository::ISource> remoteSource = ::AppInstaller::Repository::OpenSourceFromDetails(sourceDetails, 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. + auto connectResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::ConnectResult>>(); + connectResult->Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus::CatalogError, nullptr); + return *connectResult; + } + remoteSources.emplace_back(std::move(remoteSource)); + } + ::AppInstaller::Repository::CompositeSearchBehavior searchBehavior = GetRepositoryCompositeSearchBehavior(m_compositePackageCatalogOptions.CompositeSearchBehavior()); + + std::shared_ptr<::AppInstaller::Repository::ISource> installedSource; + // Check if search behavior indicates that the caller does not want to do local correlation. + if (m_compositePackageCatalogOptions.CompositeSearchBehavior() != Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromRemoteCatalogs) + { + installedSource = ::AppInstaller::Repository::OpenPredefinedSource(::AppInstaller::Repository::PredefinedSource::Installed, progress); + } + + // Create the composite source. + source = ::AppInstaller::Repository::CreateCompositeSource(installedSource, remoteSources, searchBehavior); + } + else + { + winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo* catalogInfoImpl = get_self<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>(m_info); + ::AppInstaller::Repository::SourceDetails sourceDetails = catalogInfoImpl->GetSourceDetails(); + source = ::AppInstaller::Repository::OpenSourceFromDetails(sourceDetails, progress).Source; + } + + if (!source) + { + // If source is null, return the error. There's no way to get the hresult that caused the error right now. + auto connectResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::ConnectResult>>(); + connectResult->Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus::CatalogError, nullptr); + return *connectResult; + } + + // Have to make another package catalog info because source->GetDetails has more fields than m_info does. + // Specifically, Rest sources do not have the Ids filled in m_info since they only get the id from the rest server after being Opened. + auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>(); + packageCatalogInfo->Initialize(source->GetDetails()); + auto connectResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::ConnectResult>>(); + auto packageCatalog = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalog>>(); + packageCatalog->Initialize(*packageCatalogInfo, source, (m_compositePackageCatalogOptions != nullptr)); + connectResult->Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus::Ok, *packageCatalog); + return *connectResult; + } +} diff --git a/src/Microsoft.Management.Deployment/PackageCatalogReference.h b/src/Microsoft.Management.Deployment/PackageCatalogReference.h @@ -0,0 +1,23 @@ +// 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> + { + PackageCatalogReference() = default; + void Initialize(winrt::Microsoft::Management::Deployment::PackageCatalogInfo packageCatalogInfo); + void Initialize(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions options); + + bool IsComposite(); + winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info(); + winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::ConnectResult> ConnectAsync(); + winrt::Microsoft::Management::Deployment::ConnectResult Connect(); + private: + winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions m_compositePackageCatalogOptions{ nullptr }; + winrt::Microsoft::Management::Deployment::PackageCatalogInfo m_info{ nullptr }; + bool m_isComposite = false; + }; +} diff --git a/src/Microsoft.Management.Deployment/PackageManager.cpp b/src/Microsoft.Management.Deployment/PackageManager.cpp @@ -0,0 +1,318 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "Public/AppInstallerCLICore.h" +#include "Microsoft/PredefinedInstalledSourceFactory.h" +#include "Commands/RootCommand.h" +#include "ComContext.h" +#include "ExecutionContext.h" +#include "Workflows/WorkflowBase.h" +#include <winget/UserSettings.h> +#include "Commands/InstallCommand.h" +#include <AppInstallerTelemetry.h> +#include <AppInstallerErrors.h> +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +// 6388 Allow CreateInstance. +#include <wil\cppwinrt_wrl.h> +// 4467 Allow use of uuid attribute for com object creation. +#include "PackageManager.h" +#pragma warning( pop ) +#include "PackageManager.g.cpp" +#include "InstallResult.h" +#include "PackageCatalogInfo.h" +#include "PackageCatalogReference.h" +#include "PackageVersionInfo.h" +#include "PackageVersionId.h" +#include "Converters.h" +#include "Helpers.h" + +using namespace std::literals::chrono_literals; + +const GUID PackageManagerCLSID1 = { 0xC53A4F16, 0x787E, 0x42A4, { 0xB3, 0x04, 0x29, 0xEF, 0xFB, 0x4B, 0xF5, 0x97 } }; //C53A4F16-787E-42A4-B304-29EFFB4BF597 +const GUID PackageManagerCLSID2 = { 0xE65C7D5A, 0x95AF, 0x4A98, { 0xBE, 0x5F, 0xA7, 0x93, 0x02, 0x9C, 0xEB, 0x56 } }; //E65C7D5A-95AF-4A98-BE5F-A793029CEB56 + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageCatalogReference> PackageManager::GetPackageCatalogs() + { + Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageCatalogReference> catalogs{ winrt::single_threaded_vector<Microsoft::Management::Deployment::PackageCatalogReference>() }; + std::vector<::AppInstaller::Repository::SourceDetails> sources = ::AppInstaller::Repository::GetSources(); + for (uint32_t i = 0; i < sources.size(); i++) + { + auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>(); + packageCatalogInfo->Initialize(sources.at(i)); + auto packageCatalogRef = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>(); + packageCatalogRef->Initialize(*packageCatalogInfo); + catalogs.Append(*packageCatalogRef); + } + return catalogs.GetView(); + } + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog) + { + ::AppInstaller::Repository::SourceDetails sourceDetails; + switch (predefinedPackageCatalog) + { + case winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog::OpenWindowsCatalog: + { + sourceDetails = GetWellKnownSourceDetails(::AppInstaller::Repository::WellKnownSource::WinGet); + auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>(); + packageCatalogInfo->Initialize(sourceDetails); + auto packageCatalogRef = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>(); + packageCatalogRef->Initialize(*packageCatalogInfo); + return *packageCatalogRef; + } + default: + throw hresult_invalid_argument(); + } + } + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetLocalPackageCatalog(winrt::Microsoft::Management::Deployment::LocalPackageCatalog const& localPackageCatalog) + { + // InstalledPackages is the only one supported right now, so return early if it's not that. + if(localPackageCatalog != Microsoft::Management::Deployment::LocalPackageCatalog::InstalledPackages) + { + throw hresult_invalid_argument(); + } + ::AppInstaller::Repository::SourceDetails sourceDetails = GetPredefinedSourceDetails(::AppInstaller::Repository::PredefinedSource::Installed); + auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>(); + packageCatalogInfo->Initialize(sourceDetails); + auto packageCatalogImpl = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>(); + packageCatalogImpl->Initialize(*packageCatalogInfo); + return *packageCatalogImpl; + } + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPackageCatalogByName(hstring const& catalogName) + { + std::optional<::AppInstaller::Repository::SourceDetails> source = ::AppInstaller::Repository::GetSource(winrt::to_string(catalogName)); + // Create the catalog object if the source is found, otherwise return null. Don't throw. + if (source.has_value()) + { + auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>(); + packageCatalogInfo->Initialize(source.value()); + auto packageCatalogRef = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>(); + packageCatalogRef->Initialize(*packageCatalogInfo); + return *packageCatalogRef; + } + else + { + return nullptr; + } + } + winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options) + { + for (uint32_t i = 0; i < options.Catalogs().Size(); ++i) + { + auto catalog = options.Catalogs().GetAt(i); + if (catalog.IsComposite()) + { + // Can't make a composite source out of a source that's already a composite. + throw hresult_invalid_argument(); + } + } + auto packageCatalogImpl = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>(); + packageCatalogImpl->Initialize(options); + return *packageCatalogImpl; + } + + Windows::Foundation::IAsyncAction ExecuteInstallAsync(::AppInstaller::CLI::Execution::Context& context, std::unique_ptr<::AppInstaller::CLI::Command>& command) + { + co_await winrt::resume_background(); + ::AppInstaller::CLI::Execute(context, command); + } + winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress> PackageManager::InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options) + { + auto report_progress{ co_await winrt::get_progress_token() }; + auto cancellationToken{ co_await winrt::get_cancellation_token() }; + + InstallProgress queuedProgress{ PackageInstallProgressState::Queued, 0, 0, 0 }; + report_progress(queuedProgress); + + Microsoft::Management::Deployment::PackageVersionId versionId{ nullptr }; + if (options) + { + versionId = options.PackageVersionId(); + } + + // If the version of the package is specified use that, otherwise use the default. + Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo{ nullptr }; + if (versionId) + { + packageVersionInfo = package.GetPackageVersionInfo(versionId); + } + else + { + packageVersionInfo = package.DefaultInstallVersion(); + } + + if (!packageVersionInfo) + { + // If no package version was found on the catalog then return a failure. This is unexpected, a catalog with no latest version should not be in the catalog. + HRESULT terminationHR = APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER; + winrt::Microsoft::Management::Deployment::InstallResultStatus installResultStatus = GetInstallResultStatus(terminationHR); + auto installResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::InstallResult>>(); + installResult->Initialize(installResultStatus, terminationHR, options.CorrelationData(), false); + co_return *installResult; + } + + // Handle the progress from the installer + ::AppInstaller::COMContext context; + + // TODO: Exact ComCaller's process name needs to be retrieved from COM Client side in the future + context.SetLoggerContext(options.CorrelationData(), "COMCaller"); + + context.SetProgressCallbackFunction([=]( + ::AppInstaller::ReportType reportType, + uint64_t current, + uint64_t maximum, + ::AppInstaller::ProgressType progressType, + ::AppInstaller::CLI::Workflow::ExecutionStage executionPhase) + { + bool reportProgress = false; + PackageInstallProgressState progressState = PackageInstallProgressState::Queued; + double downloadProgress = 0; + double installProgress = 0; + uint64_t downloadBytesDownloaded = 0; + uint64_t downloadBytesRequired = 0; + switch (executionPhase) + { + case ::AppInstaller::CLI::Workflow::ExecutionStage::Initial: + case ::AppInstaller::CLI::Workflow::ExecutionStage::ParseArgs: + case ::AppInstaller::CLI::Workflow::ExecutionStage::Discovery: + // We already reported queued progress up front. + break; + case ::AppInstaller::CLI::Workflow::ExecutionStage::Download: + progressState = PackageInstallProgressState::Downloading; + if (reportType == ::AppInstaller::ReportType::BeginProgress) + { + reportProgress = true; + } + else if (progressType == ::AppInstaller::ProgressType::Bytes) + { + downloadBytesDownloaded = current; + downloadBytesRequired = maximum; + if (maximum > 0 && maximum >= current) + { + reportProgress = true; + downloadProgress = static_cast<double>(current) / static_cast<double>(maximum); + } + } + break; + case ::AppInstaller::CLI::Workflow::ExecutionStage::PreExecution: + // Wait until installer starts to report Installing. + break; + case ::AppInstaller::CLI::Workflow::ExecutionStage::Execution: + progressState = PackageInstallProgressState::Installing; + downloadProgress = 1; + if (reportType == ::AppInstaller::ReportType::ExecutionPhaseUpdate) + { + // Install is starting. Send progress so callers know the AsyncOperation can't be cancelled. + reportProgress = true; + } + else if (reportType == ::AppInstaller::ReportType::EndProgress) + { + // Install is "finished". May not have succeeded. + reportProgress = true; + installProgress = 1; + } + else if (progressType == ::AppInstaller::ProgressType::Percent) + { + if (maximum > 0 && maximum >= current) + { + // Install is progressing + reportProgress = true; + installProgress = static_cast<double>(current) / static_cast<double>(maximum); + } + } + break; + case ::AppInstaller::CLI::Workflow::ExecutionStage::PostExecution: + if (reportType == ::AppInstaller::ReportType::ExecutionPhaseUpdate) + { + // Send PostInstall progress when it switches to PostExecution phase. + reportProgress = true; + progressState = PackageInstallProgressState::PostInstall; + downloadProgress = 1; + installProgress = 1; + } + break; + } + if (reportProgress) + { + winrt::Microsoft::Management::Deployment::InstallProgress contextProgress{ progressState, downloadBytesDownloaded, downloadBytesRequired, downloadProgress, installProgress }; + report_progress(contextProgress); + } + return; + } + ); + context.EnableCtrlHandler(); + + // Convert the options to arguments for the installer. + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Id, ::AppInstaller::Utility::ConvertToUTF8(package.Id())); + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Version, ::AppInstaller::Utility::ConvertToUTF8(packageVersionInfo.Version())); + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Channel, ::AppInstaller::Utility::ConvertToUTF8(packageVersionInfo.Channel())); + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Source, ::AppInstaller::Utility::ConvertToUTF8(packageVersionInfo.PackageCatalog().Info().Name())); + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Exact); + if (options) + { + if (!options.LogOutputPath().empty()) + { + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Log, ::AppInstaller::Utility::ConvertToUTF8(options.LogOutputPath())); + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::VerboseLogs); + } + if (options.AllowHashMismatch()) + { + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::HashOverride); + } + + // If the PackageInstallScope is anything other than ::Any then set it as a requirement. + if (options.PackageInstallScope() == PackageInstallScope::System) + { + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::InstallScope, ScopeToString(::AppInstaller::Manifest::ScopeEnum::Machine)); + } + else if (options.PackageInstallScope() == PackageInstallScope::User) + { + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::InstallScope, ScopeToString(::AppInstaller::Manifest::ScopeEnum::User)); + } + + if (options.PackageInstallMode() == PackageInstallMode::Interactive) + { + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Interactive); + } + else if (options.PackageInstallMode() == PackageInstallMode::Silent) + { + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Silent); + } + + if (!options.PreferredInstallLocation().empty()) + { + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::InstallLocation, ::AppInstaller::Utility::ConvertToUTF8(options.PreferredInstallLocation())); + } + + if (!options.ReplacementInstallerArguments().empty()) + { + context.Args.AddArg(::AppInstaller::CLI::Execution::Args::Type::Override, ::AppInstaller::Utility::ConvertToUTF8(options.ReplacementInstallerArguments())); + } + } + + // TODO: AdditionalPackageCatalogArguments is not currently supported by the underlying implementation. + ::AppInstaller::CLI::RootCommand rootCommand; + std::unique_ptr<::AppInstaller::CLI::Command> command = std::make_unique<::AppInstaller::CLI::InstallCommand>(rootCommand.Name()); + Windows::Foundation::IAsyncAction executeOperation = ExecuteInstallAsync(context, command); + + cancellationToken.callback([&context] + { + context.Terminate(APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED); + }); + // Wait for the execute operation to finish. + // The cancellation of the AsyncOperation triggers Terminate which causes the executeOperation to end. + co_await executeOperation; + + HRESULT terminationHR = context.GetTerminationHR(); + winrt::Microsoft::Management::Deployment::InstallResultStatus installResultStatus = GetInstallResultStatus(terminationHR); + + // TODO - RebootRequired not yet populated, msi arguments not returned from Execute. + auto installResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::InstallResult>>(); + installResult->Initialize(installResultStatus, terminationHR, options.CorrelationData(), false); + co_return *installResult; + } + CoCreatableCppWinRtClassWithCLSID(PackageManager, 1, &PackageManagerCLSID1); + CoCreatableCppWinRtClassWithCLSID(PackageManager, 2, &PackageManagerCLSID2); +} diff --git a/src/Microsoft.Management.Deployment/PackageManager.h b/src/Microsoft.Management.Deployment/PackageManager.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageManager.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + [uuid("C53A4F16-787E-42A4-B304-29EFFB4BF597")] + struct PackageManager : PackageManagerT<PackageManager> + { + PackageManager() = default; + + winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageCatalogReference> 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<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress> + InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options); + winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress> + GetInstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package); + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct PackageManager : PackageManagerT<PackageManager, implementation::PackageManager> + { + }; +} diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -0,0 +1,536 @@ +// 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<String> PackageFamilyNames { get; }; + Windows.Foundation.Collections.IVectorView<String> 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<PackageVersionId> 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<MatchResult> 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<PackageMatchFilter> 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<PackageMatchFilter> 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<FindPackagesResult> 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<ConnectResult> 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<PackageCatalogReference> 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<PackageCatalogReference> 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<InstallResult, InstallProgress> InstallPackageAsync(CatalogPackage package, InstallOptions options); + } + + /// Force midl3 to generate vector marshalling info. + declare + { + interface Windows.Foundation.Collections.IVector<PackageCatalog>; + interface Windows.Foundation.Collections.IVectorView<PackageCatalog>; + interface Windows.Foundation.Collections.IVector<PackageCatalogInfo>; + interface Windows.Foundation.Collections.IVectorView<PackageCatalogInfo>; + interface Windows.Foundation.Collections.IVector<PackageCatalogReference>; + interface Windows.Foundation.Collections.IVectorView<PackageCatalogReference>; + interface Windows.Foundation.Collections.IVector<CatalogPackage>; + interface Windows.Foundation.Collections.IVectorView<CatalogPackage>; + interface Windows.Foundation.Collections.IVector<FindPackagesOptions>; + interface Windows.Foundation.Collections.IVectorView<FindPackagesOptions>; + interface Windows.Foundation.Collections.IVector<FindPackagesResult>; + interface Windows.Foundation.Collections.IVectorView<FindPackagesResult>; + interface Windows.Foundation.Collections.IVector<CreateCompositePackageCatalogOptions>; + interface Windows.Foundation.Collections.IVectorView<CreateCompositePackageCatalogOptions>; + interface Windows.Foundation.Collections.IVector<InstallOptions>; + interface Windows.Foundation.Collections.IVectorView<InstallOptions>; + interface Windows.Foundation.Collections.IVector<InstallResult>; + interface Windows.Foundation.Collections.IVectorView<InstallResult>; + interface Windows.Foundation.Collections.IVector<MatchResult>; + interface Windows.Foundation.Collections.IVectorView<MatchResult>; + interface Windows.Foundation.Collections.IVector<PackageMatchFilter>; + interface Windows.Foundation.Collections.IVectorView<PackageMatchFilter>; + interface Windows.Foundation.Collections.IVector<PackageVersionId>; + interface Windows.Foundation.Collections.IVectorView<PackageVersionId>; + interface Windows.Foundation.Collections.IVector<PackageVersionInfo>; + interface Windows.Foundation.Collections.IVectorView<PackageVersionInfo>; + } +} diff --git a/src/Microsoft.Management.Deployment/PackageMatchFilter.cpp b/src/Microsoft.Management.Deployment/PackageMatchFilter.cpp @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <AppInstallerRepositorySource.h> +#include <AppInstallerRepositorySearch.h> +#include "Converters.h" +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +// 6388 Allow CreateInstance. +#include <wil\cppwinrt_wrl.h> +// 4467 Allow use of uuid attribute for com object creation. +#include "PackageMatchFilter.h" +#pragma warning( pop ) +#include "PackageMatchFilter.g.cpp" +#include "Helpers.h" + +const GUID PackageMatchFilterCLSID1 = { 0xD02C9DAF, 0x99DC, 0x429C, { 0xB5, 0x03, 0x4E, 0x50, 0x4E, 0x4A, 0xB0, 0x00 } }; //D02C9DAF-99DC-429C-B503-4E504E4AB000 +const GUID PackageMatchFilterCLSID2 = { 0xADBF3B4A, 0xDB8A, 0x496C, { 0xA5, 0x79, 0x62, 0xB5, 0x8F, 0x5F, 0xB1, 0x3F } }; //ADBF3B4A-DB8A-496C-A579-62B58F5FB13F + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void PackageMatchFilter::Initialize(::AppInstaller::Repository::PackageMatchFilter matchFilter) + { + m_value = winrt::to_hstring(matchFilter.Value); + m_matchField = GetDeploymentMatchField(matchFilter.Field); + m_packageFieldMatchOption = GetDeploymentMatchOption(matchFilter.Type); + } + winrt::Microsoft::Management::Deployment::PackageFieldMatchOption PackageMatchFilter::Option() + { + return m_packageFieldMatchOption; + } + void PackageMatchFilter::Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value) + { + m_packageFieldMatchOption = value; + } + winrt::Microsoft::Management::Deployment::PackageMatchField PackageMatchFilter::Field() + { + return m_matchField; + } + void PackageMatchFilter::Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value) + { + m_matchField = value; + } + hstring PackageMatchFilter::Value() + { + return hstring(m_value); + } + void PackageMatchFilter::Value(hstring const& value) + { + m_value = value; + } + CoCreatableCppWinRtClassWithCLSID(PackageMatchFilter, 1, &PackageMatchFilterCLSID1); + CoCreatableCppWinRtClassWithCLSID(PackageMatchFilter, 2, &PackageMatchFilterCLSID2); +} diff --git a/src/Microsoft.Management.Deployment/PackageMatchFilter.h b/src/Microsoft.Management.Deployment/PackageMatchFilter.h @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "PackageMatchFilter.g.h" + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + [uuid("D02C9DAF-99DC-429C-B503-4E504E4AB000")] + struct PackageMatchFilter : PackageMatchFilterT<PackageMatchFilter> + { + PackageMatchFilter() = default; + void Initialize(::AppInstaller::Repository::PackageMatchFilter matchFilter); + + 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: + 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; + }; +} +namespace winrt::Microsoft::Management::Deployment::factory_implementation +{ + struct PackageMatchFilter : PackageMatchFilterT<PackageMatchFilter, implementation::PackageMatchFilter> + { + }; +} diff --git a/src/Microsoft.Management.Deployment/PackageVersionId.cpp b/src/Microsoft.Management.Deployment/PackageVersionId.cpp @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <AppInstallerRepositorySource.h> +#include "PackageVersionId.h" +#include "PackageVersionId.g.cpp" +#include <wil\cppwinrt_wrl.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void PackageVersionId::Initialize(::AppInstaller::Repository::PackageVersionKey packageVersionKey) + { + m_packageVersionKey = packageVersionKey; + } + hstring PackageVersionId::PackageCatalogId() + { + return winrt::to_hstring(m_packageVersionKey.SourceId); + } + hstring PackageVersionId::Version() + { + return winrt::to_hstring(m_packageVersionKey.Version); + } + hstring PackageVersionId::Channel() + { + return winrt::to_hstring(m_packageVersionKey.Channel); + } +} diff --git a/src/Microsoft.Management.Deployment/PackageVersionId.h b/src/Microsoft.Management.Deployment/PackageVersionId.h @@ -0,0 +1,19 @@ +// 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> + { + PackageVersionId() = default; + void Initialize(::AppInstaller::Repository::PackageVersionKey packageVersionKey); + + hstring PackageCatalogId(); + hstring Version(); + hstring Channel(); + private: + ::AppInstaller::Repository::PackageVersionKey m_packageVersionKey{}; + }; +} diff --git a/src/Microsoft.Management.Deployment/PackageVersionInfo.cpp b/src/Microsoft.Management.Deployment/PackageVersionInfo.cpp @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include <mutex> +#include <AppInstallerRepositorySource.h> +#include "PackageVersionInfo.h" +#include "PackageVersionInfo.g.cpp" +#include "PackageCatalogInfo.h" +#include "PackageCatalog.h" +#include "CatalogPackage.h" +#include "Converters.h" +#include <wil\cppwinrt_wrl.h> + +namespace winrt::Microsoft::Management::Deployment::implementation +{ + void PackageVersionInfo::Initialize(std::shared_ptr<::AppInstaller::Repository::IPackageVersion> packageVersion) + { + m_packageVersion = std::move(packageVersion); + } + hstring PackageVersionInfo::GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField) + { + ::AppInstaller::Repository::PackageVersionMetadata metadataKey = GetRepositoryPackageVersionMetadata(metadataField); + ::AppInstaller::Repository::IPackageVersion::Metadata metadata = m_packageVersion->GetMetadata(); + auto result = metadata.find(metadataKey); + hstring resultString = winrt::to_hstring(result->second); + // The api uses "System" rather than "Machine" for install scope. + if (metadataField == PackageVersionMetadataField::InstalledScope && resultString == L"Machine") + { + return winrt::to_hstring(L"System"); + } + return resultString; + } + hstring PackageVersionInfo::Id() + { + return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Id).get()); + } + hstring PackageVersionInfo::DisplayName() + { + return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Name).get()); + } + hstring PackageVersionInfo::Version() + { + return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Version).get()); + } + hstring PackageVersionInfo::Channel() + { + return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Channel).get()); + } + winrt::Windows::Foundation::Collections::IVectorView<hstring> PackageVersionInfo::PackageFamilyNames() + { + if (!m_packageFamilyNames) + { + // Vector hasn't been created yet, create and populate it. + auto packageFamilyNames = winrt::single_threaded_vector<hstring>(); + for (auto&& string : m_packageVersion->GetMultiProperty(::AppInstaller::Repository::PackageVersionMultiProperty::PackageFamilyName)) + { + packageFamilyNames.Append(winrt::to_hstring(string)); + } + m_packageFamilyNames = packageFamilyNames; + } + return m_packageFamilyNames.GetView(); + } + winrt::Windows::Foundation::Collections::IVectorView<hstring> PackageVersionInfo::ProductCodes() + { + if (!m_productCodes) + { + // Vector hasn't been created yet, create and populate it. + auto productCodes = winrt::single_threaded_vector<hstring>(); + for (auto&& string : m_packageVersion->GetMultiProperty(::AppInstaller::Repository::PackageVersionMultiProperty::ProductCode)) + { + productCodes.Append(winrt::to_hstring(string)); + } + m_productCodes = productCodes; + } + return m_productCodes.GetView(); + } + winrt::Microsoft::Management::Deployment::PackageCatalog PackageVersionInfo::PackageCatalog() + { + if (!m_packageCatalog) + { + auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>(); + packageCatalogInfo->Initialize(m_packageVersion->GetSource()->GetDetails()); + auto packageCatalog = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalog>>(); + packageCatalog->Initialize(*packageCatalogInfo, m_packageVersion->GetSource(), false); + m_packageCatalog = *packageCatalog; + } + return m_packageCatalog; + } +} diff --git a/src/Microsoft.Management.Deployment/PackageVersionInfo.h b/src/Microsoft.Management.Deployment/PackageVersionInfo.h @@ -0,0 +1,27 @@ +// 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> + { + PackageVersionInfo() = default; + void Initialize(std::shared_ptr<::AppInstaller::Repository::IPackageVersion> packageVersion); + + hstring GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField); + hstring Id(); + hstring DisplayName(); + hstring Version(); + hstring Channel(); + winrt::Windows::Foundation::Collections::IVectorView<hstring> PackageFamilyNames(); + winrt::Windows::Foundation::Collections::IVectorView<hstring> ProductCodes(); + winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog(); + private: + winrt::Microsoft::Management::Deployment::PackageCatalog m_packageCatalog{ nullptr }; + std::shared_ptr<::AppInstaller::Repository::IPackageVersion> m_packageVersion; + Windows::Foundation::Collections::IVector<hstring> m_packageFamilyNames{ nullptr }; + Windows::Foundation::Collections::IVector<hstring> m_productCodes{ nullptr }; + }; +} diff --git a/src/Microsoft.Management.Deployment/PropertySheet.props b/src/Microsoft.Management.Deployment/PropertySheet.props @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <!-- + To customize common C++/WinRT project properties: + * right-click the project node + * expand the Common Properties item + * select the C++/WinRT property page + + For more advanced scenarios, and complete documentation, please see: + https://github.com/Microsoft/cppwinrt/tree/master/nuget + --> + <PropertyGroup /> + <ItemDefinitionGroup /> +</Project>+ \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/packages.config b/src/Microsoft.Management.Deployment/packages.config @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Microsoft.Windows.CppWinRT" version="2.0.210505.3" targetFramework="native" /> + <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" /> +</packages>+ \ No newline at end of file diff --git a/src/Microsoft.Management.Deployment/pch.cpp b/src/Microsoft.Management.Deployment/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/pch.h b/src/Microsoft.Management.Deployment/pch.h @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include <unknwn.h> +#include <winrt/Windows.Foundation.h> +#include <winrt/Windows.Foundation.Collections.h> diff --git a/src/WinGetServer/PropertySheet.props b/src/WinGetServer/PropertySheet.props @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <!-- + To customize common C++/WinRT project properties: + * right-click the project node + * expand the Common Properties item + * select the C++/WinRT property page + + For more advanced scenarios, and complete documentation, please see: + https://github.com/Microsoft/cppwinrt/tree/master/nuget + --> + <PropertyGroup /> + <ItemDefinitionGroup /> +</Project>+ \ No newline at end of file diff --git a/src/WinGetServer/WinGetServer.exe.manifest b/src/WinGetServer/WinGetServer.exe.manifest @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +</assembly>+ \ No newline at end of file diff --git a/src/WinGetServer/WinGetServer.rc b/src/WinGetServer/WinGetServer.rc Binary files differ. diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj @@ -0,0 +1,176 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" /> + <PropertyGroup Label="Globals"> + <CppWinRTOptimized>true</CppWinRTOptimized> + <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge> + <CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata> + <MinimalCoreWin>true</MinimalCoreWin> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{2b00d362-ac92-41f3-a8d2-5b1599bdca01}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>WinGetServer</RootNamespace> + <WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion> + <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion> + <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport> + <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support> + <ProjectName>WinGetServer</ProjectName> + <TargetName>WindowsPackageManagerServer</TargetName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset> + <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration"> + <UseDebugLibraries>true</UseDebugLibraries> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration"> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <LinkIncremental>false</LinkIncremental> + <SpectreMitigation>Spectre</SpectreMitigation> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="PropertySheet.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <OutDir>$(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> + <LibraryPath>$(OutDir)..\Microsoft.Management.Deployment;$(OutDir)..\AppInstallerCLICore;$(OutDir)..\JsonCppLib;$(OutDir)..\AppInstallerRepositoryCore;$(OutDir)..\YamlCppLib;$(OutDir)..\AppInstallerCommonCore;$(OutDir)..\cpprestsdk;$(LibraryPath)</LibraryPath> + <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors> + <RunCodeAnalysis>false</RunCodeAnalysis> + <CodeAnalysisRuleSet>..\CodeAnalysis.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile> + <PreprocessorDefinitions>_CONSOLE;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <WarningLevel>Level4</WarningLevel> + <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj</AdditionalOptions> + <TreatWarningAsError>true</TreatWarningAsError> + <SDLCheck>true</SDLCheck> + <EnablePREfast>true</EnablePREfast> + <AdditionalIncludeDirectories>$(ProjectDir)..\AppInstallerCLICore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerRepositoryCore\Public;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\JsonCppLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <AdditionalLibraryDirectories>$(OutDir)..\Microsoft.Management.Deployment;$(OutDir)..\AppInstallerCLICore;$(OutDir)..\JsonCppLib;$(OutDir)..\AppInstallerRepositoryCore;$(OutDir)..\YamlCppLib;$(OutDir)..\AppInstallerCommonCore;$(OutDir)..\cpprestsdk;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>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)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'"> + <ClCompile> + <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="resource.h" /> + <ClCompile Include="WinMain.cpp" /> + <ResourceCompile Include="WinGetServer.rc" /> + <Manifest Include="WinGetServer.exe.manifest" /> + <None Include="packages.config" /> + <None Include="PropertySheet.props" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\AppInstallerCommonCore\AppInstallerCommonCore.vcxproj"> + <Project>{5890d6ed-7c3b-40f3-b436-b54f640d9e65}</Project> + </ProjectReference> + <ProjectReference Include="..\AppInstallerRepositoryCore\AppInstallerRepositoryCore.vcxproj"> + <Project>{5eb88068-5fb9-4e69-89b2-72dbc5e068f9}</Project> + </ProjectReference> + <ProjectReference Include="..\cpprestsdk\cpprestsdk.vcxproj"> + <Project>{866c3f06-636f-4be8-bc24-5f86ecc606a1}</Project> + </ProjectReference> + <ProjectReference Include="..\JsonCppLib\JsonCppLib.vcxproj"> + <Project>{82b39fda-e86b-4713-a873-9d56de00247a}</Project> + </ProjectReference> + <ProjectReference Include="..\YamlCppLib\YamlCppLib.vcxproj"> + <Project>{8bb94bb8-374f-4294-bca1-c7811514a6b7}</Project> + </ProjectReference> + <ProjectReference Include="..\Microsoft.Management.Deployment\Microsoft.Management.Deployment.vcxproj"> + <Project>{1cc41a9a-ae66-459d-9210-1e572dd7be69}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> + </ImportGroup> + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> + <PropertyGroup> + <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> + </PropertyGroup> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets'))" /> + </Target> +</Project>+ \ No newline at end of file diff --git a/src/WinGetServer/WinGetServer.vcxproj.filters b/src/WinGetServer/WinGetServer.vcxproj.filters @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="WinMain.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="PropertySheet.props" /> + <None Include="packages.config" /> + </ItemGroup> + <ItemGroup> + <Manifest Include="WinGetServer.exe.manifest" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="WinGetServer.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>+ \ No newline at end of file diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include <winrt/Microsoft.Management.Deployment.h> +#include <wrl/module.h> +#include <winget/ExperimentalFeature.h> +#include <winget/GroupPolicy.h> +#include "COMContext.h" + +using namespace winrt::Microsoft::Management::Deployment; + +CoCreatableClassWrlCreatorMapInclude(PackageManager1); +CoCreatableClassWrlCreatorMapInclude(PackageManager2); +CoCreatableClassWrlCreatorMapInclude(FindPackagesOptions1); +CoCreatableClassWrlCreatorMapInclude(FindPackagesOptions2); +CoCreatableClassWrlCreatorMapInclude(CreateCompositePackageCatalogOptions1); +CoCreatableClassWrlCreatorMapInclude(CreateCompositePackageCatalogOptions2); +CoCreatableClassWrlCreatorMapInclude(InstallOptions1); +CoCreatableClassWrlCreatorMapInclude(InstallOptions2); +CoCreatableClassWrlCreatorMapInclude(PackageMatchFilter1); +CoCreatableClassWrlCreatorMapInclude(PackageMatchFilter2); + +// Holds the wwinmain open until COM tells us there are no more server connections +wil::unique_event _comServerExitEvent; + +// Routine Description: +// - Called back when COM says there is nothing left for our server to do and we can tear down. +static void _releaseNotifier() noexcept +{ + _comServerExitEvent.SetEvent(); +} + +// Check whether the packaged api is enabled and the overarching winget group policy is enabled. +bool IsServerEnabled() +{ + if (!::AppInstaller::Settings::ExperimentalFeature::IsEnabled(::AppInstaller::Settings::ExperimentalFeature::Feature::PackagedAPI)) + { + return false; + } + if (!::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::WinGet)) + { + return false; + } + + return true; +} + +int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int) +{ + winrt::init_apartment(); + + // Enable fast rundown of objects so that the server exits faster when clients go away. + { + winrt::com_ptr<IGlobalOptions> globalOptions; + winrt::check_hresult(CoCreateInstance(CLSID_GlobalOptions, nullptr, CLSCTX_INPROC, IID_PPV_ARGS(&globalOptions))); + winrt::check_hresult(globalOptions->Set(COMGLB_RO_SETTINGS, COMGLB_FAST_RUNDOWN)); + } + + AppInstaller::COMContext::SetLoggers(); + + _comServerExitEvent.create(); + auto& module = ::Microsoft::WRL::Module<::Microsoft::WRL::ModuleType::OutOfProc>::Create(&_releaseNotifier); + try + { + if (!IsServerEnabled()) + { + return 0; + } + + // Register all the CoCreatableClassWrlCreatorMapInclude classes + RETURN_IF_FAILED(module.RegisterObjects()); + _comServerExitEvent.wait(); + RETURN_IF_FAILED(module.UnregisterObjects()); + + } + CATCH_RETURN() + + return 0; +} diff --git a/src/WinGetServer/packages.config b/src/WinGetServer/packages.config @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Microsoft.Windows.CppWinRT" version="2.0.210505.3" targetFramework="native" /> + <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" /> +</packages>+ \ No newline at end of file diff --git a/src/WinGetServer/resource.h b/src/WinGetServer/resource.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/WinGetUtil/WinGetUtil.vcxproj b/src/WinGetUtil/WinGetUtil.vcxproj @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" /> <PropertyGroup Label="Globals"> <CppWinRTOptimized>true</CppWinRTOptimized> <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge> @@ -316,15 +316,15 @@ </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" /> - <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" /> </ImportGroup> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" /> - <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.props'))" /> + <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.210505.3\build\native\Microsoft.Windows.CppWinRT.targets'))" /> </Target> </Project> \ No newline at end of file diff --git a/src/WinGetUtil/packages.config b/src/WinGetUtil/packages.config @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" /> - <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200519.2" targetFramework="native" /> + <package id="Microsoft.Windows.CppWinRT" version="2.0.210505.3" targetFramework="native" /> + <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" /> </packages> \ No newline at end of file