-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Fix Default/OEM encoding behavior PowerShell Core #3467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9580b4a
64bceba
a26149c
b60e9eb
900311c
957f01b
595b728
0f04279
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -530,22 +530,26 @@ internal static object[] GetCustomAttributes<T>(Assembly assembly) | |
#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 @@ internal static Encoding GetOEMEncoding() | |
{ | ||
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 | ||
67F4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't notice the duplicate code between coreclr and fullclr. In this case, maybe the following is better?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried - it is difficult to read. In compile time no duplicate code is. So maybe leave as is? |
||
} | ||
return s_oemEncoding; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove extra line, or move There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved. |
||
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 @@ private static class NativeMethods | |
[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> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -135,6 +135,7 @@ internal static class PinvokeDllNames | |
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*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The API set matches the API on my laptop. I don't have access to a Nano VM at the moment to verify it there. On Nano, it must match the exporting API set exactly. You can verify it with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now I don't run still dumpbin.exe /exports
What version we should use? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is correct "as-is" here. No change needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! Clear. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. Nano Server contains the 1-2-0 version of the API set |
||
#else | ||
internal const string QueryDosDeviceDllName = "kernel32.dll"; /*1*/ | ||
internal const string CreateSymbolicLinkDllName = "kernel32.dll"; /*2*/ | ||
|
@@ -257,6 +258,7 @@ internal static class PinvokeDllNames | |
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 | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
NativeMethods.GetOEMCP
in this file can be removed if it's no longer used.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is used in
ClrFacade.GetOEMEncoding
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ClrFacade
has its own copy ofGetOEMEncoding
, so the one inFileSystemProvider.cs
can be removed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.