PackageVersionInfo.cpp (10131B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include <mutex> 5 #include <winget/RepositorySource.h> 6 #include "PackageVersionInfo.h" 7 #include "PackageVersionInfo.g.cpp" 8 #include "PackageCatalogInfo.h" 9 #include "PackageCatalog.h" 10 #include "PackageInstallerInfo.h" 11 #include "CatalogPackage.h" 12 #include "CatalogPackageMetadata.h" 13 #include "ComContext.h" 14 #include "Workflows/WorkflowBase.h" 15 #include <winget/ManifestComparator.h> 16 #include "winget/RepositorySearch.h" 17 #include "AppInstallerVersions.h" 18 #include "Converters.h" 19 #pragma warning( push ) 20 #pragma warning ( disable : 4467 ) 21 // 4467 Allow use of uuid attribute for com object creation. 22 #include "PackageManager.h" 23 #pragma warning( pop ) 24 #include <wil\cppwinrt_wrl.h> 25 #include <winget/Locale.h> 26 27 namespace winrt::Microsoft::Management::Deployment::implementation 28 { 29 namespace 30 { 31 // Do the same thing as PopulateContextFromInstallOptions but without all the string conversions. 32 AppInstaller::Manifest::ManifestComparator::Options GetComparatorOptionsFromInstallOptions(InstallOptions options) 33 { 34 AppInstaller::Manifest::ManifestComparator::Options result; 35 36 auto installerType = GetManifestInstallerType(options.InstallerType()); 37 if (installerType != AppInstaller::Manifest::InstallerTypeEnum::Unknown) 38 { 39 result.RequestedInstallerType = installerType; 40 } 41 42 auto manifestScope = GetManifestScope(options.PackageInstallScope()); 43 if (manifestScope.first != ::AppInstaller::Manifest::ScopeEnum::Unknown) 44 { 45 result.RequestedInstallerScope = manifestScope.first; 46 result.AllowUnknownScope = manifestScope.second; 47 } 48 49 if (options.AllowedArchitectures().Size() != 0) 50 { 51 for (auto architecture : options.AllowedArchitectures()) 52 { 53 auto convertedArchitecture = GetUtilityArchitecture(architecture); 54 if (convertedArchitecture) 55 { 56 result.AllowedArchitectures.push_back(convertedArchitecture.value()); 57 } 58 } 59 } 60 61 return result; 62 } 63 } 64 65 void PackageVersionInfo::Initialize(std::shared_ptr<::AppInstaller::Repository::IPackageVersion> packageVersion) 66 { 67 m_packageVersion = std::move(packageVersion); 68 } 69 std::shared_ptr<::AppInstaller::Repository::IPackageVersion> PackageVersionInfo::GetRepositoryPackageVersion() 70 { 71 return m_packageVersion; 72 } 73 hstring PackageVersionInfo::GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField) 74 { 75 ::AppInstaller::Repository::PackageVersionMetadata metadataKey = GetRepositoryPackageVersionMetadata(metadataField); 76 ::AppInstaller::Repository::IPackageVersion::Metadata metadata = m_packageVersion->GetMetadata(); 77 auto result = metadata.find(metadataKey); 78 if (result == metadata.end()) 79 { 80 return {}; 81 } 82 83 hstring resultString = winrt::to_hstring(result->second); 84 // The api uses "System" rather than "Machine" for install scope. 85 if (metadataField == PackageVersionMetadataField::InstalledScope && resultString == L"Machine") 86 { 87 return winrt::to_hstring(L"System"); 88 } 89 return resultString; 90 } 91 hstring PackageVersionInfo::Id() 92 { 93 return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Id).get()); 94 } 95 hstring PackageVersionInfo::DisplayName() 96 { 97 return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Name).get()); 98 } 99 hstring PackageVersionInfo::Publisher() 100 { 101 return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Publisher).get()); 102 } 103 hstring PackageVersionInfo::Version() 104 { 105 return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Version).get()); 106 } 107 hstring PackageVersionInfo::Channel() 108 { 109 return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Channel).get()); 110 } 111 winrt::Windows::Foundation::Collections::IVectorView<hstring> PackageVersionInfo::PackageFamilyNames() 112 { 113 if (!m_packageFamilyNames) 114 { 115 // Vector hasn't been created yet, create and populate it. 116 auto packageFamilyNames = winrt::single_threaded_vector<hstring>(); 117 for (auto&& string : m_packageVersion->GetMultiProperty(::AppInstaller::Repository::PackageVersionMultiProperty::PackageFamilyName)) 118 { 119 packageFamilyNames.Append(winrt::to_hstring(string)); 120 } 121 m_packageFamilyNames = packageFamilyNames; 122 } 123 return m_packageFamilyNames.GetView(); 124 } 125 winrt::Windows::Foundation::Collections::IVectorView<hstring> PackageVersionInfo::ProductCodes() 126 { 127 if (!m_productCodes) 128 { 129 // Vector hasn't been created yet, create and populate it. 130 auto productCodes = winrt::single_threaded_vector<hstring>(); 131 for (auto&& string : m_packageVersion->GetMultiProperty(::AppInstaller::Repository::PackageVersionMultiProperty::ProductCode)) 132 { 133 productCodes.Append(winrt::to_hstring(string)); 134 } 135 m_productCodes = productCodes; 136 } 137 return m_productCodes.GetView(); 138 } 139 winrt::Microsoft::Management::Deployment::PackageCatalog PackageVersionInfo::PackageCatalog() 140 { 141 if (!m_packageCatalog) 142 { 143 auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>(); 144 packageCatalogInfo->Initialize(m_packageVersion->GetSource().GetDetails()); 145 auto packageCatalog = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalog>>(); 146 packageCatalog->Initialize(*packageCatalogInfo, m_packageVersion->GetSource(), false); 147 m_packageCatalog = *packageCatalog; 148 } 149 return m_packageCatalog; 150 } 151 152 winrt::Microsoft::Management::Deployment::CompareResult PackageVersionInfo::CompareToVersion(const hstring& versionString) 153 { 154 if (versionString.empty()) 155 { 156 return CompareResult::Unknown; 157 } 158 159 AppInstaller::Utility::Version thisVersion{ m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Version).get() }; 160 AppInstaller::Utility::Version otherVersion{ AppInstaller::Utility::ConvertToUTF8(versionString) }; 161 162 if (thisVersion < otherVersion) 163 { 164 return CompareResult::Lesser; 165 } 166 else if (otherVersion < thisVersion) 167 { 168 return CompareResult::Greater; 169 } 170 else 171 { 172 return CompareResult::Equal; 173 } 174 } 175 bool PackageVersionInfo::HasApplicableInstaller(InstallOptions options) 176 { 177 AppInstaller::Manifest::ManifestComparator manifestComparator{ GetComparatorOptionsFromInstallOptions(options) }; 178 AppInstaller::Manifest::Manifest manifest = m_packageVersion->GetManifest(); 179 auto result = manifestComparator.GetPreferredInstaller(manifest); 180 return result.installer.has_value(); 181 } 182 winrt::Microsoft::Management::Deployment::PackageInstallerInfo PackageVersionInfo::GetApplicableInstaller(InstallOptions options) 183 { 184 AppInstaller::Manifest::ManifestComparator manifestComparator{ GetComparatorOptionsFromInstallOptions(options) }; 185 AppInstaller::Manifest::Manifest manifest = m_packageVersion->GetManifest(); 186 auto result = manifestComparator.GetPreferredInstaller(manifest); 187 188 if (result.installer.has_value()) 189 { 190 auto packageInstallerInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageInstallerInfo>>(); 191 packageInstallerInfo->Initialize(result.installer.value()); 192 return *packageInstallerInfo; 193 } 194 else 195 { 196 return nullptr; 197 } 198 } 199 Microsoft::Management::Deployment::CatalogPackageMetadata PackageVersionInfo::GetCatalogPackageMetadata() 200 { 201 auto catalogPackageMetadata = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::CatalogPackageMetadata>>(); 202 if (m_packageVersion) 203 { 204 auto manifest = m_packageVersion->GetManifest(); 205 manifest.ApplyLocale(); 206 catalogPackageMetadata->Initialize(manifest.CurrentLocalization); 207 } 208 209 return *catalogPackageMetadata; 210 } 211 Microsoft::Management::Deployment::CatalogPackageMetadata PackageVersionInfo::GetCatalogPackageMetadata(const hstring& preferredLocale) 212 { 213 std::string localeString = winrt::to_string(preferredLocale); 214 if (!::AppInstaller::Locale::IsWellFormedBcp47Tag(localeString)) 215 { 216 throw hresult_invalid_argument(); 217 } 218 219 auto catalogPackageMetadata = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::CatalogPackageMetadata>>(); 220 if (m_packageVersion) 221 { 222 auto manifest = m_packageVersion->GetManifest(); 223 manifest.ApplyLocale(localeString); 224 catalogPackageMetadata->Initialize(manifest.CurrentLocalization); 225 } 226 227 return *catalogPackageMetadata; 228 } 229 }