| File: src\vstest\src\Microsoft.TestPlatform.Execution.Shared\UILanguageOverride.cs | Web Access |
| Project: src\vstest\src\testhost\testhost.csproj (testhost) |
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Globalization; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers; using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; namespace Microsoft.VisualStudio.TestPlatform.Execution; // Borrowed from dotnet/sdk with some tweaks to allow testing internal class UiLanguageOverride { private const string DOTNET_CLI_UI_LANGUAGE = nameof(DOTNET_CLI_UI_LANGUAGE); private const string VSLANG = nameof(VSLANG); private const string PreferredUILang = nameof(PreferredUILang); private readonly IEnvironmentVariableHelper _environmentVariableHelper; private readonly Action<CultureInfo> _setDefaultThreadCurrentUICulture; public UiLanguageOverride() : this(new EnvironmentVariableHelper(), language => CultureInfo.DefaultThreadCurrentUICulture = language) { } public UiLanguageOverride(IEnvironmentVariableHelper environmentVariableHelper, Action<CultureInfo> setDefaultThreadCurrentUICulture) { _environmentVariableHelper = environmentVariableHelper; _setDefaultThreadCurrentUICulture = setDefaultThreadCurrentUICulture; } internal void SetCultureSpecifiedByUser() { var language = GetOverriddenUiLanguage(_environmentVariableHelper); if (language == null) { return; } ApplyOverrideToCurrentProcess(language, _setDefaultThreadCurrentUICulture); FlowOverrideToChildProcesses(language, _environmentVariableHelper); } private static void ApplyOverrideToCurrentProcess(CultureInfo language, Action<CultureInfo> setDefaultThreadCurrentUICulture) { setDefaultThreadCurrentUICulture(language); } private static CultureInfo? GetOverriddenUiLanguage(IEnvironmentVariableHelper environmentVariableHelper) { // DOTNET_CLI_UI_LANGUAGE=<culture name> is the main way for users to customize the CLI's UI language. string? dotnetCliLanguage = environmentVariableHelper.GetEnvironmentVariable(DOTNET_CLI_UI_LANGUAGE); if (dotnetCliLanguage != null) { try { return new CultureInfo(dotnetCliLanguage); } catch (CultureNotFoundException) { /* Culture not available on this system — fall back to default. */ } } // VSLANG=<lcid> is set by VS and we respect that as well so that we will respect the VS // language preference if we're invoked by VS. string? vsLang = environmentVariableHelper.GetEnvironmentVariable(VSLANG); if (vsLang != null && int.TryParse(vsLang, out int vsLcid)) { try { return new CultureInfo(vsLcid); } catch (ArgumentOutOfRangeException) { /* Invalid culture value — fall back to default. */ } catch (CultureNotFoundException) { /* Culture not available on this system — fall back to default. */ } } return null; } private static void FlowOverrideToChildProcesses(CultureInfo language, IEnvironmentVariableHelper environmentVariableHelper) { // Do not override any environment variables that are already set as we do not want to clobber a more granular setting with our global setting. SetIfNotAlreadySet(DOTNET_CLI_UI_LANGUAGE, language.Name, environmentVariableHelper); SetIfNotAlreadySet(VSLANG, language.LCID.ToString(CultureInfo.CurrentCulture), environmentVariableHelper); // for tools following VS guidelines to just work in CLI SetIfNotAlreadySet(PreferredUILang, language.Name, environmentVariableHelper); // for C#/VB targets that pass $(PreferredUILang) to compiler } private static void SetIfNotAlreadySet(string environmentVariableName, string value, IEnvironmentVariableHelper environmentVariableHelper) { string? currentValue = environmentVariableHelper.GetEnvironmentVariable(environmentVariableName); if (currentValue == null) { environmentVariableHelper.SetEnvironmentVariable(environmentVariableName, value); } } }