From 710d81f0c5e865d96ba139069b49ac8a5cf6676a Mon Sep 17 00:00:00 2001 From: Gang Wang Date: Tue, 14 Oct 2025 08:05:31 +0000 Subject: [PATCH 1/3] Add the feature flag that allows users to opt out automatic UTF8 console encoding --- src/MSBuild/XMake.cs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/MSBuild/XMake.cs b/src/MSBuild/XMake.cs index 7febc492d7a..5a346fc56dc 100644 --- a/src/MSBuild/XMake.cs +++ b/src/MSBuild/XMake.cs @@ -1934,23 +1934,26 @@ internal static void SetConsoleUI() CultureInfo.CurrentUICulture = desiredCulture; CultureInfo.DefaultThreadCurrentUICulture = desiredCulture; + if (Environment.GetEnvironmentVariable("CONSOLE_USE_DEFAULT_ENCODING") != "1") + { #if RUNTIME_TYPE_NETCORE - if (EncodingUtilities.CurrentPlatformIsWindowsAndOfficiallySupportsUTF8Encoding()) + if (EncodingUtilities.CurrentPlatformIsWindowsAndOfficiallySupportsUTF8Encoding()) #else - if (EncodingUtilities.CurrentPlatformIsWindowsAndOfficiallySupportsUTF8Encoding() - && !CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.Equals("en", StringComparison.InvariantCultureIgnoreCase)) + if (EncodingUtilities.CurrentPlatformIsWindowsAndOfficiallySupportsUTF8Encoding() + && !CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.Equals("en", StringComparison.InvariantCultureIgnoreCase)) #endif - { - try - { - // Setting both encodings causes a change in the CHCP, making it so we don't need to P-Invoke CHCP ourselves. - Console.OutputEncoding = Encoding.UTF8; - // If the InputEncoding is not set, the encoding will work in CMD but not in PowerShell, as the raw CHCP page won't be changed. - Console.InputEncoding = Encoding.UTF8; - } - catch (Exception ex) when (ex is IOException || ex is SecurityException) { - // The encoding is unavailable. Do nothing. + try + { + // Setting both encodings causes a change in the CHCP, making it so we don't need to P-Invoke CHCP ourselves. + Console.OutputEncoding = Encoding.UTF8; + // If the InputEncoding is not set, the encoding will work in CMD but not in PowerShell, as the raw CHCP page won't be changed. + Console.InputEncoding = Encoding.UTF8; + } + catch (Exception ex) when (ex is IOException || ex is SecurityException) + { + // The encoding is unavailable. Do nothing. + } } } From ab7cb68c84f8bde0bf7fe9d6ac205af95ac4743f Mon Sep 17 00:00:00 2001 From: Gang Wang Date: Wed, 15 Oct 2025 09:32:02 +0000 Subject: [PATCH 2/3] Document the environment variable --- documentation/wiki/MSBuild-Environment-Variables.md | 2 ++ src/Framework/Traits.cs | 5 +++++ src/MSBuild/XMake.cs | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/documentation/wiki/MSBuild-Environment-Variables.md b/documentation/wiki/MSBuild-Environment-Variables.md index 76b73f435f4..f2df570ea77 100644 --- a/documentation/wiki/MSBuild-Environment-Variables.md +++ b/documentation/wiki/MSBuild-Environment-Variables.md @@ -34,3 +34,5 @@ Some of the env variables listed here are unsupported, meaning there is no guara - Set this to force all tasks to run out of process (except inline tasks). - `MSBUILDFORCEINLINETASKFACTORIESOUTOFPROC` - Set this to force all inline tasks to run out of process. It is not compatible with custom TaskFactories. +- `CONSOLE_USE_DEFAULT_ENCODING` + - It opts out automatic console encoding UTF-8. Make Console use default encoding in the system. \ No newline at end of file diff --git a/src/Framework/Traits.cs b/src/Framework/Traits.cs index 8cbf21feef1..029d74448a9 100644 --- a/src/Framework/Traits.cs +++ b/src/Framework/Traits.cs @@ -147,6 +147,11 @@ public Traits() /// public readonly bool ForceTaskFactoryOutOfProc = Environment.GetEnvironmentVariable("MSBUILDFORCEINLINETASKFACTORIESOUTOFPROC") == "1"; + /// + /// Make Console use default encoding in the system. It opts out automatic console encoding UTF-8. + /// + public readonly bool ConsoleUseDefaultEncoding = Environment.GetEnvironmentVariable("CONSOLE_USE_DEFAULT_ENCODING") == "1"; + /// /// Variables controlling opt out at the level of not initializing telemetry infrastructure. Set to "1" or "true" to opt out. /// mirroring diff --git a/src/MSBuild/XMake.cs b/src/MSBuild/XMake.cs index 5a346fc56dc..ffd58665a96 100644 --- a/src/MSBuild/XMake.cs +++ b/src/MSBuild/XMake.cs @@ -1934,7 +1934,7 @@ internal static void SetConsoleUI() CultureInfo.CurrentUICulture = desiredCulture; CultureInfo.DefaultThreadCurrentUICulture = desiredCulture; - if (Environment.GetEnvironmentVariable("CONSOLE_USE_DEFAULT_ENCODING") != "1") + if (!Traits.Instance.ConsoleUseDefaultEncoding) { #if RUNTIME_TYPE_NETCORE if (EncodingUtilities.CurrentPlatformIsWindowsAndOfficiallySupportsUTF8Encoding()) From 11d90fbc953294e142c0f4ff8af3b7ae2688e039 Mon Sep 17 00:00:00 2001 From: Gang Wang Date: Mon, 5 Jan 2026 18:34:16 +0800 Subject: [PATCH 3/3] Prefix the environment variable with MSBUILD --- documentation/wiki/MSBuild-Environment-Variables.md | 2 +- src/Framework/Traits.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/wiki/MSBuild-Environment-Variables.md b/documentation/wiki/MSBuild-Environment-Variables.md index f2df570ea77..859cc8e7f69 100644 --- a/documentation/wiki/MSBuild-Environment-Variables.md +++ b/documentation/wiki/MSBuild-Environment-Variables.md @@ -34,5 +34,5 @@ Some of the env variables listed here are unsupported, meaning there is no guara - Set this to force all tasks to run out of process (except inline tasks). - `MSBUILDFORCEINLINETASKFACTORIESOUTOFPROC` - Set this to force all inline tasks to run out of process. It is not compatible with custom TaskFactories. -- `CONSOLE_USE_DEFAULT_ENCODING` +- `MSBUILD_CONSOLE_USE_DEFAULT_ENCODING` - It opts out automatic console encoding UTF-8. Make Console use default encoding in the system. \ No newline at end of file diff --git a/src/Framework/Traits.cs b/src/Framework/Traits.cs index 029d74448a9..33f1fb2e776 100644 --- a/src/Framework/Traits.cs +++ b/src/Framework/Traits.cs @@ -150,7 +150,7 @@ public Traits() /// /// Make Console use default encoding in the system. It opts out automatic console encoding UTF-8. /// - public readonly bool ConsoleUseDefaultEncoding = Environment.GetEnvironmentVariable("CONSOLE_USE_DEFAULT_ENCODING") == "1"; + public readonly bool ConsoleUseDefaultEncoding = Environment.GetEnvironmentVariable("MSBUILD_CONSOLE_USE_DEFAULT_ENCODING") == "1" || Environment.GetEnvironmentVariable("DOTNET_CLI_CONSOLE_USE_DEFAULT_ENCODING") == "1"; /// /// Variables controlling opt out at the level of not initializing telemetry infrastructure. Set to "1" or "true" to opt out.