我们在Team Foundation Server (TFS)中有一个项目,其中有一个非英语字符(š)。当尝试编写一些与构建相关的脚本时,我们偶然发现了一个问题——我们不能将这个字母传递给命令行工具。命令提示符或其他东西会把它弄乱,tf.exe实用程序无法找到指定的项目。

我尝试了不同格式的.bat文件(ANSI, UTF-8,带BOM和不带BOM),以及用JavaScript编写脚本(本质上是Unicode) -但运气不好。如何执行程序并传递一个Unicode命令行?


Try:

chcp 65001

这会将代码页更改为UTF-8。此外,还需要使用Lucida控制台字体。


实际上,关键在于命令提示符实际上理解这些非英语字符,只是不能正确地显示它们。

当我在命令提示符中输入包含一些非英语字符的路径时,它显示为“?? ?”?????? ? ? ? ? ?”当您提交命令(cd "???????? ?????”在我的情况下),一切都按照预期工作。


我也有同样的问题(我来自捷克共和国)。我安装了英文的Windows,而且我必须使用共享驱动器上的文件。文件的路径包含捷克特有的字符。

适合我的解决方案是:

在批处理文件中,修改字符集页

批处理文件:

chcp 1250
copy "O:\VEŘEJNÉ\ŽŽŽŽŽŽ\Ž.xls" c:\temp

批处理文件必须保存在CP 1250中。

注意,控制台不会正确地显示字符,但它会理解它们……


对于类似的问题(我的问题是在命令提示符上显示来自MySQL的UTF-8字符),

我是这样解决的:

我把命令提示符的字体改成了Lucida Console。(此步骤必须与您的情况无关。它只与你在屏幕上看到的东西有关,而与角色本身无关)。 我把代码页改成了Windows-1253。您可以在命令提示符中通过“chcp 1253”执行此操作。它适用于我想要查看UTF-8的情况。


检查非unicode程序的语言。如果你在Windows控制台中有俄语问题,那么你应该在这里设置俄语:


一个更好更干净的方法是:安装可用的免费微软日语包。(其他东方语言包也可以,但我已经测试了日语包。)

这将为您提供具有较大字形集的字体,使它们成为默认行为,更改各种Windows工具,如cmd, WordPad等。


把代码页改成1252对我有用。我遇到的问题是,Windows Server 2008上的DOS正在将符号double doller§转换为另一个符号。

在我的BCP声明^§中,我使用了CHCP 1252和它之前的一个帽。


一个快速决定。bat文件,如果你的电脑显示你的路径/文件名正确时,你在dos窗口输入:

copy con temp.txt[按Enter] 输入路径/文件名[按Enter] 按Ctrl-Z[按Enter]

这样你就创建了一个。txt文件- temp.txt。在记事本中打开它,复制文本(不要担心它看起来不可读),并粘贴到你的。bat文件中。 在DOS-window中执行以这种方式创建的.bat对mе(西里尔语,保加利亚语)有效。


更改Windows控制台的默认Codepage是相当困难的。当你在网上搜索时,你会发现不同的建议,然而其中一些可能会完全破坏你的Windows,即你的PC无法再启动。

最安全的解决方案是: 转到你的注册表键HKEY_CURRENT_USER\Software\Microsoft\Command Processor并添加字符串值Autorun = chcp 65001。

或者,对于最常见的代码页,可以使用这个小的批处理脚本。

@ECHO off

SET ROOT_KEY="HKEY_CURRENT_USER"


FOR /f "skip=2 tokens=3" %%i in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v OEMCP') do set OEMCP=%%i

ECHO System default values:

ECHO.
ECHO ...............................................
ECHO Select Codepage 
ECHO ...............................................
ECHO.
ECHO 1 - CP1252
ECHO 2 - UTF-8
ECHO 3 - CP850
ECHO 4 - ISO-8859-1
ECHO 5 - ISO-8859-15
ECHO 6 - US-ASCII
ECHO.
ECHO 9 - Reset to System Default (CP%OEMCP%)
ECHO 0 - EXIT
ECHO.


SET /P  CP="Select a Codepage: "

if %CP%==1 (
    echo Set default Codepage to CP1252
    reg add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 1252>nul" /f
) else if %CP%==2 (
    echo Set default Codepage to UTF-8
    reg add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 65001>nul" /f
) else if %CP%==3 (
    echo Set default Codepage to CP850
    reg add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 850>nul" /f
) else if %CP%==4 (
    echo Set default Codepage to ISO-8859-1
    add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 28591>nul" /f
) else if %CP%==5 (
    echo Set default Codepage to ISO-8859-15
    add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 28605>nul" /f
) else if %CP%==6 (
    echo Set default Codepage to ASCII
    add "%ROOT_KEY%\Software\Microsoft\Command Processor" /v Autorun /t REG_SZ /d "@chcp 20127>nul" /f
) else if %CP%==9 (
    echo Reset Codepage to System Default
    reg delete "%ROOT_KEY%\Software\Microsoft\Command Processor" /v AutoRun /f
) else if %CP%==0 (
    echo Bye
) else (
    echo Invalid choice
    pause
)

使用@chcp 65001>nul而不是chcp 65001会抑制每次启动一个新的命令行窗口时都会得到的输出“活动代码页:65001”。

所有可用号码的完整列表,您可以从代码页标识符

注意,设置只适用于当前用户。如果你想为所有用户设置它,将set ROOT_KEY="HKEY_CURRENT_USER"替换为set ROOT_KEY="HKEY_LOCAL_MACHINE"


我通过在批处理文件中使用它们的短名称(8点3)来删除以unicode命名的文件,从而避免了类似的问题。

短名称可以通过执行dir /x查看。显然,这只适用于已知的Unicode文件名。


一个非常简单的选择是安装一个Windows bash shell,如MinGW并使用它:

有一点学习曲线,因为你将需要使用Unix命令行功能,但你会喜欢它的力量,你可以将控制台字符集设置为UTF-8。

当然,您还可以得到所有常见的*nix好东西,如grep、find、less等。


由于我还没有看到Python 2.7的完整答案,我将概述两个重要步骤和一个非常有用的可选步骤。

You need a font with Unicode support. Windows comes with Lucida Console which may be selected by right-clicking the title bar of command prompt and clicking the Defaults option. This also gives access to colours. Note that you can also change settings for command windows invoked in certain ways (e.g, open here, Visual Studio) by choosing Properties instead. You need to set the code page to cp65001, which appears to be Microsoft's attempt to offer UTF-7 and UTF-8 support to command prompt. Do this by running chcp 65001 in command prompt. Once set, it remains this way until the window is closed. You'll need to redo this every time you launch cmd.exe.

要获得更永久的解决方案,请参考超级用户上的答案。简而言之,在HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor中使用regedit创建一个REG_SZ (String)条目,并将其命名为AutoRun。将其值修改为chcp 65001。如果不想看到命令的输出消息,请使用@chcp 65001>nul。

有些程序在与这种编码进行交互时遇到麻烦,MinGW就是一个显著的例子,它在编译时出现无意义的错误消息而失败。尽管如此,这工作得非常好,并且不会对大多数程序造成错误。


在Windows 10 x64机器上,我通过以下方法使命令提示符显示非英语字符:

打开提升命令提示符(以管理员身份运行CMD.EXE)。通过以下方法查询控制台可用的TrueType字体的注册表:

    REG query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont"

你会看到如下输出:

    0    REG_SZ    Lucida Console
    00    REG_SZ    Consolas
    936    REG_SZ    *新宋体
    932    REG_SZ    *MS ゴシック

现在我们需要添加一个TrueType字体,支持你需要的字符,如Courier New。我们通过在字符串名后面加0来实现,所以在这种情况下,下一个字符串将是"000":

    REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v 000 /t REG_SZ /d "Courier New"

现在我们实现了UTF-8支持:

    REG ADD HKCU\Console /v CodePage /t REG_DWORD /d 65001 /f

设置默认字体为Courier New:

    REG ADD HKCU\Console /v FaceName /t REG_SZ /d "Courier New" /f

设置字体大小为20:

    REG ADD HKCU\Console /v FontSize /t REG_DWORD /d 20 /f

启用快速编辑,如果你喜欢:

    REG ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f

这个问题很烦人。我通常在文件名和文件内容中使用中文字符。请注意,我使用的是Windows 10,下面是我的解决方案:

如果在Windows 10上安装了Ubuntu bash,则显示文件名为dir或ls

设置该区域支持非utf8字符。 在此之后,控制台的字体将被更改为该地区的字体,它还将更改控制台的编码。

在完成以上步骤后,为了使用命令行工具显示UTF-8文件的文件内容

通过chcp 65001将页面更改为utf-8 更改为支持utf-8的字体,例如Lucida Console 使用type命令查看文件内容,如果你在Windows 10上安装了Ubuntu bash,可以使用cat命令查看 请注意,在将控制台的编码设置为utf-8后,我无法在cmd中使用中文输入法输入汉字。

最懒的解决方案:只使用控制台模拟器,如http://cmder.net/


我的背景:我在控制台中使用Unicode输入/输出已经很多年了(并且每天都这么做。此外,我还为这项任务开发了支持工具)。只要你了解以下事实/限制,问题就很少:

CMD and “console” are unrelated factors. CMD.exe is a just one of programs which are ready to “work inside” a console (“console applications”). AFAIK, CMD has perfect support for Unicode; you can enter/output all Unicode chars when any codepage is active. Windows’ console has A LOT of support for Unicode — but it is not perfect (just “good enough”; see below). chcp 65001 is very dangerous. Unless a program was specially designed to work around defects in the Windows’ API (or uses a C runtime library which has these workarounds), it would not work reliably. Win8 fixes ½ of these problems with cp65001, but the rest is still applicable to Win10. I work in cp1252. As I already said: To input/output Unicode in a console, one does not need to set the codepage.

细节

To read/write Unicode to a console, an application (or its C runtime library) should be smart enough to use not File-I/O API, but Console-I/O API. (For an example, see how Python does it.) Likewise, to read Unicode command-line arguments, an application (or its C runtime library) should be smart enough to use the corresponding API. Console font rendering supports only Unicode characters in BMP (in other words: below U+10000). Only simple text rendering is supported (so European — and some East Asian — languages should work fine — as far as one uses precomposed forms). [There is a minor fine print here for East Asian and for characters U+0000, U+0001, U+30FB.]

实际考虑

The defaults on Window are not very helpful. For best experience, one should tune up 3 pieces of configuration: For output: a comprehensive console font. For best results, I recommend my builds. (The installation instructions are present there — and also listed in other answers on this page.) For input: a capable keyboard layout. For best results, I recommend my layouts. For input: allow HEX input of Unicode. One more gotcha with “Pasting” into a console application (very technical): HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.) Conclusion: many application would not react on HEX input events. Moreover, what happens with a “Pasted” character depends on the current keyboard layout: if the character can be typed without using prefix keys (but with arbitrary complicated combination of modifiers, as in Ctrl-Alt-AltGr-Kana-Shift-Gray*) then it is delivered on an emulated keypress. This is what any application expects — so pasting anything which contains only such characters is fine. However, the “other” characters are delivered by emulating HEX input. Conclusion: unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI: Alt-Space E P. (This is why I recommend using my keyboard layouts!)

我们还应该记住,Windows上的“替代的、更强大的”主机根本不是主机。它们不支持Console-I/O api,因此依赖这些api工作的程序将无法正常工作。(不过,只使用“文件- i /O api到控制台文件句柄”的程序可以很好地工作。)

微软的Powershell就是一个非主机的例子。我不用它;要进行实验,按下并释放WinKey,然后输入powershell。


(另一方面,有一些程序,如ConEmu或ANSICON,试图做更多的事情:他们“试图”拦截控制台i /O api,以使“真正的控制台应用程序”也能工作。这绝对适用于玩具示例程序;在现实生活中,这可能解决不了您的特定问题。实验。)

总结

设置字体,键盘布局(并可选地,允许十六进制输入)。 只使用通过Console-I/O api的程序,并接受Unicode命令行参数。例如,任何由cygwin编译的程序都可以。正如我已经说过的,CMD也很好。

UPD:最初,对于cp65001中的一个错误,我混淆了内核层和CRTL层(UPD²:和Windows用户模式API!)另外:Win8修复了这个错误的一半;我澄清了关于“更好的控制台”应用程序的部分,并添加了Python如何做到这一点的参考。


我在这里看到了几个答案,但它们似乎没有解决这个问题——用户希望从命令行获得Unicode输入。

Windows使用UTF-16进行两个字节字符串的编码,因此您需要在程序中从操作系统获取这些。有两种方法可以做到这一点

1)微软有一个扩展,允许main采用一个宽字符数组: Int wmain(Int argc, wchar_t *argv[]); https://msdn.microsoft.com/en-us/library/6wd819wh.aspx

2)调用windows api获取命令行的unicode版本 wchar_t win_argv = (wchar_t)CommandLineToArgvW(GetCommandLineW(), &nargs); https://learn.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvw

读这个:http://utf8everywhere.org 获取详细信息,特别是如果您支持其他操作系统。


我发现这个方法在新版本的Windows 10中很有用:

打开此功能:"Beta版:使用Unicode UTF-8支持全球语言"

控制面板->区域设置->管理选项卡->更改 系统区域设置…


从2019年6月开始,使用Windows 10,你将不必更改代码页。

参见“介绍Windows终端”(来自Kayla Cinnamon)和Microsoft/Terminal。 通过使用Consolas字体,将提供部分Unicode支持。

如Microsoft/Terminal issue 387中所述:

There are 87,887 ideographs currently in Unicode. You need all of them too? We need a boundary, and characters beyond that boundary should be handled by font fallback / font linking / whatever. What Consolas should cover: Characters that used as symbols that used by modern OSS programs in CLI. These characters should follow Consolas' design and metrics, and properly aligned with existing Consolas characters. What Consolas should NOT cover: Characters and punctuation of scripts that beyond Latin, Greek and Cyrillic, especially characters need complex shaping (like Arabic). These characters should be handled with font fallback.


对于那些使用WSL但又不想要Cygwin或Git的额外包的人来说,wsltty是可用的,它只提供支持UTF-8的终端