Manifest.cs (17900B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="Manifest.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace Microsoft.WinGetUtil.Models.V1 8 { 9 using System.Collections.Generic; 10 using System.IO; 11 using Microsoft.WinGetUtil.Common; 12 using YamlDotNet.Serialization; 13 14 /// <summary> 15 /// Class that defines the structure of the manifest. Uses YamlDotNet 16 /// to deserialize a string or a stream and produce a manifest object. 17 /// </summary> 18 public class Manifest 19 { 20 /// <summary> 21 /// Gets or sets the Id of the package. 22 /// </summary> 23 [YamlMember(Alias ="PackageIdentifier")] 24 public string Id { get; set; } 25 26 /// <summary> 27 /// Gets or sets the version of the package. 28 /// </summary> 29 [YamlMember(Alias = "PackageVersion")] 30 public string Version { get; set; } 31 32 /// <summary> 33 /// Gets or sets the manifest type. 34 /// </summary> 35 public string ManifestType { get; set; } 36 37 /// <summary> 38 /// Gets or sets the manifest version. 39 /// </summary> 40 public string ManifestVersion { get; set; } 41 42 /// <summary> 43 /// Gets or sets the Channel. 44 /// </summary> 45 public string Channel { get; set; } 46 47 // Localization fields 48 49 /// <summary> 50 /// Gets or sets the AppMoniker. 51 /// </summary> 52 public string Moniker { get; set; } 53 54 /// <summary> 55 /// Gets or sets the default locale. 56 /// </summary> 57 public string PackageLocale { get; set; } 58 59 /// <summary> 60 /// Gets or sets the publisher in default locale. 61 /// </summary> 62 public string Publisher { get; set; } 63 64 /// <summary> 65 /// Gets or sets the publisher url in default locale. 66 /// </summary> 67 public string PublisherUrl { get; set; } 68 69 /// <summary> 70 /// Gets or sets the publisher support url in default locale. 71 /// </summary> 72 public string PublisherSupportUrl { get; set; } 73 74 /// <summary> 75 /// Gets or sets the default privacy url. 76 /// </summary> 77 public string PrivacyUrl { get; set; } 78 79 /// <summary> 80 /// Gets or sets the author in default locale. 81 /// </summary> 82 public string Author { get; set; } 83 84 /// <summary> 85 /// Gets or sets the package name in default locale. 86 /// </summary> 87 public string PackageName { get; set; } 88 89 /// <summary> 90 /// Gets or sets the package homepage url in default locale. 91 /// </summary> 92 public string PackageUrl { get; set; } 93 94 /// <summary> 95 /// Gets or sets the license in default locale. 96 /// </summary> 97 public string License { get; set; } 98 99 /// <summary> 100 /// Gets or sets the license url in default locale. 101 /// </summary> 102 public string LicenseUrl { get; set; } 103 104 /// <summary> 105 /// Gets or sets the copyright in default locale. 106 /// </summary> 107 public string Copyright { get; set; } 108 109 /// <summary> 110 /// Gets or sets the copyright url in default locale. 111 /// </summary> 112 public string CopyrightUrl { get; set; } 113 114 /// <summary> 115 /// Gets or sets the package short description in default locale. 116 /// </summary> 117 public string ShortDescription { get; set; } 118 119 /// <summary> 120 /// Gets or sets the package description in default locale. 121 /// </summary> 122 public string Description { get; set; } 123 124 /// <summary> 125 /// Gets or sets the Tags in default locale. 126 /// </summary> 127 public List<string> Tags { get; set; } 128 129 /// <summary> 130 /// Gets or sets the package agreements in default locale. 131 /// </summary> 132 public List<PackageAgreement> Agreements { get; set; } 133 134 /// <summary> 135 /// Gets or sets the release notes in default locale. 136 /// </summary> 137 public string ReleaseNotes { get; set; } 138 139 /// <summary> 140 /// Gets or sets the manifest documentation. 141 /// </summary> 142 public List<ManifestDocumentation> Documentations { get; set; } 143 144 /// <summary> 145 /// Gets or sets the manifest icons information. 146 /// </summary> 147 public List<ManifestIcon> Icons { get; set; } 148 149 /// <summary> 150 /// Gets or sets the release notes url in default locale. 151 /// </summary> 152 public string ReleaseNotesUrl { get; set; } 153 154 /// <summary> 155 /// Gets or sets the purchase url of the package. 156 /// </summary> 157 public string PurchaseUrl { get; set; } 158 159 /// <summary> 160 /// Gets or sets the installation notes. 161 /// </summary> 162 public string InstallationNotes { get; set; } 163 164 // Installer fields 165 166 /// <summary> 167 /// Gets or sets the default installer locale. 168 /// </summary> 169 public string InstallerLocale { get; set; } 170 171 /// <summary> 172 /// Gets or sets the default list of supported platforms. 173 /// </summary> 174 public List<string> Platform { get; set; } 175 176 /// <summary> 177 /// Gets or sets the default minimum OS version. 178 /// </summary> 179 public string MinimumOSVersion { get; set; } 180 181 /// <summary> 182 /// Gets or sets the default installer type. 183 /// </summary> 184 public string InstallerType { get; set; } 185 186 /// <summary> 187 /// Gets or sets the default installer scope. 188 /// </summary> 189 public string Scope { get; set; } 190 191 /// <summary> 192 /// Gets or sets the default list of install modes. 193 /// </summary> 194 public List<string> InstallModes { get; set; } 195 196 /// <summary> 197 /// Gets or sets the default list of additional installer success codes. 198 /// </summary> 199 public List<long> InstallerSuccessCodes { get; set; } 200 201 /// <summary> 202 /// Gets or sets the default upgrade behavior. 203 /// </summary> 204 public string UpgradeBehavior { get; set; } 205 206 /// <summary> 207 /// Gets or sets the default list of commands. 208 /// </summary> 209 public List<string> Commands { get; set; } 210 211 /// <summary> 212 /// Gets or sets the default list of supported protocols. 213 /// </summary> 214 public List<string> Protocols { get; set; } 215 216 /// <summary> 217 /// Gets or sets the default list of supported file extensions. 218 /// </summary> 219 public List<string> FileExtensions { get; set; } 220 221 /// <summary> 222 /// Gets or sets the default package family name for msix packaged installers. 223 /// </summary> 224 public string PackageFamilyName { get; set; } 225 226 /// <summary> 227 /// Gets or sets default product code for ARP (Add/Remove Programs) installers. 228 /// </summary> 229 public string ProductCode { get; set; } 230 231 /// <summary> 232 /// Gets or sets the default list of capabilities. For msix only. 233 /// </summary> 234 public List<string> Capabilities { get; set; } 235 236 /// <summary> 237 /// Gets or sets the default list of restricted capabilities. For msix only. 238 /// </summary> 239 public List<string> RestrictedCapabilities { get; set; } 240 241 /// <summary> 242 /// Gets or sets the default installer dependency. 243 /// </summary> 244 public InstallerDependency Dependencies { get; set; } 245 246 /// <summary> 247 /// Gets or sets the default installer switches. 248 /// </summary> 249 [YamlMember(Alias = "InstallerSwitches")] 250 public InstallerSwitches Switches { get; set; } 251 252 /// <summary> 253 /// Gets or sets the default installer markets info. 254 /// </summary> 255 public InstallerMarkets Markets { get; set; } 256 257 /// <summary> 258 /// Gets or sets the installation metadata. 259 /// </summary> 260 public InstallerInstallationMetadata InstallationMetadata { get; set; } 261 262 /// <summary> 263 /// Gets or sets the nested installer type. 264 /// </summary> 265 public string NestedInstallerType { get; set; } 266 267 /// <summary> 268 /// Gets or sets the nested installer files. 269 /// </summary> 270 public List<InstallerNestedInstallerFile> NestedInstallerFiles { get; set; } 271 272 /// <summary> 273 /// Gets or sets the unsupported arguments. 274 /// </summary> 275 public List<string> UnsupportedArguments { get; set; } 276 277 /// <summary> 278 /// Gets or sets a value indicating whether the default installer behavior aborts terminal. 279 /// </summary> 280 public bool? InstallerAbortsTerminal { get; set; } 281 282 /// <summary> 283 /// Gets or sets a value indicating whether the default installer behavior requires explicit install location. 284 /// </summary> 285 public bool? InstallLocationRequired { get; set; } 286 287 /// <summary> 288 /// Gets or sets a value indicating whether the default installer behavior requires explicit upgrade. 289 /// </summary> 290 public bool? RequireExplicitUpgrade { get; set; } 291 292 /// <summary> 293 /// Gets or sets the default installer release date. 294 /// </summary> 295 public string ReleaseDate { get; set; } 296 297 /// <summary> 298 /// Gets or sets the default list of unsupported OS architectures. 299 /// </summary> 300 public List<string> UnsupportedOSArchitectures { get; set; } 301 302 /// <summary> 303 /// Gets or sets a value indicating whether to display install warnings. 304 /// </summary> 305 public bool? DisplayInstallWarnings { get; set; } 306 307 /// <summary> 308 /// Gets or sets the default list of apps and features entries. 309 /// </summary> 310 public List<InstallerArpEntry> AppsAndFeaturesEntries { get; set; } 311 312 /// <summary> 313 /// Gets or sets the default installer elevation requirement. 314 /// </summary> 315 public string ElevationRequirement { get; set; } 316 317 /// <summary> 318 /// Gets or sets the default list of installer expected return codes. 319 /// </summary> 320 public List<InstallerExpectedReturnCode> ExpectedReturnCodes { get; set; } 321 322 /// <summary> 323 /// Gets or sets a value indicating whether the installer is prohibited from being downloaded for offline installation. 324 /// </summary> 325 public bool? DownloadCommandProhibited { get; set; } 326 327 /// <summary> 328 /// Gets or sets a value indicating whether the install location should be added directly to the PATH environment variable. 329 /// </summary> 330 public bool? ArchiveBinariesDependOnPath { get; set; } 331 332 /// <summary> 333 /// Gets or sets the default repair behavior. 334 /// </summary> 335 public string RepairBehavior { get; set; } 336 337 /// <summary> 338 /// Gets or sets the default installer authentication info. 339 /// </summary> 340 public InstallerAuthentication Authentication { get; set; } 341 342 /// <summary> 343 /// Gets or sets collection of ManifestInstaller. At least one is required. 344 /// </summary> 345 public List<ManifestInstaller> Installers { get; set; } 346 347 /// <summary> 348 /// Gets or sets collection of additional ManifestLocalization. 349 /// </summary> 350 public List<ManifestLocalization> Localization { get; set; } 351 352 /// <summary> 353 /// Deserialize a stream reader into a Manifest object. 354 /// </summary> 355 /// <param name="filePath">file path.</param> 356 /// <returns>Manifest object populated and validated.</returns> 357 public static Manifest CreateManifestFromPath(string filePath) 358 { 359 using (StreamReader streamReader = new StreamReader(filePath)) 360 { 361 return Manifest.CreateManifestFromStreamReader(streamReader); 362 } 363 } 364 365 /// <summary> 366 /// Deserialize a stream into a Manifest object. 367 /// </summary> 368 /// <param name="stream">Manifest stream.</param> 369 /// <returns>Manifest object populated and validated.</returns> 370 public static Manifest CreateManifestFromStream(Stream stream) 371 { 372 using (StreamReader streamReader = new StreamReader(stream)) 373 { 374 return Manifest.CreateManifestFromStreamReader(streamReader); 375 } 376 } 377 378 /// <summary> 379 /// Deserialize a stream reader into a Manifest object. 380 /// </summary> 381 /// <param name="streamReader">stream reader.</param> 382 /// <returns>Manifest object populated and validated.</returns> 383 public static Manifest CreateManifestFromStreamReader(StreamReader streamReader) 384 { 385 streamReader.BaseStream.Seek(0, SeekOrigin.Begin); 386 var deserializer = Helpers.CreateDeserializer(); 387 return deserializer.Deserialize<Manifest>(streamReader); 388 } 389 390 /// <summary> 391 /// Deserialize a string into a Manifest object. 392 /// </summary> 393 /// <param name="value">Manifest in string value.</param> 394 /// <returns>Manifest object populated and validated.</returns> 395 public static Manifest CreateManifestFromString(string value) 396 { 397 var deserializer = Helpers.CreateDeserializer(); 398 return deserializer.Deserialize<Manifest>(value); 399 } 400 401 /// <summary> 402 /// Returns a List of strings containing the URIs contained within this manifest. 403 /// </summary> 404 /// <returns>List of strings.</returns> 405 public List<string> GetURIs() 406 { 407 List<string> uris = new List<string>(); 408 if (!string.IsNullOrEmpty(this.PublisherUrl)) 409 { 410 uris.Add(this.PublisherUrl); 411 } 412 413 if (!string.IsNullOrEmpty(this.PublisherSupportUrl)) 414 { 415 uris.Add(this.PublisherSupportUrl); 416 } 417 418 if (!string.IsNullOrEmpty(this.PrivacyUrl)) 419 { 420 uris.Add(this.PrivacyUrl); 421 } 422 423 if (!string.IsNullOrEmpty(this.PackageUrl)) 424 { 425 uris.Add(this.PackageUrl); 426 } 427 428 if (!string.IsNullOrEmpty(this.LicenseUrl)) 429 { 430 uris.Add(this.LicenseUrl); 431 } 432 433 if (!string.IsNullOrEmpty(this.CopyrightUrl)) 434 { 435 uris.Add(this.CopyrightUrl); 436 } 437 438 if (!string.IsNullOrEmpty(this.ReleaseNotesUrl)) 439 { 440 uris.Add(this.ReleaseNotesUrl); 441 } 442 443 if (this.Agreements != null) 444 { 445 foreach (var agreement in this.Agreements) 446 { 447 if (!string.IsNullOrEmpty(agreement.AgreementUrl)) 448 { 449 uris.Add(agreement.AgreementUrl); 450 } 451 } 452 } 453 454 foreach (ManifestInstaller installer in this.Installers) 455 { 456 uris.AddRange(installer.GetURIs()); 457 } 458 459 if (this.Localization != null) 460 { 461 foreach (ManifestLocalization localization in this.Localization) 462 { 463 uris.AddRange(localization.GetURIs()); 464 } 465 } 466 467 if (this.Documentations != null) 468 { 469 foreach (var docs in this.Documentations) 470 { 471 if (!string.IsNullOrEmpty(docs.DocumentUrl)) 472 { 473 uris.Add(docs.DocumentUrl); 474 } 475 } 476 } 477 478 if (this.Icons != null) 479 { 480 foreach (var icon in this.Icons) 481 { 482 if (!string.IsNullOrEmpty(icon.IconUrl)) 483 { 484 uris.Add(icon.IconUrl); 485 } 486 } 487 } 488 489 return uris; 490 } 491 492 /// <summary> 493 /// Checks if two manifests are equivalent. 494 /// </summary> 495 /// <param name="other">other object.</param> 496 /// <returns>boolean indicating if the objects are equals.</returns> 497 public bool IsManifestEquivalent(Manifest other) 498 { 499 // If parameter is null, return false. 500 if (ReferenceEquals(other, null)) 501 { 502 return false; 503 } 504 505 // Optimization for a common success case. 506 if (ReferenceEquals(this, other)) 507 { 508 return true; 509 } 510 511 // If run-time types are not exactly the same, return false. 512 if (this.GetType() != other.GetType()) 513 { 514 return false; 515 } 516 517 // Equality of Manifest consist on only these properties. 518 return (this.Id == other.Id) && 519 (this.Version == other.Version) && 520 this.CompareInstallers(other.Installers); 521 } 522 523 private bool CompareInstallers(List<ManifestInstaller> installers) 524 { 525 ISet<ManifestInstaller> first = 526 new HashSet<ManifestInstaller>( 527 this.Installers != null ? 528 this.Installers : 529 new List<ManifestInstaller>()); 530 531 return first.SetEquals(installers != null 532 ? installers : new List<ManifestInstaller>()); 533 } 534 } 535 }