这是因为,正如文档明确指出的那样,通过 CultureInfo 设置当前文化是特定于线程的。
Powershell 的 set-culture 命令通过调用非托管 Win32 函数来完成一些完全不同的操作,正如您从 cmdlet 的反汇编中看到的那样:
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults")]
protected override void ProcessRecord()
{
if (LPAPIWrapper.NlsUpdateLocale(cultureinfo.Name, NLS_LOCALE_SELECT | NLS_LOCALE_CLEAR_USER_DATA) == 0)
{
NumberFormatInfo numberFormat = cultureinfo.NumberFormat;
DateTimeFormatInfo dateTimeFormat = cultureinfo.DateTimeFormat;
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ICURRDIGITS, numberFormat.CurrencyDecimalDigits.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, numberFormat.CurrencyDecimalSeparator.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, numberFormat.CurrencyGroupSeparator.ToString());
SetGroupSizes(LOCALE_SMONGROUPING, numberFormat.CurrencyGroupSizes);
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_INEGCURR, numberFormat.CurrencyNegativePattern.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ICURRENCY, numberFormat.CurrencyPositivePattern.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, numberFormat.CurrencySymbol.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDIGITSUBSTITUTION, numberFormat.DigitSubstitution.ToString());
string text = "";
string[] nativeDigits = numberFormat.NativeDigits;
foreach (string str in nativeDigits)
{
text += str;
}
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNATIVEDIGITS, text);
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN, numberFormat.NegativeSign.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDIGITS, numberFormat.NumberDecimalDigits.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, numberFormat.NumberDecimalSeparator.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, numberFormat.NumberGroupSeparator.ToString());
SetGroupSizes(LOCALE_SGROUPING, numberFormat.NumberGroupSizes);
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER, numberFormat.NumberNegativePattern.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SPOSITIVESIGN, numberFormat.PositiveSign.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDATE, dateTimeFormat.DateSeparator.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, dateTimeFormat.TimeSeparator.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SSHORTDATE, dateTimeFormat.ShortDatePattern.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLONGDATE, dateTimeFormat.LongDatePattern.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, dateTimeFormat.LongTimePattern.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S1159, dateTimeFormat.AMDesignator.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S2359, dateTimeFormat.PMDesignator.ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK, ((int)(dateTimeFormat.FirstDayOfWeek + 6) % 7).ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IFIRSTWEEKOFYEAR, ((int)dateTimeFormat.CalendarWeekRule).ToString());
LPAPIWrapper.SetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SYEARMONTH, dateTimeFormat.YearMonthPattern.ToString());
LPAPIWrapper.SendNotifyMessage((IntPtr)65535, 26u, IntPtr.Zero, "intl");
}
}
如果你想进一步分析发生了什么,你可以反汇编位于C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.InternationalSettings.Commands\v4.0_3.0.0.0__31bf3856ad364e35\Microsoft.InternationalSettings.Commands.dll的dll