mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Fix Default/OEM encoding behavior PowerShell Core (#3467)
Based on the conclusion in discussion #3248, this PR fix "OEM" and "Default" encoding in powershell. 1. OEM -- We need an internal fix because .Net Core has no "OEM" encoding. The fix gives the following PowerShell Core behavior on "OEM" encoding: - on Windows - as Windows PowerShell based on GetOEMCP() and legacy encodings (System.Text.Encoding.CodePages) - on Unix - the same as default encoding in PowerShell Core 2. Default -- We need internal fix because CoreFX `Encoding.default` for all platforms is UTF8. Until we complete the `Encoding RFC` we should restore behavior as in Windows PowerShell. The fix gives the following PowerShell Core behavior on "Default" encoding: - on Windows - as Windows PowerShell based on GetACP() and legacy encodings (System.Text.Encoding.CodePages) - on Unix - UTF-8 without BOM (We are expecting that the same will be [in CoreFX](https://github.com/dotnet/coreclr/issues/10643))
This commit is contained in:
@@ -85,7 +85,6 @@
|
||||
<PackageReference Include="System.ServiceModel.Primitives" Version="4.3.0" />
|
||||
<PackageReference Include="System.ServiceModel.Security" Version="4.3.0" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.3.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.3.0" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.AccessControl" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Overlapped" Version="4.3.0" />
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
<PackageReference Include="System.Security.Cryptography.Algorithms" Version="4.3.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="4.3.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.X509Certificates" Version="4.3.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Thread" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.3.0" />
|
||||
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
|
||||
|
||||
@@ -7569,8 +7569,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
case FileSystemCmdletProviderEncoding.Oem:
|
||||
{
|
||||
uint oemCP = NativeMethods.GetOEMCP();
|
||||
encoding = System.Text.Encoding.GetEncoding((int)oemCP);
|
||||
encoding = ClrFacade.GetOEMEncoding();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -7607,11 +7606,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
} // get
|
||||
} // WasStreamTypeSpecified
|
||||
|
||||
private static class NativeMethods
|
||||
{
|
||||
[DllImport(PinvokeDllNames.GetOEMCPDllName, SetLastError = false, CharSet = CharSet.Unicode)]
|
||||
internal static extern uint GetOEMCP();
|
||||
}
|
||||
} // class FileSystemContentDynamicParametersBase
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -530,22 +530,26 @@ namespace System.Management.Automation
|
||||
#region Encoding
|
||||
|
||||
/// <summary>
|
||||
/// Facade for Encoding.Default
|
||||
/// Facade for getting default encoding
|
||||
/// </summary>
|
||||
internal static Encoding GetDefaultEncoding()
|
||||
{
|
||||
if (s_defaultEncoding == null)
|
||||
{
|
||||
#if CORECLR // Encoding.Default is not in CoreCLR
|
||||
// As suggested by CoreCLR team (tarekms), use latin1 (ISO-8859-1, CodePage 28591) as the default encoding.
|
||||
// We will revisit this if it causes any failures when running tests on Core PS.
|
||||
s_defaultEncoding = Encoding.GetEncoding(28591);
|
||||
#else
|
||||
#if UNIX // PowerShell Core on Unix
|
||||
s_defaultEncoding = new UTF8Encoding(false);
|
||||
#elif CORECLR // PowerShell Core on Windows
|
||||
EncodingRegisterProvider();
|
||||
|
||||
uint currentAnsiCp = NativeMethods.GetACP();
|
||||
s_defaultEncoding = Encoding.GetEncoding((int)currentAnsiCp);
|
||||
#else // Windows PowerShell
|
||||
s_defaultEncoding = Encoding.Default;
|
||||
#endif
|
||||
}
|
||||
return s_defaultEncoding;
|
||||
}
|
||||
|
||||
private static volatile Encoding s_defaultEncoding;
|
||||
|
||||
/// <summary>
|
||||
@@ -555,18 +559,34 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (s_oemEncoding == null)
|
||||
{
|
||||
#if CORECLR // The OEM code page '437' is not supported by CoreCLR.
|
||||
// Use the default encoding (ISO-8859-1, CodePage 28591) as the OEM encoding in OneCore powershell.
|
||||
#if UNIX // PowerShell Core on Unix
|
||||
s_oemEncoding = GetDefaultEncoding();
|
||||
#else
|
||||
#elif CORECLR // PowerShell Core on Windows
|
||||
EncodingRegisterProvider();
|
||||
|
||||
uint oemCp = NativeMethods.GetOEMCP();
|
||||
s_oemEncoding = Encoding.GetEncoding((int)oemCp);
|
||||
|
||||
#else // Windows PowerShell
|
||||
uint oemCp = NativeMethods.GetOEMCP();
|
||||
s_oemEncoding = Encoding.GetEncoding((int)oemCp);
|
||||
#endif
|
||||
}
|
||||
return s_oemEncoding;
|
||||
}
|
||||
|
||||
private static volatile Encoding s_oemEncoding;
|
||||
|
||||
#if CORECLR
|
||||
private static void EncodingRegisterProvider()
|
||||
{
|
||||
if (s_defaultEncoding == null && s_oemEncoding == null)
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion Encoding
|
||||
|
||||
#region Security
|
||||
@@ -1033,6 +1053,12 @@ namespace System.Management.Automation
|
||||
[DllImport(PinvokeDllNames.GetOEMCPDllName, SetLastError = false, CharSet = CharSet.Unicode)]
|
||||
internal static extern uint GetOEMCP();
|
||||
|
||||
/// <summary>
|
||||
/// Pinvoke for GetACP to get the Windows operating system code page.
|
||||
/// </summary>
|
||||
[DllImport(PinvokeDllNames.GetACPDllName, SetLastError = false, CharSet = CharSet.Unicode)]
|
||||
internal static extern uint GetACP();
|
||||
|
||||
public const int S_OK = 0x00000000;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -135,6 +135,7 @@ namespace System.Management.Automation
|
||||
internal const string CreateToolhelp32SnapshotDllName = "api-ms-win-core-toolhelp-l1-1-0"; /*120*/
|
||||
internal const string Process32FirstDllName = "api-ms-win-core-toolhelp-l1-1-0"; /*121*/
|
||||
internal const string Process32NextDllName = "api-ms-win-core-toolhelp-l1-1-0"; /*122*/
|
||||
internal const string GetACPDllName = "api-ms-win-core-localization-l1-2-0.dll"; /*123*/
|
||||
#else
|
||||
internal const string QueryDosDeviceDllName = "kernel32.dll"; /*1*/
|
||||
internal const string CreateSymbolicLinkDllName = "kernel32.dll"; /*2*/
|
||||
@@ -257,6 +258,7 @@ namespace System.Management.Automation
|
||||
internal const string CreateToolhelp32SnapshotDllName = "kernel32.dll"; /*120*/
|
||||
internal const string Process32FirstDllName = "kernel32.dll"; /*121*/
|
||||
internal const string Process32NextDllName = "kernel32.dll"; /*122*/
|
||||
internal const string GetACPDllName = "kernel32.dll"; /*123*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user