| File: Commands\Workload\Install\WorkloadManifestUpdater.cs | Web Access |
| Project: src\sdk\src\Cli\dotnet\dotnet.csproj (dotnet) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable using System.Text.Json; using Microsoft.DotNet.Cli.Commands.Workload.Install.WorkloadInstallRecords; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Configurer; using Microsoft.DotNet.InternalAbstractions; using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.NET.Sdk.WorkloadManifestReader; namespace Microsoft.DotNet.Cli.Commands.Workload.Install; /// <summary> /// Shared background advertising-manifest entry points used by both the managed and Native AOT CLI. /// The managed <see cref="IWorkloadManifestUpdater"/> implementation is in the managed-only partial. /// </summary> internal partial class WorkloadManifestUpdater { public static readonly string WorkloadSetManifestId = "Microsoft.NET.Workloads"; /// <summary> /// Builds the narrow set of dependencies the background advertising-manifest update needs, without /// going through <see cref="WorkloadInstallerFactory"/> (i.e. without constructing the full /// <see cref="FileBasedInstaller"/>/<see cref="NetSdkMsiInstallerClient"/> installer or, on Windows, /// any elevated MSI IPC). /// </summary> private static WorkloadAdvertisingManifestUpdater GetAdvertisingUpdaterInstance(string userProfileDir) { var reporter = new NullReporter(); var dotnetPath = Path.GetDirectoryName(Environment.ProcessPath); var sdkVersion = Product.Version; var sdkFeatureBand = new SdkFeatureBand(sdkVersion); var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, sdkVersion, userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, dotnetPath, sdkVersion, userProfileDir); var tempPackagesDir = new DirectoryPath(TemporaryDirectory.CreateSubdirectory()); // NuGet verification uses ShouldVerifySignatures() (respects registry policy and host // signing status, but not --skip-sign-check since this is a background operation). // MSI verification is intentionally disabled — this updater only downloads advertising // manifests, not installable MSIs. var verifySignatures = WorkloadUtilities.ShouldVerifySignatures(); var nugetPackageDownloader = NuGetPackageDownloader.NuGetPackageDownloader.CreateForWorkloads( tempPackagesDir, verifySignatures, reporter: reporter); IWorkloadManifestInstaller manifestInstaller; IWorkloadInstallationRecordRepository workloadRecordRepo; if (WorkloadInstallType.GetWorkloadInstallType(sdkFeatureBand, dotnetPath) == InstallType.Msi) { #if !TARGET_WINDOWS throw new InvalidOperationException(CliCommandStrings.OSDoesNotSupportMsi); #else if (!OperatingSystem.IsWindows()) { throw new InvalidOperationException(CliCommandStrings.OSDoesNotSupportMsi); } manifestInstaller = WindowsMsiManifestInstaller.CreateForAdvertisingManifestUpdates(nugetPackageDownloader, out workloadRecordRepo); #endif } else { manifestInstaller = new FileBasedManifestInstaller(nugetPackageDownloader, tempPackagesDir); workloadRecordRepo = FileBasedWorkloadInstallationRecordRepositoryFactory.Create(dotnetPath, sdkFeatureBand, userProfileDir); } return new WorkloadAdvertisingManifestUpdater(reporter, workloadResolver, nugetPackageDownloader, userProfileDir, workloadRecordRepo, manifestInstaller, sdkFeatureBand: sdkFeatureBand); } public static async Task BackgroundUpdateAdvertisingManifestsAsync(string userProfileDir) { try { var advertisingUpdater = GetAdvertisingUpdaterInstance(userProfileDir); await advertisingUpdater.BackgroundUpdateAdvertisingManifestsWhenRequiredAsync(); } catch (Exception) { // Never surface messages on background updates } } public static bool ShouldUseWorkloadSetMode(SdkFeatureBand sdkFeatureBand, string dotnetDir) => WorkloadAdvertisingManifestUpdater.ShouldUseWorkloadSetMode(sdkFeatureBand, dotnetDir); public static void AdvertiseWorkloadUpdates() { try { var backgroundUpdatesDisabled = bool.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.WORKLOAD_UPDATE_NOTIFY_DISABLE), out var disableEnvVar) && disableEnvVar; SdkFeatureBand featureBand = new(Product.Version); var adUpdatesFile = WorkloadAdvertisingManifestUpdater.GetAdvertisingWorkloadsFilePath(CliFolderPathCalculator.DotnetUserProfileFolderPath, featureBand); if (!backgroundUpdatesDisabled && File.Exists(adUpdatesFile)) { var updatableWorkloads = JsonSerializer.Deserialize(File.ReadAllText(adUpdatesFile), WorkloadManifestUpdaterJsonSerializerContext.Default.StringArray); if (updatableWorkloads != null && updatableWorkloads.Any()) { Console.WriteLine(); Console.WriteLine(CliCommandStrings.WorkloadInstallWorkloadUpdatesAvailable); } } } catch (Exception) { // Never surface errors } } }