diff --git a/src/Cli/dotnet/CliStrings.resx b/src/Cli/dotnet/CliStrings.resx
index 58f8ae903efe..e3a268cf073f 100644
--- a/src/Cli/dotnet/CliStrings.resx
+++ b/src/Cli/dotnet/CliStrings.resx
@@ -416,6 +416,12 @@ setx PATH "%PATH%;{0}"
Settings file 'DotnetToolSettings.xml' was not found in the package.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
Tool '{0}' (version '{1}') is already installed.
diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstance.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstance.cs
index d17874fdb2c8..8253562c236d 100644
--- a/src/Cli/dotnet/ToolPackage/ToolPackageInstance.cs
+++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstance.cs
@@ -97,7 +97,7 @@ public ToolPackageInstance(PackageId id,
ResolvedPackageVersion = Version;
}
- var toolConfiguration = DeserializeToolConfiguration(library, packageDirectory, _fileSystem);
+ var toolConfiguration = DeserializeToolConfiguration(library, packageDirectory, ResolvedPackageId, _fileSystem);
Warnings = toolConfiguration.Warnings;
var installPath = new VersionFolderPathResolver(PackageDirectory.Value).GetInstallPath(ResolvedPackageId.ToString(), ResolvedPackageVersion);
@@ -165,17 +165,58 @@ public static ToolConfiguration GetToolConfiguration(PackageId id,
{
var lockFile = new LockFileFormat().Read(assetsJsonParentDirectory.WithFile(AssetsFileName).Value);
var lockFileTargetLibrary = FindLibraryInLockFile(lockFile);
- return DeserializeToolConfiguration(lockFileTargetLibrary, packageDirectory, fileSystem);
+ return DeserializeToolConfiguration(lockFileTargetLibrary, packageDirectory, id, fileSystem);
}
- private static ToolConfiguration DeserializeToolConfiguration(LockFileTargetLibrary library, DirectoryPath packageDirectory, IFileSystem fileSystem)
+ private static ToolConfiguration DeserializeToolConfiguration(LockFileTargetLibrary library, DirectoryPath packageDirectory, PackageId packageId, IFileSystem fileSystem)
{
try
{
var dotnetToolSettings = FindItemInTargetLibrary(library, ToolSettingsFileName);
if (dotnetToolSettings == null)
{
+ // Check if this is because of framework incompatibility
+ // Load available frameworks from the package to provide better error messages
+ var installPath = new VersionFolderPathResolver(packageDirectory.Value).GetInstallPath(library.Name, library.Version);
+ var toolsPackagePath = Path.Combine(installPath, "tools");
+
+ if (fileSystem.Directory.Exists(toolsPackagePath))
+ {
+ var availableFrameworks = fileSystem.Directory.EnumerateDirectories(toolsPackagePath)
+ .Select(path => NuGetFramework.ParseFolder(Path.GetFileName(path)))
+ .Where(f => f.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp)
+ .ToList();
+
+ if (availableFrameworks.Count > 0)
+ {
+ var currentFramework = new NuGetFramework(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, new Version(Environment.Version.Major, Environment.Version.Minor));
+
+ // Find the minimum framework version required by the tool
+ var minRequiredFramework = availableFrameworks.MinBy(f => f.Version);
+
+ // If all available frameworks require a higher version than current runtime
+ if (minRequiredFramework != null && minRequiredFramework.Version > currentFramework.Version)
+ {
+ var requiredVersionString = $".NET {minRequiredFramework.Version.Major}.{minRequiredFramework.Version.Minor}";
+ var currentVersionString = $".NET {currentFramework.Version.Major}.{currentFramework.Version.Minor}";
+
+ var errorMessage = string.Format(
+ CliStrings.ToolRequiresHigherDotNetVersion,
+ packageId,
+ requiredVersionString,
+ currentVersionString);
+
+ var suggestion = string.Format(
+ CliStrings.ToolRequiresHigherDotNetVersionSuggestion,
+ minRequiredFramework.Version.Major,
+ currentFramework.Version.Major);
+
+ throw new GracefulException($"{errorMessage} {suggestion}", isUserError: false);
+ }
+ }
+ }
+
throw new ToolConfigurationException(
CliStrings.MissingToolSettingsFile);
}
diff --git a/src/Cli/dotnet/xlf/CliStrings.cs.xlf b/src/Cli/dotnet/xlf/CliStrings.cs.xlf
index 65d8392b66f2..341d7f33bafe 100644
--- a/src/Cli/dotnet/xlf/CliStrings.cs.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.cs.xlf
@@ -1084,6 +1084,16 @@ Výchozí hodnota je false. Pokud však cílíte na .NET 7 nebo nižší a je za
Balíček {0} není nástroj .NET.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.Příkaz {0} obsahuje minimálně jeden neplatný znak: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.de.xlf b/src/Cli/dotnet/xlf/CliStrings.de.xlf
index d79a4f07b422..8d371aa78f27 100644
--- a/src/Cli/dotnet/xlf/CliStrings.de.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.de.xlf
@@ -1083,6 +1083,16 @@ Der Standardwert lautet FALSE. Wenn sie jedoch auf .NET 7 oder niedriger abziele
Paket {0} ist kein .NET-Tool.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.Der Befehl "{0}" enthält mindestens eines der folgenden ungültigen Zeichen: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.es.xlf b/src/Cli/dotnet/xlf/CliStrings.es.xlf
index c72c86d6fddb..16f12512b3b0 100644
--- a/src/Cli/dotnet/xlf/CliStrings.es.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.es.xlf
@@ -1083,6 +1083,16 @@ El valor predeterminado es "false." Sin embargo, cuando el destino es .NET 7 o i
El paquete {0} no es una herramienta de .NET.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.El comando "{0}" contiene uno o varios de los siguientes caracteres no válidos: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.fr.xlf b/src/Cli/dotnet/xlf/CliStrings.fr.xlf
index ffce7f406825..659a0a26e85f 100644
--- a/src/Cli/dotnet/xlf/CliStrings.fr.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.fr.xlf
@@ -1084,6 +1084,16 @@ La valeur par défaut est « false ». Toutefois, lorsque vous ciblez .NET 7 o
Le package {0} n’est pas un outil .NET.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.La commande '{0}' contient un ou plusieurs caractères non valides suivants : {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.it.xlf b/src/Cli/dotnet/xlf/CliStrings.it.xlf
index f4bb209f3056..593bd9f66e44 100644
--- a/src/Cli/dotnet/xlf/CliStrings.it.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.it.xlf
@@ -1083,6 +1083,16 @@ Il valore predefinito è 'false'. Tuttavia, quando la destinazione è .NET 7 o u
Il pacchetto {0} non è uno strumento .NET.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.Il comando '{0}' contiene uno o più dei caratteri seguenti non validi: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.ja.xlf b/src/Cli/dotnet/xlf/CliStrings.ja.xlf
index 025a2a04c987..16a80141b682 100644
--- a/src/Cli/dotnet/xlf/CliStrings.ja.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.ja.xlf
@@ -1083,6 +1083,16 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is
パッケージ {0} は .NET ツールではありません。
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.コマンド '{0}' には次の無効な文字が 1 つまたは複数含まれています: {1}。
diff --git a/src/Cli/dotnet/xlf/CliStrings.ko.xlf b/src/Cli/dotnet/xlf/CliStrings.ko.xlf
index 0718276866cf..f50fae32b387 100644
--- a/src/Cli/dotnet/xlf/CliStrings.ko.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.ko.xlf
@@ -1083,6 +1083,16 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is
{0} 패키지는 .NET 도구가 아닙니다.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.'{0}' 명령에 다음과 같은 잘못된 문자가 하나 이상 포함되어 있습니다. {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.pl.xlf b/src/Cli/dotnet/xlf/CliStrings.pl.xlf
index 49e51a8dab95..c4b5de3606ed 100644
--- a/src/Cli/dotnet/xlf/CliStrings.pl.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.pl.xlf
@@ -1083,6 +1083,16 @@ Wartość domyślna to „false”. Jednak w przypadku określania wartości doc
Pakiet {0} nie jest narzędziem platformy .NET.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.Polecenie „{0}” zawiera co najmniej jeden nieprawidłowy znak: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.pt-BR.xlf b/src/Cli/dotnet/xlf/CliStrings.pt-BR.xlf
index 18d6646955a9..af15ad2fdbe1 100644
--- a/src/Cli/dotnet/xlf/CliStrings.pt-BR.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.pt-BR.xlf
@@ -1084,6 +1084,16 @@ O padrão é 'false.' No entanto, ao direcionar para .NET 7 ou inferior, o padr
O pacote {0} não é uma ferramenta .NET.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.O comando '{0}' contém um ou mais dos seguintes caracteres inválidos: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.ru.xlf b/src/Cli/dotnet/xlf/CliStrings.ru.xlf
index 341f9d41bc55..cc3b304b9081 100644
--- a/src/Cli/dotnet/xlf/CliStrings.ru.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.ru.xlf
@@ -1084,6 +1084,16 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is
Пакет {0} не является средством .NET.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.Команда "{0}" содержит следующие недопустимы символы: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.tr.xlf b/src/Cli/dotnet/xlf/CliStrings.tr.xlf
index 26da8f61300c..bdb920e0a076 100644
--- a/src/Cli/dotnet/xlf/CliStrings.tr.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.tr.xlf
@@ -1083,6 +1083,16 @@ Varsayılan değer 'false.' Ancak çalışma zamanı tanımlayıcısı belirtild
{0} paketi bir .NET aracı değil.
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.'{0}' komutu şu geçersiz karakterlerden birini veya daha fazlasını içeriyor: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.zh-Hans.xlf b/src/Cli/dotnet/xlf/CliStrings.zh-Hans.xlf
index 380a74f4c834..eea160a146c8 100644
--- a/src/Cli/dotnet/xlf/CliStrings.zh-Hans.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.zh-Hans.xlf
@@ -1084,6 +1084,16 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is
包 {0} 不是 .NET 工具。
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.命令“{0}”包含一个或多个以下无效字符: {1}。
diff --git a/src/Cli/dotnet/xlf/CliStrings.zh-Hant.xlf b/src/Cli/dotnet/xlf/CliStrings.zh-Hant.xlf
index c7a96f081838..d97b3f1aa637 100644
--- a/src/Cli/dotnet/xlf/CliStrings.zh-Hant.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.zh-Hant.xlf
@@ -1083,6 +1083,16 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is
套件 {0} 不是 .NET 工具。
+
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+ Tool '{0}' requires a higher version of .NET than is currently installed. The tool targets {1}, but the current runtime is {2}.
+
+
+
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+ To use this tool, upgrade to .NET {0} or later, or use a version of the tool that is compatible with .NET {1}.
+
+ Command '{0}' contains one or more of the following invalid characters: {1}.命令 '{0}' 包含下列一或多個無效的字元: {1}。
diff --git a/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs b/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs
index 3eae1ab6133e..8746779afa6f 100644
--- a/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs
+++ b/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs
@@ -500,6 +500,117 @@ static XElement GetToolSettingsFile(string packagePath)
}
+ [Fact]
+ public void InstallToolWithHigherFrameworkAsGlobalToolShowsAppropriateError()
+ {
+ var toolPackagesPath = CreateNet99ToolPackage();
+ var testDirectory = _testAssetsManager.CreateTestDirectory();
+ var homeFolder = Path.Combine(testDirectory.Path, "home");
+
+ var result = new DotnetToolCommand(Log, "install", "-g", "Net99Tool", "--add-source", toolPackagesPath)
+ .WithEnvironmentVariables(homeFolder)
+ .WithWorkingDirectory(testDirectory.Path)
+ .Execute();
+
+ result.Should().Fail()
+ .And.HaveStdErrContaining("requires a higher version of .NET")
+ .And.HaveStdErrContaining(".NET 99");
+ }
+
+ [Fact]
+ public void InstallToolWithHigherFrameworkAsLocalToolShowsAppropriateError()
+ {
+ var toolPackagesPath = CreateNet99ToolPackage();
+ var testDirectory = _testAssetsManager.CreateTestDirectory();
+ var homeFolder = Path.Combine(testDirectory.Path, "home");
+
+ new DotnetCommand(Log, "new", "tool-manifest")
+ .WithEnvironmentVariables(homeFolder)
+ .WithWorkingDirectory(testDirectory.Path)
+ .Execute()
+ .Should().Pass();
+
+ var result = new DotnetToolCommand(Log, "install", "Net99Tool", "--add-source", toolPackagesPath)
+ .WithEnvironmentVariables(homeFolder)
+ .WithWorkingDirectory(testDirectory.Path)
+ .Execute();
+
+ result.Should().Fail()
+ .And.HaveStdErrContaining("requires a higher version of .NET")
+ .And.HaveStdErrContaining(".NET 99");
+ }
+
+ [Fact]
+ public void RunToolWithHigherFrameworkUsingDnxShowsAppropriateError()
+ {
+ var toolPackagesPath = CreateNet99ToolPackage();
+ var testDirectory = _testAssetsManager.CreateTestDirectory();
+ var homeFolder = Path.Combine(testDirectory.Path, "home");
+
+ var result = new DotnetToolCommand(Log, "exec", "Net99Tool", "--yes", "--source", toolPackagesPath)
+ .WithEnvironmentVariables(homeFolder)
+ .WithWorkingDirectory(testDirectory.Path)
+ .Execute();
+
+ result.Should().Fail()
+ .And.HaveStdErrContaining("requires a higher version of .NET")
+ .And.HaveStdErrContaining(".NET 99");
+ }
+
+ ///
+ /// Creates a tool package that targets net99.0 to simulate a tool requiring a higher .NET version
+ ///
+ private string CreateNet99ToolPackage()
+ {
+ var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: "net99tool");
+ var projectDirectory = Path.Combine(testDirectory.Path, "toolproject");
+ Directory.CreateDirectory(projectDirectory);
+
+ // Create the directory structure for the tool files
+ var toolsDir = Path.Combine(projectDirectory, "tools", "net99.0", "any");
+ Directory.CreateDirectory(toolsDir);
+
+ // Create DotnetToolSettings.xml
+ File.WriteAllText(Path.Combine(toolsDir, "DotnetToolSettings.xml"), @"
+
+
+
+
+");
+
+ // Create a minimal DLL file
+ File.WriteAllText(Path.Combine(toolsDir, "Net99Tool.dll"), "");
+
+ // Create a .nuspec file
+ var nuspecPath = Path.Combine(projectDirectory, "Net99Tool.nuspec");
+ File.WriteAllText(nuspecPath, @"
+
+
+ Net99Tool
+ 1.0.0
+ Test
+ Test tool targeting net99.0
+
+
+
+
+
+
+
+");
+
+ // Use NuGet pack to create the package
+ var packageOutputPath = Path.Combine(testDirectory.Path, "packages");
+ Directory.CreateDirectory(packageOutputPath);
+
+ new DotnetCommand(Log, "pack", nuspecPath, "-o", packageOutputPath)
+ .WithWorkingDirectory(projectDirectory)
+ .Execute()
+ .Should().Pass();
+
+ return packageOutputPath;
+ }
+
///
/// Opens the nupkg and verifies that it does not contain a dependency on the given dll.
///
@@ -516,9 +627,11 @@ static class EndToEndToolTestExtensions
{
public static TestCommand WithEnvironmentVariables(this TestCommand command, string homeFolder)
{
+ var nugetPackagesFolder = Path.Combine(homeFolder, ".nuget", "packages");
return command.WithEnvironmentVariable("DOTNET_CLI_HOME", homeFolder)
.WithEnvironmentVariable("DOTNET_NOLOGO", "1")
- .WithEnvironmentVariable("DOTNET_ADD_GLOBAL_TOOLS_TO_PATH", "0");
+ .WithEnvironmentVariable("DOTNET_ADD_GLOBAL_TOOLS_TO_PATH", "0")
+ .WithEnvironmentVariable("NUGET_PACKAGES", nugetPackagesFolder);
}
}
}
diff --git a/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs b/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs
index 32f6f731397a..b5ef60470c47 100644
--- a/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs
+++ b/test/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs
@@ -965,5 +965,68 @@ public ToolPackageDownloaderTests(ITestOutputHelper log, TestToolBuilder toolBui
{
ToolBuilder = toolBuilder;
}
+
+ [Fact]
+ public void GivenAToolWithHigherFrameworkItShowsAppropriateErrorMessage()
+ {
+ // Create a mock tool package with net99.0 framework to simulate a tool requiring a higher .NET version
+ var testDir = _testAssetsManager.CreateTestDirectory();
+ var fileSystem = new FileSystemWrapper();
+ var packageId = new PackageId("test.tool.higher.framework");
+ var packageVersion = new NuGetVersion("1.0.0");
+ var packageRoot = new DirectoryPath(testDir.Path).WithSubDirectories(".store", packageId.ToString(), packageVersion.ToNormalizedString());
+
+ // Create the package directory structure with net99.0 framework
+ var toolsPath = Path.Combine(packageRoot.Value, "tools", "net99.0", "any");
+ fileSystem.Directory.CreateDirectory(toolsPath);
+
+ // Create DotnetToolSettings.xml
+ var settingsContent = @"
+
+
+
+
+";
+ fileSystem.File.WriteAllText(Path.Combine(toolsPath, "DotnetToolSettings.xml"), settingsContent);
+
+ // Create a dummy assembly file
+ fileSystem.File.WriteAllText(Path.Combine(toolsPath, "test.dll"), "dummy");
+
+ // Create an empty asset file (simulating NuGet restore with no compatible frameworks)
+ var assetFilePath = Path.Combine(packageRoot.Value, "project.assets.json");
+ var currentFramework = $"net{Environment.Version.Major}.{Environment.Version.Minor}";
+ var assetFileContents = $$"""
+ {
+ "version": 3,
+ "targets": {
+ "{{currentFramework}}/{{RuntimeInformation.RuntimeIdentifier}}": {
+ "{{packageId}}/{{packageVersion}}": {
+ "type": "package",
+ "tools": {
+ }
+ }
+ }
+ },
+ "libraries": {},
+ "projectFileDependencyGroups": {}
+ }
+ """;
+ fileSystem.File.WriteAllText(assetFilePath, assetFileContents);
+
+ // Try to create a ToolPackageInstance, which should throw an informative error
+ Action action = () =>
+ {
+ _ = new ToolPackageInstance(
+ packageId,
+ packageVersion,
+ new DirectoryPath(testDir.Path).WithSubDirectories(".store"),
+ packageRoot,
+ fileSystem);
+ };
+
+ action.Should().Throw()
+ .WithMessage("*requires a higher version of .NET*")
+ .WithMessage("*.NET 99*");
+ }
}
}