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}.");
+ }
}
}