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