diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/testassets/MonoWorkloadManifest.json b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/testassets/MonoWorkloadManifest.json new file mode 100644 index 00000000000..3e1177e5e06 --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/testassets/MonoWorkloadManifest.json @@ -0,0 +1,273 @@ +{ + "version": "6.0.0-preview.7.21358.4", + "depends-on": { + "Microsoft.NET.Workload.Emscripten": "6.0.0-preview.7.21330.1" + }, + "workloads": { + "microsoft-net-sdk-blazorwebassembly-aot": { + "description": "Browser Runtime native performance tools", + "packs": [ + "Microsoft.NET.Runtime.WebAssembly.Sdk", + "Microsoft.NETCore.App.Runtime.Mono.browser-wasm", + "Microsoft.NETCore.App.Runtime.AOT.Cross.browser-wasm", + "Microsoft.NET.Runtime.Emscripten.Node", + "Microsoft.NET.Runtime.Emscripten.Python", + "Microsoft.NET.Runtime.Emscripten.Sdk" + ], + "extends": [ "microsoft-net-runtime-mono-tooling", "microsoft-net-sdk-emscripten" ], + "platforms": [ "win-x64", "linux-x64", "osx-x64", "osx-arm64" ] + }, + "microsoft-net-runtime-android": { + "abstract": true, + "description": "Android Mono Runtime", + "packs": [ + "Microsoft.NETCore.App.Runtime.Mono.android-arm", + "Microsoft.NETCore.App.Runtime.Mono.android-arm64", + "Microsoft.NETCore.App.Runtime.Mono.android-x64", + "Microsoft.NETCore.App.Runtime.Mono.android-x86" + ], + "extends": [ "microsoft-net-runtime-mono-tooling" ], + "platforms": [ "win-x64", "linux-x64", "osx-x64", "osx-arm64" ] + }, + "microsoft-net-runtime-android-aot": { + "abstract": true, + "description": "Android Mono AOT Workload", + "packs": [ + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86", + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm", + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm64" + ], + "extends": [ "microsoft-net-runtime-android" ], + "platforms": [ "win-x64", "linux-x64", "osx-x64", "osx-arm64" ] + }, + "microsoft-net-runtime-ios": { + "abstract": true, + "description": "iOS Mono Runtime and AOT Workload", + "packs": [ + "Microsoft.NETCore.App.Runtime.Mono.ios-arm", + "Microsoft.NETCore.App.Runtime.Mono.ios-arm64", + "Microsoft.NETCore.App.Runtime.Mono.iossimulator", + "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x86", + "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm", + "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator", + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x86" + ], + "extends": [ "microsoft-net-runtime-mono-tooling" ], + "platforms": [ "osx-arm64", "osx-x64" ] + }, + "microsoft-net-runtime-maccatalyst": { + "abstract": true, + "description": "MacCatalyst Mono Runtime and AOT Workload", + "packs": [ + "Microsoft.NETCore.App.Runtime.Mono.maccatalyst", + "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst" + ], + "extends": [ "microsoft-net-runtime-mono-tooling" ], + "platforms": [ "osx-arm64", "osx-x64" ] + }, + "microsoft-net-runtime-tvos": { + "abstract": true, + "description": "tvOS Mono Runtime and AOT Workload", + "packs": [ + "Microsoft.NETCore.App.Runtime.Mono.tvos-arm64", + "Microsoft.NETCore.App.Runtime.Mono.tvossimulator", + "Microsoft.NETCore.App.Runtime.AOT.Cross.tvos-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator" + ], + "extends": [ "microsoft-net-runtime-mono-tooling" ], + "platforms": [ "osx-arm64", "osx-x64" ] + }, + "microsoft-net-runtime-mono-tooling": { + "abstract": true, + "description": "Shared native build tooling for Mono runtime", + "packs": [ + "Microsoft.NET.Runtime.MonoAOTCompiler.Task", + "Microsoft.NET.Runtime.MonoTargets.Sdk", + ], + } + }, + "packs": { + "Microsoft.NET.Runtime.MonoAOTCompiler.Task": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NET.Runtime.MonoTargets.Sdk": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NET.Runtime.WebAssembly.Sdk": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NETCore.App.Runtime.Mono.android-arm": { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NETCore.App.Runtime.Mono.android-arm64": { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NETCore.App.Runtime.Mono.android-x64": { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NETCore.App.Runtime.Mono.android-x86": { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-x86", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.android-x86", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-x86", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-x86" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-x64", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.android-x64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-x64", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-arm", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.android-arm", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm64": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-arm64", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.android-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm64", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm64" + } + }, + "Microsoft.NETCore.App.Runtime.Mono.maccatalyst": { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64" + } + }, + "Microsoft.NETCore.App.Runtime.Mono.ios-arm" : { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NETCore.App.Runtime.Mono.ios-arm64" : { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NETCore.App.Runtime.Mono.iossimulator" : { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x64" + } + }, + "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x86" : { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-x64": "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x86" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.tvos-arm64": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvos-arm64", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvos-arm64", + } + }, + "Microsoft.NETCore.App.Runtime.Mono.tvos-arm64" : { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4" + }, + "Microsoft.NETCore.App.Runtime.Mono.tvossimulator" : { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm", + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm64": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm64", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm64", + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x86": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x86" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.browser-wasm": { + "kind": "Sdk", + "version": "6.0.0-preview.7.21358.4", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.browser-wasm", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.browser-wasm", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.browser-wasm", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.browser-wasm" + } + }, + "Microsoft.NETCore.App.Runtime.Mono.browser-wasm" : { + "kind": "framework", + "version": "6.0.0-preview.7.21358.4" + }, + } +} diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs index 16bee2bad66..384e46cfdde 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs @@ -234,11 +234,13 @@ public override bool Execute() MsiProperties msiProps = new MsiProperties { InstallSize = MsiUtils.GetInstallSize(msiPath), + Language = Convert.ToInt32(MsiUtils.GetProperty(msiPath, "ProductLanguage")), Payload = Path.GetFileName(msiPath), ProductCode = MsiUtils.GetProperty(msiPath, "ProductCode"), ProductVersion = MsiUtils.GetProperty(msiPath, "ProductVersion"), ProviderKeyName = $"{nupkg.Id},{nupkg.Version},{platform}", - UpgradeCode = MsiUtils.GetProperty(msiPath, "UpgradeCode") + UpgradeCode = MsiUtils.GetProperty(msiPath, "UpgradeCode"), + RelatedProducts = MsiUtils.GetRelatedProducts(msiPath) }; string msiJsonPath = Path.Combine(Path.GetDirectoryName(msiPath), Path.GetFileNameWithoutExtension(msiPath) + ".json"); @@ -308,7 +310,6 @@ private string GeneratePackageProject(string msiPath, string msiJsonPath, string writer.WriteElementString("PackageId", $"{nupkg.Id}.Msi.{platform}"); writer.WriteElementString("PackageVersion", $"{nupkg.Version}"); writer.WriteElementString("Description", nupkg.Description); - writer.WriteElementString("PackageIcon", "Icon.png"); if (!string.IsNullOrWhiteSpace(nupkg.Authors)) { @@ -326,11 +327,23 @@ private string GeneratePackageProject(string msiPath, string msiJsonPath, string writer.WriteStartElement("ItemGroup"); WriteItem(writer, "None", msiPath, @"\data"); WriteItem(writer, "None", msiJsonPath, @"\data\msi.json"); - WriteItem(writer, "None", iconFileName, string.Empty); WriteItem(writer, "None", licenseFileName, @"\"); - writer.WriteEndElement(); - - writer.WriteEndElement(); + writer.WriteEndElement(); // ItemGroup + + writer.WriteRaw(@" + + + Icon.png + + + + + +"); + + writer.WriteEndElement(); // Project writer.Flush(); writer.Close(); diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateMsiBase.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateMsiBase.cs index 62fcf789438..9e201639401 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateMsiBase.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateMsiBase.cs @@ -256,11 +256,13 @@ protected IEnumerable Generate(string sourcePackage, string swixPacka MsiProperties msiProps = new MsiProperties { InstallSize = MsiUtils.GetInstallSize(msiPath), + Language = Convert.ToInt32(MsiUtils.GetProperty(msiPath, "ProductLanguage")), Payload = Path.GetFileName(msiPath), ProductCode = MsiUtils.GetProperty(msiPath, "ProductCode"), ProductVersion = MsiUtils.GetProperty(msiPath, "ProductVersion"), ProviderKeyName = $"{nupkg.Id},{nupkg.Version},{platform}", - UpgradeCode = MsiUtils.GetProperty(msiPath, "UpgradeCode") + UpgradeCode = MsiUtils.GetProperty(msiPath, "UpgradeCode"), + RelatedProducts = MsiUtils.GetRelatedProducts(msiPath) }; string msiJsonPath = Path.Combine(Path.GetDirectoryName(msiPath), Path.GetFileNameWithoutExtension(msiPath) + ".json"); @@ -334,7 +336,6 @@ private string GeneratePackageProject(string msiPath, string msiJsonPath, string writer.WriteElementString("PackageId", $"{nupkg.Id}.Msi.{platform}"); writer.WriteElementString("PackageVersion", $"{nupkg.Version}"); writer.WriteElementString("Description", nupkg.Description); - writer.WriteElementString("PackageIcon", "Icon.png"); if (!string.IsNullOrWhiteSpace(nupkg.Authors)) { @@ -352,11 +353,23 @@ private string GeneratePackageProject(string msiPath, string msiJsonPath, string writer.WriteStartElement("ItemGroup"); WriteItem(writer, "None", msiPath, @"\data"); WriteItem(writer, "None", msiJsonPath, @"\data\msi.json"); - WriteItem(writer, "None", iconFileName, string.Empty); WriteItem(writer, "None", licenseFileName, @"\"); - writer.WriteEndElement(); - - writer.WriteEndElement(); + writer.WriteEndElement(); // ItemGroup + + writer.WriteRaw(@" + + + Icon.png + + + + + +"); + + writer.WriteEndElement(); // Project writer.Flush(); writer.Close(); diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiProperties.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiProperties.cs index b3f4ab15d23..7c8376c69a0 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiProperties.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiProperties.cs @@ -1,11 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Microsoft.DotNet.Build.Tasks.Workloads { @@ -17,6 +13,12 @@ public long InstallSize set; } + public int Language + { + get; + set; + } + public string Payload { get; @@ -45,6 +47,12 @@ public string UpgradeCode { get; set; - } + } + + public IEnumerable RelatedProducts + { + get; + set; + } } } diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/ManifestProduct.wxs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/ManifestProduct.wxs index b5556c28d19..128fe2200bb 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/ManifestProduct.wxs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/ManifestProduct.wxs @@ -2,7 +2,7 @@ - diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Product.wxs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Product.wxs index 98d2a78515c..6f628f7797b 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Product.wxs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Product.wxs @@ -2,7 +2,7 @@ - diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Registry.wxs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Registry.wxs index 9835ce99ca4..99f2127088e 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Registry.wxs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Registry.wxs @@ -11,6 +11,7 @@ + diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Variables.wxi b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Variables.wxi index 0c5e3b07d49..0e1b15b5322 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Variables.wxi +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Variables.wxi @@ -17,6 +17,10 @@ + + + + diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiUtils.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiUtils.cs index caa99c8170c..6ca695ff84f 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiUtils.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiUtils.cs @@ -13,6 +13,8 @@ public class MsiUtils { private const string _getFilesQuery = "SELECT `File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence` FROM `File`"; + private const string _getUpgradeQuery = "SELECT `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes` FROM `Upgrade`"; + public static IEnumerable GetAllFiles(string packagePath) { using InstallPackage ip = new(packagePath, DatabaseOpenMode.ReadOnly); @@ -29,12 +31,40 @@ public static IEnumerable GetAllFiles(string packagePath) return files; } + public static IEnumerable GetRelatedProducts(string packagePath) + { + using InstallPackage ip = new(packagePath, DatabaseOpenMode.ReadOnly); + using Database db = new(packagePath, DatabaseOpenMode.ReadOnly); + + if (db.Tables.Contains("Upgrade")) + { + using View upgradeView = db.OpenView(_getUpgradeQuery); + List relatedProducts = new(); + upgradeView.Execute(); + + foreach (Record relatedProduct in upgradeView) + { + relatedProducts.Add(RelatedProduct.Create(relatedProduct)); + } + + return relatedProducts; + } + + return Enumerable.Empty(); + } + + /// + /// Extracts the specified property from the MSI's Property table. + /// + /// The path to the MSI package. + /// The name of the property to extract. + /// The value of the property. public static string GetProperty(string packagePath, string property) { using InstallPackage ip = new(packagePath, DatabaseOpenMode.ReadOnly); return ip.Property[property]; - } + /// /// Calculate the number of bytes a Windows Installer Package would consume on disk. The function assumes that all files will be installed. /// diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/RelatedProduct.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/RelatedProduct.cs new file mode 100644 index 00000000000..4eb3a09ba1f --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/RelatedProduct.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Microsoft.Deployment.WindowsInstaller; + +namespace Microsoft.DotNet.Build.Tasks.Workloads +{ + // Represents a single row from the MSI Upgrade table. + public class RelatedProduct + { + public string UpgradeCode + { + get; + set; + } + + public string VersionMin + { + get; + set; + } + + public string VersionMax + { + get; + set; + } + + public string Language + { + get; + set; + } + + public int Attributes + { + get; + set; + } + + public static RelatedProduct Create(Record record) + { + string versionMin = (string)record["VersionMin"]; + string versionMax = (string)record["VersionMax"]; + + return new RelatedProduct + { + UpgradeCode = (string)record["UpgradeCode"], + VersionMin = string.IsNullOrWhiteSpace(versionMin) ? null : versionMin, + VersionMax = string.IsNullOrWhiteSpace(versionMax) ? null : versionMax, + Language = (string)record["Language"], + Attributes = (int)record["Attributes"] + }; + } + } +} diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs index b6d523fb38e..22b083a99b5 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs @@ -243,7 +243,7 @@ public static VisualStudioComponent Create(TaskLoggingHelper log, WorkloadManife IEnumerable missingPackIds = missingPacks.Select(p => p.ItemSpec); log?.LogMessage(MessageImportance.Low, $"Missing packs: {string.Join(", ", missingPackIds)}"); - // If the work extends other workloads, we add those as component dependencies before + // If the workload extends other workloads, we add those as component dependencies before // processing direct pack dependencies if (workload.Extends?.Count() > 0) { @@ -263,7 +263,15 @@ public static VisualStudioComponent Create(TaskLoggingHelper log, WorkloadManife foreach (WorkloadPackId packId in packIds) { log?.LogMessage(MessageImportance.Low, $"Adding component dependency for {packId} "); - component.AddDependency(manifest.Packs[packId]); + + if (manifest.Packs.ContainsKey(packId)) + { + component.AddDependency(manifest.Packs[packId]); + } + else + { + log?.LogMessage(MessageImportance.High, $"Missing Visual Studio component dependency, packId: {packId}."); + } } }