diff --git a/src/Cli/dotnet/CommonLocalizableStrings.resx b/src/Cli/dotnet/CommonLocalizableStrings.resx index 58c9371ccd01..1f5b5e8107bc 100644 --- a/src/Cli/dotnet/CommonLocalizableStrings.resx +++ b/src/Cli/dotnet/CommonLocalizableStrings.resx @@ -735,5 +735,23 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + - + \ No newline at end of file diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index ede94d7056b2..8ebe1a046b35 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -12,6 +12,7 @@ using NuGet.Protocol; using NuGet.Protocol.Core.Types; using NuGet.Versioning; +using Microsoft.DotNet.Cli; namespace Microsoft.DotNet.Cli.NuGetPackageDownloader { @@ -132,17 +133,11 @@ public async Task DownloadPackageAsync(PackageId packageId, return nupkgPath; } - private bool verbosityGreaterThanMinimal() - { - return _verbosityOptions != VerbosityOptions.quiet && _verbosityOptions != VerbosityOptions.q - && _verbosityOptions != VerbosityOptions.minimal && _verbosityOptions != VerbosityOptions.m; - } - private void VerifySigning(string nupkgPath) { if (!_verifySignatures && !_validationMessagesDisplayed) { - if (verbosityGreaterThanMinimal()) + if (!(_verbosityOptions.IsQuiet() || _verbosityOptions.IsMinimal())) { _reporter.WriteLine(LocalizableStrings.NuGetPackageSignatureVerificationSkipped); } diff --git a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs index 45a72e6aadf6..3d966a23c20c 100644 --- a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Threading.Tasks; using Microsoft.DotNet.ToolPackage; using NuGet.Versioning; @@ -15,7 +14,8 @@ IToolPackage InstallPackage(PackageLocation packageLocation, VersionRange versionRange = null, string targetFramework = null, bool isGlobalTool = false, - bool isGlobalToolRollForward = false + bool isGlobalToolRollForward = false, + bool forceInstall = false ); NuGetVersion GetNuGetVersion( diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index cca3de9bba0c..a96518266b6c 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -1,14 +1,7 @@ // 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. -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.CommandLine; using System.Reflection; -using System.Runtime.InteropServices; -using System.Threading.Tasks; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; @@ -27,10 +20,9 @@ using NuGet.Versioning; using NuGet.Configuration; using Microsoft.TemplateEngine.Utils; -using System.Text.Json; -using System.Xml; -using System.Text.Json.Nodes; using Newtonsoft.Json.Linq; +using System.Text.Json; +using static Microsoft.DotNet.NativeWrapper.NETCoreSdkResolverNativeWrapper; namespace Microsoft.DotNet.Cli.ToolPackage { @@ -77,7 +69,8 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa VersionRange versionRange = null, string targetFramework = null, bool isGlobalTool = false, - bool isGlobalToolRollForward = false + bool isGlobalToolRollForward = false, + bool forceInstall = false ) { var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); @@ -111,7 +104,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa } NuGetVersion packageVersion = nugetPackageDownloader.GetBestPackageVersionAsync(packageId, versionRange, packageSourceLocation).GetAwaiter().GetResult(); - rollbackDirectory = isGlobalTool ? toolDownloadDir.Value: Path.Combine(toolDownloadDir.Value, packageId.ToString(), packageVersion.ToString()); + rollbackDirectory = isGlobalTool ? toolDownloadDir.Value : Path.Combine(toolDownloadDir.Value, packageId.ToString(), packageVersion.ToString()); if (isGlobalTool) { @@ -134,7 +127,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa { DownloadAndExtractPackage(packageId, nugetPackageDownloader, toolDownloadDir.Value, packageVersion, packageSourceLocation, includeUnlisted: givenSpecificVersion).GetAwaiter().GetResult(); } - else if(isGlobalTool) + else if (isGlobalTool) { throw new ToolPackageException( string.Format( @@ -142,9 +135,9 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa packageId, packageVersion.ToNormalizedString())); } - + CreateAssetFile(packageId, packageVersion, toolDownloadDir, assetFileDirectory, _runtimeJsonPath, targetFramework); - + DirectoryPath toolReturnPackageDirectory; DirectoryPath toolReturnJsonParentDirectory; @@ -168,12 +161,17 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa packageDirectory: toolReturnPackageDirectory, assetsJsonParentDirectory: toolReturnJsonParentDirectory); + if (!forceInstall && !isGlobalToolRollForward) + { + CheckIfRequiredRuntimeIsInstalled(toolPackageInstance, packageId, isGlobalTool); + } + if (isGlobalToolRollForward) { UpdateRuntimeConfig(toolPackageInstance); } - return toolPackageInstance; + return toolPackageInstance; }, rollback: () => { @@ -190,6 +188,44 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa }); } + private static void CheckIfRequiredRuntimeIsInstalled( + ToolPackageInstance toolPackageInstance, + PackageId packageId, + bool isGlobalTool + ) + { + var executableFilePath = toolPackageInstance.Commands[0].Executable; + var runtimeConfigFilePath = Path.ChangeExtension(executableFilePath.ToString(), ".runtimeconfig.json"); + + // Check if the runtimeconfig.json file is compatible with the current runtime + if (File.Exists(runtimeConfigFilePath)) + { + string tfmValue = ""; + JsonElement rootElement = JsonDocument.Parse(File.ReadAllText(runtimeConfigFilePath)).RootElement; + + if (rootElement.TryGetProperty("runtimeOptions", out JsonElement runtimeOptionsElement) && + runtimeOptionsElement.TryGetProperty("tfm", out JsonElement tfmElement)) + { + tfmValue = new string(tfmElement.GetString().Where(c => char.IsDigit(c) || c == '.').ToArray()); + } + var result = InitializeForRuntimeConfig(runtimeConfigFilePath); + + // Error if tool is incompatible + var global = isGlobalTool ? " -g" : ""; + switch (result) + { + case InitializationRuntimeConfigResult.Success: + break; + + default: + throw new GracefulException( + string.Format( + CommonLocalizableStrings.ToolPackageRuntimeConfigIncompatible, + packageId, tfmValue, global)); + } + } + } + // The following methods are copied from the LockFileUtils class in Nuget.Client private static void AddToolsAssets( ManagedCodeConventions managedCodeConventions, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx index 11ab99870bff..801a483a832c 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx @@ -247,4 +247,7 @@ If you would like to create a manifest, use the `--create-manifest-if-needed` fl Allow package downgrade when installing a .NET tool package. + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs index 3c21b0c5bd19..c7e01f8a99c0 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs @@ -57,7 +57,12 @@ internal static class ToolInstallCommandParser public static readonly CliOption AllowPackageDowngradeOption = new("--allow-downgrade") { Description = LocalizableStrings.AllowPackageDowngradeOptionDescription - }; + }; + + public static readonly CliOption ForceInstallOption = new("--force") + { + Description = LocalizableStrings.ForceInstallOptionName + }; public static readonly CliOption VerbosityOption = CommonOptions.VerbosityOption; @@ -98,6 +103,7 @@ private static CliCommand ConstructCommand() command.Options.Add(CreateManifestIfNeededOption); command.Options.Add(AllowPackageDowngradeOption); command.Options.Add(RollForwardOption); + command.Options.Add(ForceInstallOption); command.SetAction((parseResult) => new ToolInstallCommand(parseResult).Execute()); diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 870a87cee6b7..e27f6ef069d3 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -48,7 +48,7 @@ internal class ToolInstallGlobalOrToolPathCommand : CommandBase private readonly bool _allowRollForward; private readonly bool _allowPackageDowngrade; private readonly bool _updateAll; - + private readonly bool _forceInstall; public ToolInstallGlobalOrToolPathCommand( ParseResult parseResult, @@ -95,6 +95,7 @@ public ToolInstallGlobalOrToolPathCommand( _createToolPackageStoreDownloaderUninstaller = createToolPackageStoreDownloaderUninstaller ?? ToolPackageFactory.CreateToolPackageStoresAndDownloaderAndUninstaller; _updateAll = parseResult.GetValue(ToolUpdateCommandParser.UpdateAllOption); + _forceInstall = parseResult.GetValue(ToolInstallCommandParser.ForceInstallOption); _reporter = (reporter ?? Reporter.Output); } @@ -190,7 +191,8 @@ private int ExecuteInstallCommand(PackageId packageId) targetFramework: _framework, verbosity: _verbosity, isGlobalTool: true, - isGlobalToolRollForward: _allowRollForward + isGlobalToolRollForward: _allowRollForward, + forceInstall: _forceInstall ); EnsureVersionIsHigher(oldPackageNullable, newInstalledPackage, _allowPackageDowngrade); diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs index 0fc97b6afc15..e988af922fab 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs @@ -22,6 +22,7 @@ internal class ToolInstallLocalCommand : CommandBase private readonly IReporter _reporter; private readonly PackageId? _packageId; private readonly bool _allowPackageDowngrade; + private readonly bool _forceInstall; private readonly string _explicitManifestFile; private readonly bool _createManifestIfNeeded; @@ -56,6 +57,7 @@ public ToolInstallLocalCommand( _toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageDownloader, runtimeJsonPathForTests); _allowRollForward = parseResult.GetValue(ToolInstallCommandParser.RollForwardOption); _allowPackageDowngrade = parseResult.GetValue(ToolInstallCommandParser.AllowPackageDowngradeOption); + _forceInstall = parseResult.GetValue(ToolInstallCommandParser.ForceInstallOption); } public override int Execute() @@ -93,11 +95,11 @@ private int ExecuteInstallCommand(PackageId packageId) if (!existingPackageWithPackageId.Any()) { - return InstallNewTool(manifestFile, packageId); + return InstallNewTool(manifestFile, packageId, _forceInstall); } var existingPackage = existingPackageWithPackageId.Single(); - var toolDownloadedPackage = _toolLocalPackageInstaller.Install(manifestFile, packageId); + var toolDownloadedPackage = _toolLocalPackageInstaller.Install(manifestFile, packageId, _forceInstall); InstallToolUpdate(existingPackage, toolDownloadedPackage, manifestFile, packageId); @@ -154,10 +156,10 @@ public int InstallToolUpdate(ToolManifestPackage existingPackage, IToolPackage t return 0; } - public int InstallNewTool(FilePath manifestFile, PackageId packageId) + public int InstallNewTool(FilePath manifestFile, PackageId packageId, bool forceInstall) { IToolPackage toolDownloadedPackage = - _toolLocalPackageInstaller.Install(manifestFile, packageId); + _toolLocalPackageInstaller.Install(manifestFile, packageId, forceInstall); _toolManifestEditor.Add( manifestFile, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs index 118577482a12..a69140c8a288 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs @@ -42,7 +42,7 @@ public ToolInstallLocalInstaller( TargetFrameworkToInstall = BundledTargetFramework.GetTargetFrameworkMoniker(); } - public IToolPackage Install(FilePath manifestFile, PackageId packageId) + public IToolPackage Install(FilePath manifestFile, PackageId packageId, bool forceInstall) { if (!string.IsNullOrEmpty(_configFilePath) && !File.Exists(_configFilePath)) { @@ -70,7 +70,8 @@ public IToolPackage Install(FilePath manifestFile, PackageId packageId) packageId, verbosity: _verbosity, versionRange, - TargetFrameworkToInstall + TargetFrameworkToInstall, + forceInstall: forceInstall ); return toolDownloadedPackage; diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf index 37740a6c631e..a23a2e810638 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf @@ -12,6 +12,11 @@ Vytvořte manifest nástroje, pokud se nějaký nenajde během instalace nástroje. Informace o tom, jak se manifesty nacházejí, najdete v tématu https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. Možnost local (--local), možnost global (--global), možnost tool path (--tool-path), v jednu chvíli je možné mít jen jednu. Zadejte jen jednu z možností: {0} diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf index 4ace782842f9..d29f72d7a83f 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf @@ -12,6 +12,11 @@ Erstellen Sie ein Toolmanifest, wenn es während der Toolinstallation nicht gefunden wird. Informationen dazu, wie Manifeste gefunden werden, finden Sie unter https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. Die lokale Option (--local), die globale Option (--global) und die Toolpfadoption (--tool-path) können nicht zusammen angegeben werden. Geben Sie nur eine der Optionen an: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf index bb88aa3fe12d..4524c85278d5 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf @@ -12,6 +12,11 @@ Cree un manifiesto de herramienta si no se encuentra ninguno durante la instalación de la herramienta. Para obtener información sobre cómo se encuentran los manifiestos, consulte https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. La opción local (--local), la opción global (--global) y la opción de ruta de acceso de herramienta (--tool-path), solo pueden estar una cada vez. Especifique solo una de las opciones: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf index 5b63ced51669..3cc96cd6f742 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf @@ -12,6 +12,11 @@ Créez un manifeste d'outil si aucun n'est trouvé lors de l'installation de l'outil. Pour plus d'informations sur la localisation des manifestes, voir https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. L'option locale (--local), l'option globale (--global) et l'option de chemin d'outil (--tool-path) ne peuvent pas être utilisées simultanément. Spécifiez une seule des options : {0}. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf index c95e8ceccd16..835a05520af7 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf @@ -12,6 +12,11 @@ Creare un manifesto dello strumento se non ne viene trovato uno durante l'installazione dello strumento. Per informazioni sulla posizione dei manifesti, vedere https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. Le opzioni locale (--local), globale (--global) e del percorso dello strumento (--tool-path) non possono essere specificate contemporaneamente. Specificare una sola di queste opzioni: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf index d00ed60df6c7..faf542824a90 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf @@ -12,6 +12,11 @@ ツールのインストール中にツール マニフェスト見つからない場合は作成します。マニフェストの場所については、https://aka.ms/dotnet/tools/create-manifest-if-needed を参照してください + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. ローカル オプション (--local)、グローバル オプション (--global)、ツール パス オプション (--tool-path) は、一度に 1 つだけ指定できます。オプションを 1 つだけ指定します: {0}。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf index 126ec51e5c37..7f87329583fc 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf @@ -12,6 +12,11 @@ 도구 설치 중에 도구 매니페스트를 찾을 수 없는 경우 도구 매니페스트를 만드세요. 매니페스트의 위치는 https://aka.ms/dotnet/tools/create-manifest-if-needed를 참조하세요. + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. 로컬 옵션(--local), 전역 옵션(--global), 도구 경로 옵션(--tool-path)은 한 번에 하나씩만 사용할 수 있습니다. {0} 옵션 중에서 하나만 지정하세요. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf index 53b06a06207e..70f9d6c0d502 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf @@ -12,6 +12,11 @@ Utwórz manifest narzędzi, jeśli nie zostanie znaleziony podczas instalacji narzędzia. Aby uzyskać informacje o lokalizacji manifestów, zobacz https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. Można określić tylko jedną opcję jednocześnie: opcję lokalną (--local), opcję globalną (--global) lub opcję ścieżki do narzędzia (--tool-path). Podaj tylko jedną z opcji: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf index b93c40e8c678..e8939012f862 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf @@ -12,6 +12,11 @@ Crie um manifesto de ferramenta se nenhum for encontrado durante a instalação da ferramenta. Para obter informações sobre como os manifestos estão localizados, consulte https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. As opções local (--local), global (--global) e do caminho da ferramenta (--tool-path) só podem ocorrer uma por vez. Especifique apenas uma das opções: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf index 63060d26744d..1e6bc66b26da 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf @@ -12,6 +12,11 @@ Создайте манифест инструмента, если он не найден во время установки инструмента. Сведения о способе размещения манифестов см. на странице https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. Локальный параметр (--local), глобальный параметр (--global) и параметр пути к средству (--tool-path) можно использовать только отдельно друг от друга. Укажите только один из этих параметров: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf index c24889bcfccb..db22169c4a26 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf @@ -12,6 +12,11 @@ Araç yüklemesi sırasında bir araç bildirimi bulunmazsa bir araç bildirimi oluşturun. Bildirimlerin nasıl bulunduğu hakkında bilgi edinmek için bkz. https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. Yerel seçeneği (--local), genel seçeneği (--global), araç yolu seçeneği (--tool-path) arasından yalnızca biri seçilebilir. Seçeneklerden yalnızca birini belirtin: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf index 208d83cfd110..8048a037f613 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -12,6 +12,11 @@ 如果在工具安装期间找不到工具清单,请创建一个工具清单。若要了解如何查找清单,请参阅 https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. 本地选项(--local)、全局选项(--global)和工具路径选项(--tool-path)一次只能有一个。请仅指定其中一个选项: {0}。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf index fc5be8760f22..aefc5088519d 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -12,6 +12,11 @@ 如果在工具安裝期間找不到工具資訊清單,則建立工具資訊清單。如需如何尋找資訊清單的相關資訊,請參閱 https://aka.ms/dotnet/tools/create-manifest-if-needed + + Forces a tool to be installed even if a compatible .NET runtime is not installed. + Forces a tool to be installed even if a compatible .NET runtime is not installed. + + The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}. 一次只能有一個本機選項 (--local)、全域選項 (--global)、工具路徑選項 (--tool-path)。請僅指定其中一個選項: {0}。 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf index 8ae7960c4016..a228e02e12ac 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf @@ -284,7 +284,42 @@ Výchozí hodnota je false, ale pokud cílíte na .NET 7 nebo nižší a je zad Tool settings file does not exist for the tool {0}. - Soubor nastavení nástroje {0} neexistuje. + Soubor nastavení nástroje {0} neexistuje. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf index e8aed6ea1205..229490475797 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf @@ -284,7 +284,42 @@ Der Standardwert lautet FALSE. Wenn sie jedoch auf .NET 7 oder niedriger abziele Tool settings file does not exist for the tool {0}. - Die Tooleinstellungsdatei ist für das Tool „{0}“ nicht vorhanden. + Die Tooleinstellungsdatei ist für das Tool „{0}“ nicht vorhanden. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf index d0456889ad38..e2ca2a06609c 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf @@ -285,7 +285,42 @@ El valor predeterminado es "false". Sin embargo, cuando el destino es .NET 7 o i Tool settings file does not exist for the tool {0}. - El archivo de configuración de herramientas no existe para la herramienta {0}. + El archivo de configuración de herramientas no existe para la herramienta {0}. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf index da5f2b48c79d..6ef935327ab9 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf @@ -285,7 +285,42 @@ La valeur par défaut est « false ». Toutefois, lorsque vous ciblez .NET 7 ou Tool settings file does not exist for the tool {0}. - Le fichier de paramètres d’outil n’existe pas pour l’outil {0}. + Le fichier de paramètres d’outil n’existe pas pour l’outil {0}. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf index 84b8e63f7b0d..4fa1ea1df071 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf @@ -284,7 +284,42 @@ Il valore predefinito è 'false'. Tuttavia, quando la destinazione è .NET 7 o u Tool settings file does not exist for the tool {0}. - Il file delle impostazioni dello strumento non esiste per lo strumento {0}. + Il file delle impostazioni dello strumento non esiste per lo strumento {0}. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf index 955e9cfc91e8..9f1edd4dd046 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf @@ -284,7 +284,42 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - ツール {0} のツール設定ファイルが存在しません。 + ツール {0} のツール設定ファイルが存在しません。 + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf index d26185296366..b602612b915d 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf @@ -285,7 +285,42 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - 도구 {0}에 대한 도구 설정 파일이 없습니다. + 도구 {0}에 대한 도구 설정 파일이 없습니다. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf index 091c83288270..c2033bc7b573 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf @@ -284,7 +284,42 @@ Wartość domyślna to „false”. Jednak w przypadku określania wartości doc Tool settings file does not exist for the tool {0}. - Plik ustawień narzędzia nie istnieje dla narzędzia {0}. + Plik ustawień narzędzia nie istnieje dla narzędzia {0}. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf index 2a82fe3a1562..ea453c0cc5c0 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf @@ -284,7 +284,42 @@ O padrão é falso.' No entanto, ao direcionar o .NET 7 ou inferior, o padrão Tool settings file does not exist for the tool {0}. - O arquivo de configurações de ferramenta não existe para a ferramenta {0}. + O arquivo de configurações de ferramenta não existe para a ferramenta {0}. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf index 30524ccfe60c..aa173c999b86 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf @@ -284,7 +284,42 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - Файл параметров для средства {0} не существует. + Файл параметров для средства {0} не существует. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf index 2cd50917f9fc..0e879aac3289 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf @@ -284,7 +284,42 @@ Varsayılan değer 'false' olur. Ancak çalışma zamanı tanımlayıcısı beli Tool settings file does not exist for the tool {0}. - {0} aracı için araç ayarları dosyası mevcut değil. + {0} aracı için araç ayarları dosyası mevcut değil. + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf index 2345a2ae6ecd..adf25f959333 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf @@ -284,7 +284,42 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - 工具 {0} 的工具设置文件不存在。 + 工具 {0} 的工具设置文件不存在。 + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf index aff0bb272f7f..4f46eb3ba6d0 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf @@ -284,7 +284,42 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - 工具 {0} 沒有工具設定檔案。 + 工具 {0} 沒有工具設定檔案。 + + + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + + Installation failed. + +This app wasn't installed because it requires .NET {1} to run, which is not installed. This can be resolved by one of the following: + +1. Install .NET {1} with the following link + +https://aka.ms/dotnet/download/sdk + +2. Install with the `--allow-roll-forward` flag, using with the following command. + +dotnet tool install {0}{2} --allow-roll-forward + +3. Install with `--force` and manually configure the tool to run, using with the following command. + +dotnet tool install {0}{2} --force + diff --git a/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs b/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs index 98769e68e2df..cc2818168b72 100644 --- a/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs +++ b/src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs @@ -149,6 +149,12 @@ internal static extern int hostfxr_resolve_sdk2( hostfxr_resolve_sdk2_flags_t flags, hostfxr_resolve_sdk2_result_fn result); + [DllImport(Constants.HostFxr, CharSet = UTF16, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + internal static extern int hostfxr_initialize_for_runtime_config( + string runtime_config_path, + IntPtr parameters, + out IntPtr host_context_handle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = UTF16)] internal delegate void hostfxr_get_available_sdks_result_fn( int sdk_count, @@ -179,6 +185,12 @@ internal static extern int hostfxr_resolve_sdk2( hostfxr_resolve_sdk2_flags_t flags, hostfxr_resolve_sdk2_result_fn result); + [DllImport(Constants.HostFxr, CharSet = UTF8, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + internal static extern int hostfxr_initialize_for_runtime_config( + string runtime_config_path, + IntPtr parameters, + out IntPtr host_context_handle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = UTF8)] internal delegate void hostfxr_get_available_sdks_result_fn( int sdk_count, diff --git a/src/Resolvers/Microsoft.DotNet.NativeWrapper/NETCoreSdkResolverNativeWrapper.cs b/src/Resolvers/Microsoft.DotNet.NativeWrapper/NETCoreSdkResolverNativeWrapper.cs index 340d5c042f26..42d12b11be0e 100644 --- a/src/Resolvers/Microsoft.DotNet.NativeWrapper/NETCoreSdkResolverNativeWrapper.cs +++ b/src/Resolvers/Microsoft.DotNet.NativeWrapper/NETCoreSdkResolverNativeWrapper.cs @@ -1,13 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; +using System.Diagnostics.Contracts; #pragma warning disable IDE0240 // Remove redundant nullable directive #nullable enable #pragma warning restore IDE0240 // Remove redundant nullable directive -using System.Diagnostics; - namespace Microsoft.DotNet.NativeWrapper { public static class NETCoreSdkResolverNativeWrapper @@ -50,5 +50,46 @@ public void Initialize(int count, string[] entries) return list.Entries; } + + [StructLayout(LayoutKind.Sequential)] + internal struct hostfxr_initialize_parameters + { + + } + + public enum InitializationRuntimeConfigResult + { + Success, + RuntimeConfigNotFound, + } + + public static InitializationRuntimeConfigResult InitializeForRuntimeConfig(string runtimeConfigPath) + { + var result = -1; + IntPtr hostContextHandle = default; + + hostfxr_initialize_parameters parameters = new hostfxr_initialize_parameters(); + + IntPtr parametersPtr = Marshal.AllocHGlobal(Marshal.SizeOf(parameters)); + Marshal.StructureToPtr(parameters, parametersPtr, false); + + if (File.Exists(runtimeConfigPath)) + { + result = Interop.RunningOnWindows + ? Interop.Windows.hostfxr_initialize_for_runtime_config(runtimeConfigPath, default, out hostContextHandle) + : Interop.Unix.hostfxr_initialize_for_runtime_config(runtimeConfigPath, default, out hostContextHandle); + } + + Marshal.FreeHGlobal(parametersPtr); + switch (result) + { + case 0: + case 1: + case 2: + return InitializationRuntimeConfigResult.Success; + default: + return InitializationRuntimeConfigResult.RuntimeConfigNotFound; + } + } } } diff --git a/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs b/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs index c90f99f21609..6a3a1eac45ae 100644 --- a/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs +++ b/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs @@ -54,6 +54,7 @@ public void GivenNugetConfigInstallSucceeds(bool testMockBehaviorIsInSync) verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -82,6 +83,7 @@ public void GivenNugetConfigInstallSucceedsInTransaction(bool testMockBehaviorIs verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); transactionScope.Complete(); @@ -108,6 +110,7 @@ public void GivenNugetConfigInstallCreatesAnAssetFile(bool testMockBehaviorIsInS verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -171,6 +174,7 @@ public void GivenAConfigFileRootDirectoryPackageInstallSucceedsViaFindingNugetCo verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -241,6 +245,7 @@ public void GivenAllButNoPackageVersionItCanInstallThePackage(bool testMockBehav packageId: TestPackageId, verbosity: TestVerbosity, targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -263,6 +268,7 @@ public void GivenAllButNoTargetFrameworkItCanDownloadThePackage(bool testMockBeh packageId: TestPackageId, verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -286,6 +292,7 @@ public void GivenASourceInstallSucceeds(bool testMockBehaviorIsInSync) verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -310,6 +317,7 @@ public void GivenARelativeSourcePathInstallSucceeds(bool testMockBehaviorIsInSyn verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -333,6 +341,7 @@ public void GivenAUriSourceInstallSucceeds(bool testMockBehaviorIsInSync) verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -359,6 +368,7 @@ public void GivenAEmptySourceAndNugetConfigInstallSucceeds(bool testMockBehavior verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -390,6 +400,7 @@ public void GivenFailureAfterRestoreInstallWillRollback(bool testMockBehaviorIsI verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); FailedStepAfterSuccessRestore(); @@ -424,6 +435,7 @@ public void GivenSecondInstallInATransactionTheFirstInstallShouldRollback(bool t verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); first.Should().NotThrow(); @@ -433,6 +445,7 @@ public void GivenSecondInstallInATransactionTheFirstInstallShouldRollback(bool t verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); t.Complete(); @@ -474,7 +487,8 @@ public void GivenFailureWhenInstallLocalToolsItWillRollbackPackageVersion(bool t packageId: TestPackageId, verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + forceInstall: true); fileSystem .Directory @@ -554,6 +568,7 @@ public void GivenSecondInstallWithoutATransactionTheFirstShouldNotRollback(bool verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -563,6 +578,7 @@ public void GivenSecondInstallWithoutATransactionTheFirstShouldNotRollback(bool verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); reporter.Lines.Should().BeEmpty(); @@ -606,6 +622,7 @@ public void GivenAnInstalledPackageUninstallRemovesThePackage(bool testMockBehav verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -632,6 +649,7 @@ public void GivenAnInstalledPackageUninstallRollsbackWhenTransactionFails(bool t verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -667,6 +685,7 @@ public void GivenAnInstalledPackageUninstallRemovesThePackageWhenTransactionComm verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -697,6 +716,7 @@ public void GivenAPackageNameWithDifferentCaseItCanInstallThePackage(bool testMo packageId: new PackageId("GlObAl.TooL.coNsoLe.DemO"), verbosity: TestVerbosity, targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -729,6 +749,7 @@ public void GivenARootWithNonAsciiCharacterInstallSucceeds() verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, store); @@ -757,6 +778,7 @@ public void GivenAComplexVersionRangeInstallSucceeds(bool testMockBehaviorIsInSy verbosity: TestVerbosity, versionRange: VersionRange.Parse("1.0.0-rc*"), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -809,6 +831,7 @@ public void GivenAPackageWithCasingAndenUSPOSIXInstallSucceeds(bool testMockBeha verbosity: TestVerbosity, versionRange: VersionRange.Parse(packageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); action.Should().NotThrow(); diff --git a/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs b/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs index 3fb9ac8addfc..7bc291423718 100644 --- a/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs +++ b/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs @@ -43,7 +43,8 @@ public void GivenNugetConfigInstallSucceeds(bool testMockBehaviorIsInSync) verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), packageLocation: new PackageLocation(nugetConfig: nugetConfigPath), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + forceInstall: true); var commands = toolPackage.Commands; var expectedPackagesFolder = NuGetGlobalPackagesFolder.GetLocation(); @@ -81,7 +82,8 @@ public void GivenNugetConfigVersionRangeInstallSucceeds(bool testMockBehaviorIsI verbosity: TestVerbosity, versionRange: VersionRange.Parse("1.0.0-*"), packageLocation: new PackageLocation(nugetConfig: nugetConfigPath), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + forceInstall: true); var expectedPackagesFolder = NuGetGlobalPackagesFolder.GetLocation(); diff --git a/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs b/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs index e95f28b38cb3..2464360f35b6 100644 --- a/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs +++ b/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs @@ -33,6 +33,7 @@ public void GivenAnInstalledPackageUninstallRemovesThePackage(bool testMockBehav verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, + forceInstall: true, isGlobalTool: true); package.PackagedShims.Should().ContainSingle(f => f.Value.Contains("demo.exe") || f.Value.Contains("demo")); diff --git a/test/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/test/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index 5ebf4181403c..4ef0568c6e24 100644 --- a/test/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/test/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -97,7 +97,8 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa VersionRange versionRange = null, string targetFramework = null, bool isGlobalTool = false, - bool isGlobalToolRollForward = false + bool isGlobalToolRollForward = false, + bool forceInstall = false ) { string rollbackDirectory = null; diff --git a/test/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs b/test/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs index 1c4ac7418be7..654c9732b9dd 100644 --- a/test/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs +++ b/test/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs @@ -42,6 +42,7 @@ public class ToolInstallGlobalOrToolPathCommandTests: SdkTest private const string LowerPackageVersion = "1.0.0"; private const string ToolCommandName = "SimulatorCommand"; private readonly string UnlistedPackageId = "elemental.sysinfotool"; + private readonly string CompatiblePackageId = "dotnet-ef"; public ToolInstallGlobalOrToolPathCommandTests(ITestOutputHelper log): base(log) { @@ -611,7 +612,8 @@ public void WhenRunWithValidUnlistedVersionRangeItShouldSucceed() const string nugetSourcePath = "https://api.nuget.org/v3/index.json"; var testDir = _testAssetsManager.CreateTestDirectory().Path; - var toolInstallGlobalOrToolPathCommand = new DotnetCommand(Log, "tool", "install", "-g", UnlistedPackageId, "--version", "[0.5.0]", "--add-source", nugetSourcePath) + // This test also validates that the tool install command can install incompatible tools with the --force option + var toolInstallGlobalOrToolPathCommand = new DotnetCommand(Log, "tool", "install", "-g", UnlistedPackageId, "--version", "[0.5.0]", "--add-source", nugetSourcePath, "--force") .WithEnvironmentVariable("DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK", "true") .WithWorkingDirectory(testDir); @@ -623,7 +625,7 @@ public void WhenRunWithValidUnlistedVersionRangeItShouldSucceed() } [Fact] - public void WhenRunWithValidBareVersionItShouldInterpretAsNuGetExactVersion() + public void WhenInstallIncompatibleToolWithoutForceItShouldFail() { const string nugetSourcePath = "https://api.nuget.org/v3/index.json"; var testDir = _testAssetsManager.CreateTestDirectory().Path; @@ -632,6 +634,36 @@ public void WhenRunWithValidBareVersionItShouldInterpretAsNuGetExactVersion() .WithEnvironmentVariable("DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK", "true") .WithWorkingDirectory(testDir); + toolInstallGlobalOrToolPathCommand.Execute().Should().Fail() + .And.HaveStdErrContaining(string.Format( + CommonLocalizableStrings.ToolPackageRuntimeConfigIncompatible, + UnlistedPackageId, "2.1", " -g").Black()); + } + + [Fact] + public void WhenInstallCompatibleToolWithoutForceItShouldSucceed() + { + const string nugetSourcePath = "https://api.nuget.org/v3/index.json"; + var testDir = _testAssetsManager.CreateTestDirectory().Path; + + var toolInstallGlobalOrToolPathCommand = new DotnetCommand(Log, "tool", "install", "-g", CompatiblePackageId, "--add-source", nugetSourcePath) + .WithEnvironmentVariable("DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK", "true") + .WithWorkingDirectory(testDir); + + toolInstallGlobalOrToolPathCommand.Execute().Should().Pass(); + } + + + [Fact] + public void WhenRunWithValidBareVersionItShouldInterpretAsNuGetExactVersion() + { + const string nugetSourcePath = "https://api.nuget.org/v3/index.json"; + var testDir = _testAssetsManager.CreateTestDirectory().Path; + + var toolInstallGlobalOrToolPathCommand = new DotnetCommand(Log, "tool", "install", "-g", UnlistedPackageId, "--version", "0.5.0", "--add-source", nugetSourcePath, "--force") + .WithEnvironmentVariable("DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK", "true") + .WithWorkingDirectory(testDir); + toolInstallGlobalOrToolPathCommand.Execute().Should().Pass(); // Uninstall the unlisted package