private const string LanguageKeyword = "language";
private const string DllName = "netfxperf.dll";
- private const int EnglishLCID = 0x009;
-
private static volatile string s_computerName;
private static volatile string s_iniFilePath;
private static volatile string s_symbolFilePath;
+ private static CultureInfo s_englishCulture;
+
private PerformanceMonitor _performanceMonitor;
private readonly string _machineName;
private readonly string _perfLcid;
}
}
+ private static CultureInfo EnglishCulture
+ {
+ get
+ {
+ if (s_englishCulture is null)
+ {
+ try
+ {
+ s_englishCulture = CultureInfo.GetCultureInfo("en");
+ }
+ catch
+ {
+ s_englishCulture = CultureInfo.InvariantCulture;
+ }
+ }
+ return s_englishCulture;
+ }
+ }
+
internal PerformanceCounterLib(string machineName, string lcid)
{
_machineName = machineName;
internal static bool CategoryExists(string machine, string category)
{
- PerformanceCounterLib library = GetPerformanceCounterLib(machine, new CultureInfo(EnglishLCID));
+ PerformanceCounterLib library = GetPerformanceCounterLib(machine, EnglishCulture);
if (library.CategoryExists(category))
return true;
- if (CultureInfo.CurrentCulture.Parent.LCID != EnglishLCID)
+ if (CultureInfo.CurrentCulture.Parent.Name != EnglishCulture.Name)
{
CultureInfo culture = CultureInfo.CurrentCulture;
while (culture != CultureInfo.InvariantCulture)
internal static bool CounterExists(string machine, string category, string counter)
{
- PerformanceCounterLib library = GetPerformanceCounterLib(machine, new CultureInfo(EnglishLCID));
+ PerformanceCounterLib library = GetPerformanceCounterLib(machine, EnglishCulture);
bool categoryExists = false;
bool counterExists = library.CounterExists(category, counter, ref categoryExists);
- if (!categoryExists && CultureInfo.CurrentCulture.Parent.LCID != EnglishLCID)
+ if (!categoryExists && CultureInfo.CurrentCulture.Parent.Name != EnglishCulture.Name)
{
CultureInfo culture = CultureInfo.CurrentCulture;
while (culture != CultureInfo.InvariantCulture)
culture = culture.Parent;
}
- library = GetPerformanceCounterLib(machineName, new CultureInfo(EnglishLCID));
+ library = GetPerformanceCounterLib(machineName, EnglishCulture);
return library.GetCategories();
}
//First check the current culture for the category. This will allow
//PerformanceCounterCategory.CategoryHelp to return localized strings.
- if (CultureInfo.CurrentCulture.Parent.LCID != EnglishLCID)
+ if (CultureInfo.CurrentCulture.Parent.Name != EnglishCulture.Name)
{
CultureInfo culture = CultureInfo.CurrentCulture;
//We did not find the category walking up the culture hierarchy. Try looking
// for the category in the default culture English.
- library = GetPerformanceCounterLib(machine, new CultureInfo(EnglishLCID));
+ library = GetPerformanceCounterLib(machine, EnglishCulture);
help = library.GetCategoryHelp(category);
if (help == null)
internal static CategorySample GetCategorySample(string machine, string category)
{
- PerformanceCounterLib library = GetPerformanceCounterLib(machine, new CultureInfo(EnglishLCID));
+ PerformanceCounterLib library = GetPerformanceCounterLib(machine, EnglishCulture);
CategorySample sample = library.GetCategorySample(category);
- if (sample == null && CultureInfo.CurrentCulture.Parent.LCID != EnglishLCID)
+ if (sample == null && CultureInfo.CurrentCulture.Parent.Name != EnglishCulture.Name)
{
CultureInfo culture = CultureInfo.CurrentCulture;
while (culture != CultureInfo.InvariantCulture)
internal static string[] GetCounters(string machine, string category)
{
- PerformanceCounterLib library = GetPerformanceCounterLib(machine, new CultureInfo(EnglishLCID));
+ PerformanceCounterLib library = GetPerformanceCounterLib(machine, EnglishCulture);
bool categoryExists = false;
string[] counters = library.GetCounters(category, ref categoryExists);
- if (!categoryExists && CultureInfo.CurrentCulture.Parent.LCID != EnglishLCID)
+ if (!categoryExists && CultureInfo.CurrentCulture.Parent.Name != EnglishCulture.Name)
{
CultureInfo culture = CultureInfo.CurrentCulture;
while (culture != CultureInfo.InvariantCulture)
//First check the current culture for the counter. This will allow
//PerformanceCounter.CounterHelp to return localized strings.
- if (CultureInfo.CurrentCulture.Parent.LCID != EnglishLCID)
+ if (CultureInfo.CurrentCulture.Parent.Name != EnglishCulture.Name)
{
CultureInfo culture = CultureInfo.CurrentCulture;
while (culture != CultureInfo.InvariantCulture)
//We did not find the counter walking up the culture hierarchy. Try looking
// for the counter in the default culture English.
- library = GetPerformanceCounterLib(machine, new CultureInfo(EnglishLCID));
+ library = GetPerformanceCounterLib(machine, EnglishCulture);
help = library.GetCounterHelp(category, counter, ref categoryExists);
if (!categoryExists)
internal static PerformanceCounterLib GetPerformanceCounterLib(string machineName, CultureInfo culture)
{
- string lcidString = culture.LCID.ToString("X3", CultureInfo.InvariantCulture);
+ // EnglishCulture.LCID == 9 will be false only if running with Globalization Invariant Mode. Use "009" at that time as default English language identifier.
+ string lcidString = EnglishCulture.LCID == 9 ? culture.LCID.ToString("X3", CultureInfo.InvariantCulture) : "009";
machineName = (machineName == "." ? ComputerName : machineName).ToLowerInvariant();
internal static bool IsCustomCategory(string machine, string category)
{
- PerformanceCounterLib library = GetPerformanceCounterLib(machine, new CultureInfo(EnglishLCID));
+ PerformanceCounterLib library = GetPerformanceCounterLib(machine, EnglishCulture);
if (library.IsCustomCategory(category))
return true;
- if (CultureInfo.CurrentCulture.Parent.LCID != EnglishLCID)
+ if (CultureInfo.CurrentCulture.Parent.Name != EnglishCulture.Name)
{
CultureInfo culture = CultureInfo.CurrentCulture;
while (culture != CultureInfo.InvariantCulture)
{
PerformanceCounterCategoryType categoryType = PerformanceCounterCategoryType.Unknown;
- PerformanceCounterLib library = GetPerformanceCounterLib(machine, new CultureInfo(EnglishLCID));
+ PerformanceCounterLib library = GetPerformanceCounterLib(machine, EnglishCulture);
if (!library.FindCustomCategory(category, out categoryType))
{
- if (CultureInfo.CurrentCulture.Parent.LCID != EnglishLCID)
+ if (CultureInfo.CurrentCulture.Parent.Name != EnglishCulture.Name)
{
CultureInfo culture = CultureInfo.CurrentCulture;
while (culture != CultureInfo.InvariantCulture)
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Globalization;
using System.Collections;
using System.Collections.Specialized;
+using Microsoft.DotNet.RemoteExecutor;
using Xunit;
namespace System.Diagnostics.Tests
}
}
+ private static bool CanRunInInvariantMode => RemoteExecutor.IsSupported && !PlatformDetection.IsNetFramework;
+
+ [ConditionalTheory(nameof(CanRunInInvariantMode))]
+ [PlatformSpecific(TestPlatforms.Windows)]
+ [InlineData(true)]
+ [InlineData(false)]
+ public static void RunWithGlobalizationInvariantModeTest(bool predefinedCultures)
+ {
+ ProcessStartInfo psi = new ProcessStartInfo() { UseShellExecute = false };
+ psi.Environment.Add("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1");
+ psi.Environment.Add("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", predefinedCultures ? "1" : "0");
+ RemoteExecutor.Invoke(() =>
+ {
+ // Ensure we are running inside the Globalization invariant mode.
+ Assert.Equal("", CultureInfo.CurrentCulture.Name);
+
+ // This test ensure creating PerformanceCounter object while we are running with Globalization Invariant Mode.
+ // PerformanceCounter used to create cultures using LCID's which fail in Globalization Invariant Mode.
+ // This test ensure no failure should be encountered in this case.
+ using (PerformanceCounter counterSample = new PerformanceCounter("Processor", "Interrupts/sec", "0", "."))
+ {
+ Assert.Equal("Processor", counterSample.CategoryName);
+ }
+ }, new RemoteInvokeOptions { StartInfo = psi}).Dispose();
+ }
+
public static PerformanceCounter CreateCounterWithCategory(string name, bool readOnly, PerformanceCounterCategoryType categoryType )
{
var category = Helpers.CreateCategory(name, categoryType);