diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs
index 384e46cfdde..ec049c9b3f7 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs
@@ -17,6 +17,15 @@ public class GenerateManifestMsi : GenerateTaskBase
{
private Version _sdkFeaureBandVersion;
+ ///
+ /// Gets or sets whether a corresponding SWIX project should be generated for the MSI.
+ ///
+ public bool GenerateSwixAuthoring
+ {
+ get;
+ set;
+ } = true;
+
///
/// The path where the generated MSIs will be placed.
///
@@ -30,7 +39,6 @@ public string OutputPath
///
/// The ID of the workload manifest.
///
- [Required]
public string ManifestId
{
get;
@@ -65,7 +73,6 @@ private Version SdkFeatureBandVersion
///
/// The SDK version, e.g. 6.0.107.
///
- [Required]
public string SdkVersion
{
get;
@@ -102,11 +109,35 @@ public override bool Execute()
{
try
{
- Log.LogMessage($"Generating workload manifest installer for {SdkFeatureBandVersion}");
-
NugetPackage nupkg = new(WorkloadManifestPackage, Log);
List msis = new();
+ var manifestSeparator = ".Manifest-";
+ if (string.IsNullOrWhiteSpace(ManifestId))
+ {
+ if ($"{nupkg.Id}".IndexOf(manifestSeparator, StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ Log.LogError($"Unable to parse a manifest ID from package ID: '{nupkg.Id}'. Please provide the 'ManifestId' parameter.");
+ }
+ else
+ {
+ ManifestId = $"{nupkg.Id}".Substring(0, $"{nupkg.Id}".IndexOf(manifestSeparator));
+ }
+ }
+ if (string.IsNullOrWhiteSpace(SdkVersion))
+ {
+ if ($"{nupkg.Id}".IndexOf(manifestSeparator, StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ Log.LogError($"Unable to parse the SDK version from package ID: '{nupkg.Id}'. Please provide the 'SdkVersion' parameter.");
+ }
+ else
+ {
+ SdkVersion = $"{nupkg.Id}".Substring($"{nupkg.Id}".IndexOf(manifestSeparator) + manifestSeparator.Length);
+ }
+ }
+
+ Log.LogMessage(MessageImportance.High, $"Generating workload manifest installer for {SdkFeatureBandVersion}");
+
// MSI ProductName defaults to the package title and fallback to the package ID with a warning.
string productName = nupkg.Title;
@@ -116,6 +147,10 @@ public override bool Execute()
productName = nupkg.Id;
}
+
+
+
+
// Extract once, but harvest multiple times because some generated attributes are platform dependent.
string packageContentsDirectory = Path.Combine(PackageDirectory, $"{nupkg.Identity}");
nupkg.Extract(packageContentsDirectory, Enumerable.Empty());
@@ -252,6 +287,19 @@ public override bool Execute()
msi.SetMetadata(Metadata.JsonProperties, msiJsonPath);
msi.SetMetadata(Metadata.WixObj, candleIntermediateOutputPath);
+ if (GenerateSwixAuthoring && IsSupportedByVisualStudio(platform))
+ {
+ string swixPackageId = $"{nupkg.Id}";
+
+ string swixProject = GenerateSwixPackageAuthoring(light.OutputFile,
+ swixPackageId, platform);
+
+ if (!string.IsNullOrWhiteSpace(swixProject))
+ {
+ msi.SetMetadata(Metadata.SwixProject, swixProject);
+ }
+ }
+
// Generate a .csproj to build a NuGet payload package to carry the MSI and JSON manifest
msi.SetMetadata(Metadata.PackageProject, GeneratePackageProject(msi.ItemSpec, msiJsonPath, platform, nupkg));
@@ -268,7 +316,6 @@ public override bool Execute()
return !Log.HasLoggedErrors;
}
-
private string GeneratePackageProject(string msiPath, string msiJsonPath, string platform, NugetPackage nupkg)
{
string msiPackageProject = Path.Combine(MsiPackageDirectory, platform, nupkg.Id, "msi.csproj");
@@ -358,5 +405,24 @@ private void WriteItem(XmlWriter writer, string itemName, string include, string
writer.WriteAttributeString("PackagePath", packagePath);
writer.WriteEndElement();
}
+
+ private string GenerateSwixPackageAuthoring(string msiPath, string packageId, string platform)
+ {
+ GenerateVisualStudioMsiPackageProject swixTask = new()
+ {
+ Chip = platform,
+ IntermediateBaseOutputPath = this.IntermediateBaseOutputPath,
+ PackageName = packageId,
+ MsiPath = msiPath,
+ BuildEngine = this.BuildEngine,
+ };
+
+ if (!swixTask.Execute())
+ {
+ Log.LogError($"Failed to generate SWIX authoring for '{msiPath}'");
+ }
+
+ return swixTask.SwixProject;
+ }
}
}
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateMsiBase.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateMsiBase.cs
index 9e201639401..3f36c9d0a11 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateMsiBase.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateMsiBase.cs
@@ -134,6 +134,7 @@ protected IEnumerable Generate(string sourcePackage, string swixPacka
string packageContentsDirectory = Path.Combine(PackageDirectory, $"{nupkg.Identity}");
IEnumerable exclusions = GetExlusionPatterns();
string installDir = GetInstallDir(kind);
+ string packKind = kind.ToString().ToLowerInvariant();
if ((kind != WorkloadPackKind.Library) && (kind != WorkloadPackKind.Template))
{
@@ -174,10 +175,14 @@ protected IEnumerable Generate(string sourcePackage, string swixPacka
string packageContentWxs = Path.Combine(msiSourcePath, "PackageContent.wxs");
sourceFiles.Add(packageContentWxs);
+ string directoryReference = (kind == WorkloadPackKind.Library) || (kind == WorkloadPackKind.Template)
+ ? "InstallDir"
+ : PackageContentDirectoryReference;
+
HarvestToolTask heat = new(BuildEngine, WixToolsetPath)
{
ComponentGroupName = PackageContentComponentGroupName,
- DirectoryReference = PackageContentDirectoryReference,
+ DirectoryReference = directoryReference,
OutputFile = packageContentWxs,
Platform = platform,
SourceDirectory = packageContentsDirectory
@@ -216,6 +221,7 @@ protected IEnumerable Generate(string sourcePackage, string swixPacka
candle.PreprocessorDefinitions.Add($@"SourceDir={packageContentsDirectory}");
candle.PreprocessorDefinitions.Add($@"Manufacturer={manufacturer}");
candle.PreprocessorDefinitions.Add($@"EulaRtf={EulaRtfPath}");
+ candle.PreprocessorDefinitions.Add($@"PackKind={packKind}");
// Compiler extension to process dependency provider authoring for package reference counting.
candle.Extensions.Add("WixDependencyExtension");
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Directories.wxs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Directories.wxs
index 574cbe373b1..709bbb08563 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Directories.wxs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Directories.wxs
@@ -7,9 +7,11 @@
+
+