diff --git a/src/Installer/core-sdk-tasks/GenerateRuntimeAnalyzersSWR.cs b/src/Installer/core-sdk-tasks/GenerateRuntimeAnalyzersSWR.cs
new file mode 100644
index 000000000000..aa36e3e2e115
--- /dev/null
+++ b/src/Installer/core-sdk-tasks/GenerateRuntimeAnalyzersSWR.cs
@@ -0,0 +1,101 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public class GenerateRuntimeAnalyzersSWR : Task
+ {
+ [Required]
+ public string RuntimeAnalyzersLayoutDirectory { get; set; }
+
+ [Required]
+ public string OutputFile { get; set; }
+
+ public override bool Execute()
+ {
+ StringBuilder sb = new StringBuilder(SWR_HEADER);
+
+ AddFolder(sb,
+ @"AspNetCoreAnalyzers",
+ @"SDK\AspNetCoreAnalyzers");
+
+ AddFolder(sb,
+ @"NetCoreAnalyzers",
+ @"SDK\NetCoreAnalyzers");
+
+ AddFolder(sb,
+ @"WindowsDesktopAnalyzers",
+ @"SDK\WindowsDesktopAnalyzers");
+
+ AddFolder(sb,
+ @"SDKAnalyzers",
+ @"SDK\SDKAnalyzers");
+
+ AddFolder(sb,
+ @"WebSDKAnalyzers",
+ @"SDK\WebSDKAnalyzers");
+
+ File.WriteAllText(OutputFile, sb.ToString());
+
+ return true;
+ }
+
+ private void AddFolder(StringBuilder sb, string relativeSourcePath, string swrInstallDir, bool ngenAssemblies = true)
+ {
+ string sourceFolder = Path.Combine(RuntimeAnalyzersLayoutDirectory, relativeSourcePath);
+ var files = Directory.GetFiles(sourceFolder)
+ .Where(f => !Path.GetExtension(f).Equals(".pdb", StringComparison.OrdinalIgnoreCase) && !Path.GetExtension(f).Equals(".swr", StringComparison.OrdinalIgnoreCase))
+ .ToList();
+ if (files.Any(f => !Path.GetFileName(f).Equals("_._")))
+ {
+ sb.Append(@"folder ""InstallDir:\");
+ // remove the version number and everything until we get to the real analyzers folder
+ Console.WriteLine(swrInstallDir);
+
+ var startIndex = swrInstallDir.IndexOf("analyzers", StringComparison.OrdinalIgnoreCase);
+ var endIndex = swrInstallDir.IndexOf("analyzers", startIndex + 1, StringComparison.OrdinalIgnoreCase);
+ var tempinstalldir = swrInstallDir;
+ if (startIndex >= 0 && endIndex >= 0)
+ {
+ tempinstalldir = swrInstallDir.Remove(startIndex + 9, endIndex - startIndex );
+ }
+ sb.Append(tempinstalldir);
+ sb.AppendLine(@"\""");
+
+ foreach (var file in files)
+ {
+ sb.Append(@" file source=""$(PkgVS_Redist_Common_Net_Core_SDK_RuntimeAnalyzers)\");
+ sb.Append(Path.Combine(relativeSourcePath, Path.GetFileName(file)));
+ sb.Append('"');
+
+ if (ngenAssemblies && file.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
+ {
+ sb.Append(@" vs.file.ngenApplications=""[installDir]\Common7\IDE\vsn.exe""");
+ }
+
+ sb.AppendLine();
+ }
+
+ sb.AppendLine();
+ }
+
+ foreach (var subfolder in Directory.GetDirectories(sourceFolder))
+ {
+ string subfolderName = Path.GetFileName(subfolder);
+ string newRelativeSourcePath = Path.Combine(relativeSourcePath, subfolderName);
+ string newSwrInstallDir = Path.Combine(swrInstallDir, subfolderName);
+
+ // Don't propagate ngenAssemblies to subdirectories.
+ AddFolder(sb, newRelativeSourcePath, newSwrInstallDir);
+ }
+ }
+
+ readonly string SWR_HEADER = @"use vs
+
+package name=Microsoft.Net.Core.SDK.RuntimeAnalyzers
+ version=$(ProductsBuildVersion)
+ vs.package.internalRevision=$(PackageInternalRevision)
+
+";
+ }
+}
diff --git a/src/Installer/redist-installer/packaging/windows/VS.Redist.Common.Net.Core.SDK.RuntimeAnalyzers.nuspec b/src/Installer/redist-installer/packaging/windows/VS.Redist.Common.Net.Core.SDK.RuntimeAnalyzers.nuspec
new file mode 100644
index 000000000000..b3a7b71cd697
--- /dev/null
+++ b/src/Installer/redist-installer/packaging/windows/VS.Redist.Common.Net.Core.SDK.RuntimeAnalyzers.nuspec
@@ -0,0 +1,17 @@
+
+
+ VS.Redist.Common.Net.Core.SDK.RuntimeAnalyzers
+ 1.0.0
+ VS.Redist.Common.Net.Core.SDK.RuntimeAnalyzers
+ Microsoft
+ Microsoft
+ https://www.microsoft.com/net/dotnet_library_license.htm
+ https://github.com/dotnet/sdk
+ true
+ Analyzers and generators from the runtime and SDK for VS insertion
+ © Microsoft Corporation. All rights reserved.
+
+
+
+
+
diff --git a/src/Installer/redist-installer/redist-installer.csproj b/src/Installer/redist-installer/redist-installer.csproj
index 311563a2d562..6f16be86da32 100644
--- a/src/Installer/redist-installer/redist-installer.csproj
+++ b/src/Installer/redist-installer/redist-installer.csproj
@@ -43,6 +43,7 @@
+
diff --git a/src/Installer/redist-installer/targets/BuildCoreSdkTasks.targets b/src/Installer/redist-installer/targets/BuildCoreSdkTasks.targets
index ce51df4b4116..9927e46d9799 100644
--- a/src/Installer/redist-installer/targets/BuildCoreSdkTasks.targets
+++ b/src/Installer/redist-installer/targets/BuildCoreSdkTasks.targets
@@ -32,6 +32,7 @@
+
diff --git a/src/Installer/redist-installer/targets/GenerateMSIs.targets b/src/Installer/redist-installer/targets/GenerateMSIs.targets
index c3809e3e221d..c7114062db33 100644
--- a/src/Installer/redist-installer/targets/GenerateMSIs.targets
+++ b/src/Installer/redist-installer/targets/GenerateMSIs.targets
@@ -37,6 +37,10 @@
$(ArtifactsNonShippingPackagesDir)VS.Redist.Common.Net.Core.SDK.MSBuildExtensions.$(FullNugetVersion).nupkg
$(ArtifactsNonShippingPackagesDir)VS.Redist.Common.Net.Core.SDK.MSBuildExtensions.swr
+ $(SdkPkgSourcesRootDirectory)/VS.Redist.Common.Net.Core.SDK.RuntimeAnalyzers.nuspec
+ $(ArtifactsNonShippingPackagesDir)VS.Redist.Common.Net.Core.SDK.RuntimeAnalyzers.$(FullNugetVersion).nupkg
+ $(ArtifactsNonShippingPackagesDir)VS.Redist.Common.Net.Core.SDK.RuntimeAnalyzers.swr
+
$(ArtifactsDir)bin/VSTemplateLocator/$(Configuration)
$(SdkPkgSourcesRootDirectory)/VS.Redist.Common.Net.Core.SDK.VSTemplateLocator.nuspec
$(ArtifactsNonShippingPackagesDir)VS.Redist.Common.Net.Core.SDK.VSTemplateLocator.$(FullNugetVersion).nupkg
@@ -497,6 +501,27 @@
'$(SdkMSBuildExtensionsNupkgFile)'" />
+
+
+
+
+
+
+
+
+