diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/LocalizableStrings.resx b/src/Cli/Microsoft.DotNet.Cli.Utils/LocalizableStrings.resx
index f834f2498126..a4350e5facc3 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/LocalizableStrings.resx
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/LocalizableStrings.resx
@@ -188,4 +188,13 @@ dotnet tool install --global {1}
.NET workloads installed:
+
+ Warning: Mixed-Mode Installation Detected
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.cs.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.cs.xlf
index 059c3cc90ea8..64715ee465d0 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.cs.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.cs.xlf
@@ -12,6 +12,21 @@
Nesprávně naformátovaný text příkazu {0}
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.Nebylo možné provést, protože zadaný příkaz nebo soubor nebyl nalezen.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.de.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.de.xlf
index b65426871939..a3d0036e06f6 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.de.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.de.xlf
@@ -12,6 +12,21 @@
Fehlerhafter Befehlstext "{0}".
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.Die Ausführung war nicht möglich, da der angegebene Befehl oder die angegebene Datei nicht gefunden wurde.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.es.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.es.xlf
index ab310ba0919e..fdeabfb73270 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.es.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.es.xlf
@@ -12,6 +12,21 @@
Texto de comando con formato incorrecto "{0}"
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.No se pudo ejecutar porque no se encontró el comando o archivo especificado.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.fr.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.fr.xlf
index 83aafec69438..4c9a020a0227 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.fr.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.fr.xlf
@@ -12,6 +12,21 @@
Texte de commande incorrect '{0}'
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.Exécution impossible, car la commande ou le fichier spécifié est introuvable.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.it.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.it.xlf
index d14e1840c5e8..d28d22ca7b20 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.it.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.it.xlf
@@ -12,6 +12,21 @@
Il testo del comando '{0}' non è corretto
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.Non è stato possibile eseguire perché il comando o il file specificato non è stato trovato.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ja.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ja.xlf
index ac1e63ccf812..9e82946e0c76 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ja.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ja.xlf
@@ -12,6 +12,21 @@
無効な形式のコマンド テキスト '{0}'
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.指定されたコマンドまたはファイルが見つからなかったため、実行できませんでした。
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ko.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ko.xlf
index 4f2d0561d088..904fc2616383 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ko.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ko.xlf
@@ -12,6 +12,21 @@
형식이 잘못된 명령 텍스트 '{0}'
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.지정한 명령 또는 파일을 찾을 수 없어 실행하지 못했습니다.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.pl.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.pl.xlf
index f6b356e4a6eb..a1fe920e8489 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.pl.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.pl.xlf
@@ -12,6 +12,21 @@
Nieprawidłowo sformułowany tekst polecenia „{0}”
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.Nie można wykonać, ponieważ nie znaleziono określonego polecenia lub pliku.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.pt-BR.xlf
index b29d04bbe723..a52b2c53c408 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.pt-BR.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.pt-BR.xlf
@@ -12,6 +12,21 @@
Texto do comando malformado '{0}'
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.Não foi possível executar porque o comando ou arquivo especificado não foi encontrado.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ru.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ru.xlf
index 0de8ace38958..2aaf3854d8ea 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ru.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.ru.xlf
@@ -12,6 +12,21 @@
Неправильный формат текста команды "{0}"
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.Не удалось выполнить, поскольку указанная команда или файл не найдены.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.tr.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.tr.xlf
index effa36b8a0ee..0caf9cf9c976 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.tr.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.tr.xlf
@@ -12,6 +12,21 @@
Hatalı biçimlendirilmiş komut metni: '{0}'
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.Belirtilen komut veya dosya bulunamadığından yürütülemedi.
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.zh-Hans.xlf
index 92d85374f55b..ce34244f776d 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.zh-Hans.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.zh-Hans.xlf
@@ -12,6 +12,21 @@
命令文本“{0}”格式错误
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.无法执行,因为找不到指定的命令或文件。
diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.zh-Hant.xlf
index 2a19383fc1ce..d9b638d4b658 100644
--- a/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.zh-Hant.xlf
+++ b/src/Cli/Microsoft.DotNet.Cli.Utils/xlf/LocalizableStrings.zh-Hant.xlf
@@ -12,6 +12,21 @@
命令文字 '{0}' 格式錯誤
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This can cause unexpected behavior. For more information, see: {2}
+
+
+
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+ The dotnet executable being used is from a global install location ({0}), but the DOTNET_ROOT environment variable is set to a different location ({1}). This indicates a PATH ordering problem. Please ensure that the directory containing the desired dotnet executable appears first in your PATH.
+
+
+
+ Warning: Mixed-Mode Installation Detected
+ Warning: Mixed-Mode Installation Detected
+
+ Could not execute because the specified command or file was not found.無法執行,因為找不到指定的命令或檔案。
diff --git a/src/Cli/dotnet/CommandLineInfo.cs b/src/Cli/dotnet/CommandLineInfo.cs
index 84f0b4ba1eff..885ed9c2a12a 100644
--- a/src/Cli/dotnet/CommandLineInfo.cs
+++ b/src/Cli/dotnet/CommandLineInfo.cs
@@ -3,6 +3,7 @@
#nullable disable
+using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Commands.Workload;
using Microsoft.DotNet.Cli.Utils;
using LocalizableStrings = Microsoft.DotNet.Cli.Utils.LocalizableStrings;
@@ -33,9 +34,50 @@ public static void PrintInfo()
Reporter.Output.WriteLine($" OS Platform: {RuntimeEnvironment.OperatingSystemPlatform}");
Reporter.Output.WriteLine($" RID: {GetDisplayRid(versionFile)}");
Reporter.Output.WriteLine($" Base Path: {AppContext.BaseDirectory}");
+ PrintMixedInstallationWarning();
PrintWorkloadsInfo();
}
+ private static void PrintMixedInstallationWarning()
+ {
+ try
+ {
+ var muxer = new Muxer();
+ string dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT");
+
+ if (MixedInstallationDetector.IsMixedInstallation(muxer.MuxerPath, dotnetRoot))
+ {
+ Reporter.Output.WriteLine();
+ Reporter.Output.WriteLine(LocalizableStrings.MixedInstallWarningTitle);
+
+ string docUrl = MixedInstallationDetector.GetDocumentationUrl();
+ string warningMessage;
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && docUrl != null)
+ {
+ warningMessage = string.Format(
+ LocalizableStrings.MixedInstallWarningMessageLinux,
+ Path.GetDirectoryName(muxer.MuxerPath),
+ dotnetRoot,
+ docUrl);
+ }
+ else
+ {
+ warningMessage = string.Format(
+ LocalizableStrings.MixedInstallWarningMessageOther,
+ Path.GetDirectoryName(muxer.MuxerPath),
+ dotnetRoot);
+ }
+
+ Reporter.Output.WriteLine($" {warningMessage}");
+ }
+ }
+ catch
+ {
+ // Silently ignore any errors in detection to avoid breaking dotnet --info
+ }
+ }
+
private static void PrintWorkloadsInfo()
{
Reporter.Output.WriteLine();
diff --git a/src/Cli/dotnet/MixedInstallationDetector.cs b/src/Cli/dotnet/MixedInstallationDetector.cs
new file mode 100644
index 000000000000..e67e5a947fda
--- /dev/null
+++ b/src/Cli/dotnet/MixedInstallationDetector.cs
@@ -0,0 +1,147 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime.InteropServices;
+using Microsoft.Win32;
+
+namespace Microsoft.DotNet.Cli;
+
+///
+/// Detects mixed installation scenarios where the dotnet muxer on PATH
+/// is from a global install but DOTNET_ROOT points to a different location.
+///
+internal static class MixedInstallationDetector
+{
+ ///
+ /// Gets the global installation root path for the current platform.
+ /// Based on https://github.com/dotnet/designs/blob/main/accepted/2020/install-locations.md
+ /// and https://github.com/dotnet/designs/blob/main/accepted/2021/install-location-per-architecture.md
+ ///
+ private static string? GetGlobalInstallRoot()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Windows: Read from registry HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\\InstallLocation
+ // Use 32-bit registry view as specified in the spec
+ try
+ {
+ string arch = RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant();
+ using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
+ using (var key = hklm.OpenSubKey($@"SOFTWARE\dotnet\Setup\InstalledVersions\{arch}"))
+ {
+ if (key != null)
+ {
+ var installLocation = key.GetValue("InstallLocation") as string;
+ if (!string.IsNullOrEmpty(installLocation))
+ {
+ return installLocation;
+ }
+ }
+ }
+ }
+ catch
+ {
+ // If registry reading fails, return null
+ }
+ }
+ else
+ {
+ // Linux/macOS: Read from /etc/dotnet/install_location or /etc/dotnet/install_location_
+ try
+ {
+ string arch = RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant();
+ string archSpecificPath = $"/etc/dotnet/install_location_{arch}";
+ string defaultPath = "/etc/dotnet/install_location";
+
+ // Try arch-specific location first
+ if (File.Exists(archSpecificPath))
+ {
+ string location = File.ReadAllText(archSpecificPath).Trim();
+ if (!string.IsNullOrEmpty(location))
+ {
+ return location;
+ }
+ }
+
+ // Fall back to default location
+ if (File.Exists(defaultPath))
+ {
+ string location = File.ReadAllText(defaultPath).Trim();
+ if (!string.IsNullOrEmpty(location))
+ {
+ return location;
+ }
+ }
+ }
+ catch
+ {
+ // If file reading fails, return null
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Detects if the current installation is a mixed installation scenario.
+ ///
+ /// The path to the current dotnet muxer executable
+ /// The value of the DOTNET_ROOT environment variable (can be null)
+ /// True if a mixed installation is detected, false otherwise
+ public static bool IsMixedInstallation(string muxerPath, string? dotnetRoot)
+ {
+ if (string.IsNullOrEmpty(muxerPath) || string.IsNullOrEmpty(dotnetRoot))
+ {
+ return false;
+ }
+
+ // Get the registered global install location
+ string? globalInstallRoot = GetGlobalInstallRoot();
+ if (string.IsNullOrEmpty(globalInstallRoot))
+ {
+ // No global install registered, cannot detect mixed installation
+ return false;
+ }
+
+ // Normalize paths for comparison
+ string normalizedMuxerPath = Path.GetFullPath(muxerPath);
+ string normalizedDotnetRoot = Path.GetFullPath(dotnetRoot);
+ string normalizedGlobalRoot = Path.GetFullPath(globalInstallRoot);
+
+ // Check if the muxer is in the global install root
+ if (!normalizedMuxerPath.StartsWith(normalizedGlobalRoot, GetStringComparison()))
+ {
+ // Muxer is not in the global install root, no mixed installation
+ return false;
+ }
+
+ // Check if DOTNET_ROOT points to a different location than the global install root
+ bool isDifferentRoot = !normalizedDotnetRoot.StartsWith(normalizedGlobalRoot, GetStringComparison());
+
+ return isDifferentRoot;
+ }
+
+ ///
+ /// Gets the appropriate string comparison for the current platform.
+ ///
+ private static StringComparison GetStringComparison()
+ {
+ // Windows is case-insensitive for paths
+ return RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+ ? StringComparison.OrdinalIgnoreCase
+ : StringComparison.Ordinal;
+ }
+
+ ///
+ /// Gets the documentation URL for mixed installation issues.
+ ///
+ public static string? GetDocumentationUrl()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ return "https://learn.microsoft.com/en-us/dotnet/core/install/linux-package-mixup";
+ }
+
+ return null;
+ }
+}
diff --git a/test/dotnet.Tests/MixedInstallationDetectorTests.cs b/test/dotnet.Tests/MixedInstallationDetectorTests.cs
new file mode 100644
index 000000000000..ce70cd94ac36
--- /dev/null
+++ b/test/dotnet.Tests/MixedInstallationDetectorTests.cs
@@ -0,0 +1,76 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime.InteropServices;
+using Microsoft.DotNet.Cli;
+
+namespace Microsoft.DotNet.Tests;
+
+public class MixedInstallationDetectorTests : SdkTest
+{
+ public MixedInstallationDetectorTests(ITestOutputHelper log) : base(log)
+ {
+ }
+
+ [Fact]
+ public void IsMixedInstallation_ReturnsFalse_WhenMuxerPathIsNull()
+ {
+ bool result = MixedInstallationDetector.IsMixedInstallation(null!, "/some/path");
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void IsMixedInstallation_ReturnsFalse_WhenMuxerPathIsEmpty()
+ {
+ bool result = MixedInstallationDetector.IsMixedInstallation("", "/some/path");
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void IsMixedInstallation_ReturnsFalse_WhenDotnetRootIsNull()
+ {
+ bool result = MixedInstallationDetector.IsMixedInstallation("/usr/share/dotnet/dotnet", null);
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void IsMixedInstallation_ReturnsFalse_WhenDotnetRootIsEmpty()
+ {
+ bool result = MixedInstallationDetector.IsMixedInstallation("/usr/share/dotnet/dotnet", "");
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void IsMixedInstallation_DoesNotThrow_WithValidInputs()
+ {
+ // This test verifies that the method doesn't throw exceptions
+ // The actual result depends on whether a global install is registered on the system
+ bool result = MixedInstallationDetector.IsMixedInstallation(
+ "/some/path/dotnet",
+ "/different/path");
+
+ // Result can be true or false depending on system configuration
+ // We just verify it doesn't throw
+ Assert.True(result == true || result == false);
+ }
+
+ [Fact]
+ public void GetDocumentationUrl_ReturnsLinuxUrl_OnLinux()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ string? url = MixedInstallationDetector.GetDocumentationUrl();
+ Assert.Equal("https://learn.microsoft.com/en-us/dotnet/core/install/linux-package-mixup", url);
+ }
+ }
+
+ [Fact]
+ public void GetDocumentationUrl_ReturnsNull_OnNonLinux()
+ {
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ string? url = MixedInstallationDetector.GetDocumentationUrl();
+ Assert.Null(url);
+ }
+ }
+}