gpt4 book ai didi

windows - 在命令提示符/Windows Powershell(Windows 10)中使用UTF-8编码(CHCP 65001)

转载 作者:行者123 更新时间:2023-12-01 18:57:38 24 4
gpt4 key购买 nike

我已经在命令提示符和Windows Powershell中强制使用chcp 65001了一段时间,但是从SO和其他几个社区的问答文章来看,它是seems like a dangerous and inefficient solution。 Microsoft是否提供了chcp 65001的改进/完整替代方案,可以在不手动更改注册表的情况下将其永久保存?如果没有,将来是否有公开宣布的时间表或议程来支持Windows CLI中的UTF-8?

我个人一直在使用chcp 949来支持韩文字符,但是反斜杠\的奇怪显示以及在某些应用程序(例如Neovim)中的不正确/难以理解的显示,以及949不支持的朝鲜语字符似乎变得最近更多的问题。

最佳答案

笔记:

  • 此答案显示了如何将Windows控制台中的字符编码切换为 UTF-8 (代码页65001),以便诸如cmd.exe和PowerShell的 shell 在与外部(控制台)通信时正确地编码和解码字符(文本) )中的程序,以及cmd.exe中的文件I/O。[1]
  • 相比之下,
  • 如果您关注的是控制台窗口中 Unicode字符呈现的局限性的单独方面,请参阅this answer的中部和底部,在此还将讨论其他控制台(终端)应用程序。

  • Does Microsoft provide an improved / complete alternative to chcp 65001 that can be saved permanently without manual alteration of the Registry?


    从(至少) Windows 10 (版本1903)开始,您可以选择 将系统语言环境(非Unicode程序的语言)设置为UTF-8 ,但是 功能在撰写本文时处于beta版
    要激活它:
  • 运行intl.cpl(在“控制面板”中打开区域设置)
  • 请按照以下屏幕快照中的说明进行操作。

  • enter image description here
  • 这将使所有将来的控制台窗口默认为UTF-8(chcp 65001)
  • 警告:
  • 如果您使用的是Windows PowerShell,这还将使Get-ContentSet-Content (以及Windows PowerShell默认情况下的其他上下文,因此系统处于 Activity 状态的ANSI代码页)默认为UTF-8 (始终使用PowerShell Core(v6 +))做)。这意味着,在没有-Encoding参数的情况下,将误读经过ANSI编码的无BOM文件(这在历史上很常见),并且使用Set-Content创建的文件将为UTF-8而不是ANSI编码。
  • [已在PowerShell 7.1中修复]至少在PowerShell 7.0上,基础.NET版本(.NET Core 3.1)中的错误导致PowerShell中的后续错误:意外地将UTF-8 BOM附加到发送到通过stdin进行外部处理(与$OutputEncoding的设置无关),尤其是破坏了Start-Job -请参阅this GitHub issue
  • 并非所有字体都使用Unicode,因此请选择TT(TrueType)字体,但即使它们通常仅支持所有字符的子集,因此您可能必须尝试使用​​特定字体以查看是否关心的所有字符都已表示-有关详细信息,请参见this answer,它还讨论了具有更好的Unicode渲染支持的替代控制台(终端)应用程序。
  • 正如eryksun所指出的那样,不“讲” UTF-8的旧版控制台应用程序将仅限于纯ASCII输入,并且在尝试输出(7位)ASCII范围以外的字符时将产生错误的输出。 (在过时的Windows 7及更低版本中,程序甚至可能崩溃)。
    如果运行旧版控制台应用程序对您来说很重要,请参阅注释中eryksun的建议。


  • 但是,对于Windows PowerShell,使用还是不够的:
  • 您还必须另外$OutputEncoding首选项变量也设置为UTF-8 :$OutputEncoding = [System.Text.UTF8Encoding]::new() [2];将命令添加到$PROFILE(仅限当前用户)或$PROFILE.AllUsersCurrentHost(所有用户)文件中是最简单的。
  • 幸运的是,在PowerShell Core中不再需要此功能,它在内部始终默认为无BOM的UTF-8。


  • 如果在您的环境中不能将系统语言环境设置为UTF-8,则使用启动命令代替:
    注意:上述注意事项在这里同样适用。如果运行旧版控制台应用程序对您来说很重要,请参阅注释中eryksun的建议。
  • 对于PowerShell (两个版本),将以下行添加到$PROFILE(仅限当前用户)或$PROFILE.AllUsersCurrentHost(所有用户)文件中,等效于chcp 65001,并添加设置首选项变量$OutputEncoding以指示PowerShell将数据发送至通过UTF-8中的管道进行外部程序:
  • 请注意,从PowerShell session 内部运行chcp 65001无效,因为.NET在启动时缓存控制台的输出编码,并且不知道以后对chcp进行的更改;此外,如上所述,Windows PowerShell要求设置$OutputEncoding-有关详细信息,请参见this answer

  • $OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
  • 例如,以下是一种快速方法,以编程方式将此行添加到$PROFILE中:
  • '$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding' + [Environment]::Newline + (Get-Content -Raw $PROFILE) | Set-Content -Encoding utf8 $PROFILE
  • 对于cmd.exe ,通过注册表在键AutoRun(仅限当前用户)或HKEY_CURRENT_USER\Software\Microsoft\Command Processor(所有用户)的HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor值中定义自动运行命令:
  • 例如,您可以使用PowerShell为您创建此值:

  • # Auto-execute `chcp 65001` whenever the current user opens a `cmd.exe` console
    # window (including when running a batch file):
    Set-ItemProperty 'HKCU:\Software\Microsoft\Command Processor' AutoRun 'chcp 65001 >NUL'

    可选阅读:为什么Windows PowerShell ISE是一个较差的选择:
    尽管ISE的确比控制台具有更好的Unicode渲染支持,但通常是一个差的选择:
  • 首先,ISE已过时:它不支持PowerShell Core,将来所有的开发都会进行下去,而且它也不是跨平台的,这与两个PowerShell版本的新的首要IDE Visual Studio Code不同,后者已经使用了UTF对于PowerShell Core,默认情况下为-8,可以将其配置为Windows PowerShell。
  • ISE通常是一个用于开发脚本的环境,而不是用于在生产环境中运行它们的环境(如果您还为其他人编写脚本,则应假定它们将在控制台中运行)。值得注意的是,在运行脚本方面,ISE的行为在所有方面都不尽相同。
  • 正如eryksun所指出的,ISE不支持运行交互式外部控制台程序,即需要用户输入的程序:

  • The problem is that it hides the console and redirects the process output (but not input) to a pipe. Most console applications switch to full buffering when a file is a pipe. Also, interactive applications require reading from stdin, which isn't possible from a hidden console window. (It can be unhidden via ShowWindow, but a separate window for input is clunky.)


  • 如果您愿意遵守此限制,那么将 Activity 代码页切换到65001(UTF-8)以便与外部程序进行正确的通信需要一种尴尬的解决方法:
  • 您必须首先通过从内置控制台运行任何外部程序来强制创建隐藏的控制台窗口,例如chcp-您将看到控制台窗口短暂闪烁。
  • 只有这样,您才能将[console]::OutputEncoding(和$OutputEncoding)设置为UTF-8,如上所示(如果尚未创建隐藏控制台,则将获得handle is invalid error)。


  • [1]在PowerShell中,如果您从不调用外部程序,则不必担心系统区域设置( Activity 代码页):PowerShell本地命令和.NET调用始终通过UTF-16字符串(本地.NET字符串)进行通信,在文件I/O上应用独立于系统区域设置的默认编码。同样,由于Windows API函数的Unicode版本用于向控制台打印和从控制台读取,因此非ASCII字符始终可以正确打印(在控制台的呈现限制内)。
    相比之下,在 cmd.exe中,系统区域设置对于文件I/O也很重要(特别是对于批处理文件源代码采用何种编码),而不仅仅是与外部程序进行通信,例如在 for /f循环中读取程序输出时。
    [2]在无法使用静态 ::new()方法的PowerShell v4-中,使用 $OutputEncoding = (New-Object System.Text.UTF8Encoding).psobject.BaseObject。有关为什么需要 .psobject.BaseObject部分的信息,请参见 GitHub issue #5763

    关于windows - 在命令提示符/Windows Powershell(Windows 10)中使用UTF-8编码(CHCP 65001),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57131654/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com