如何在Windows命令行中使用unicode字符?

时间:2008-12-23 09:30:59

标签: unicode command-line input windows-console

我们在Team Foundation Server(TFS)中有一个项目,其中包含非英文字符(š)。在尝试编写一些与构建相关的内容时,我们偶然发现了一个问题 - 我们无法将š字母传递给命令行工具。命令提示符或其他什么不会搞砸, tf.exe 实用程序找不到指定的项目。

我尝试过.bat文件的不同格式(ANSI,带有和不带BOM的UTF-8)以及用JavaScript编写脚本(这本身就是Unicode) - 但没有运气。如何执行程序并将其传递给 Unicode 命令行?

19 个答案:

答案 0 :(得分:367)

尝试:

chcp 65001

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

答案 1 :(得分:44)

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

  • CMD和“控制台”是不相关的因素。 CMD.exe只是一个准备“在控制台内”工作的程序(“控制台应用程序”)。
  • AFAIK,CMD完全支持Unicode;当任何代码页处于活动状态时,您可以输入/输出所有Unicode字符。
  • Windows'控制台对Unicode有很多支持 - 但它并不完美(只是“足够好”;见下文)。
  • chcp 65001非常危险。除非程序是专门设计用于解决Windows API中的缺陷(或使用具有这些变通方法的C运行时库),否则它将无法可靠地工作。 Win8 fixes ½ of these problems with cp65001, but the rest is still applicable to Win10
  • 我在cp1252工作。正如我已经说过的那样:要在控制台中输入/输出Unicode,不需要设置代码页

详情

  • 要将Unicode读取/写入控制台,应用程序(或其C运行时库)应足够智能,不能使用File-I/O API,而应使用Console-I/O API。 (例如,请参阅how Python does it。)
  • 同样,要读取Unicode命令行参数,应用程序(或其C运行时库)应足够智能以使用相应的API。
  • 控制台字体渲染仅支持BMP中的Unicode字符(换句话说:低于U+10000)。仅支持简单的文本呈现(因此欧洲 - 以及一些东亚语言 - 应该可以正常工作 - 只要使用预先组合的表单)。 [这里有东亚的minor fine print和字符U + 0000,U + 0001,U + 30FB。]

实际考虑因素

  • Window上的默认值不是很有用。为了获得最佳体验,应该调整3个配置:

    • 输出:全面的控制台字体。为了获得最佳效果,我建议my builds。 (安装说明在那里 - 并且也在本页的其他答案中列出。)
    • 用于输入:功能强大的键盘布局。为了获得最佳效果,我建议my layouts
    • 输入:allow HEX input of Unicode
  • 另一个问题是“粘贴”到控制台应用程序中(非常技术性):

    • HEX输入在KeyUp Alt上发送一个字符; 所有KeyDown上发送角色的其他方式;如此多的应用程序还没有准备好在KeyUp上看到一个字符。 (仅适用于使用Console-I/O API的应用程序。)
    • 结论:许多应用程序不会对HEX输入事件做出反应。
    • 此外,“粘贴”字符会发生什么情况取决于当前的键盘布局:如果可以在不使用前缀键的情况下键入字符(但使用任意复杂的修饰符组合,如Ctrl-Alt-AltGr-Kana-Shift-Gray*中所示),那么它是通过模拟按键提供。这是任何应用程序所期望的 - 所以粘贴任何只包含这些字符的东西都可以。
    • 但是,“其他”字符由模拟HEX输入提供。

    结论 :除非您的键盘布局支持输入大量没有前缀键的字符,否则某些错误的应用程序可能会跳过字符{ {1}}通过控制台的用户界面:Paste。 (是我推荐使用键盘布局的原因!)

还应该记住,Windows 的“替代”,“功能更强大”的控制台根本不是游戏机。它们不支持Alt-Space E P API,因此依赖这些API工作的程序将无法运行。 (但是,只使用“文件I / O API到控制台文件句柄”的程序可以正常工作。)

此类非控制台的一个示例是MicroSoft的Console-I/O的一部分。我不用这个;要试验,按下并释放Powershell,然后输入WinKey

(另一方面,有ConEmuANSICON这样的程序试图做更多:他们“尝试”拦截powershell API以制作“真正的控制台应用程序”这绝对适用于玩具示例程序;在现实生活中,这可能会或可能不会解决您的特定问题。实验。)

摘要

  • 设置字体,键盘布局(以及可选的允许HEX输入)。

  • 仅使用通过Console-I/O API的程序,并接受Unicode命令行参数。例如,任何Console-I/O编译的程序应该没问题。正如我已经说过的那样,cygwin也很好。

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

答案 2 :(得分:36)

我有同样的问题(我来自捷克共和国)。我有一个Windows的英文版,我必须使用共享驱动器上的文件。文件路径包括特定于捷克语的字符。

对我有用的解决方案是:

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

我的批处理文件:

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

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

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

答案 3 :(得分:25)

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

Changing language for non-Unicode programs

答案 4 :(得分:13)

更改Windows控制台的默认代码页非常困难。当您在网上搜索时,您会发现不同的提案,但有些提案可能会完全破坏您的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”。

您可以从Code Page Identifiers

获取的所有可用号码的完整列表

注意,这些设置仅适用于当前用户。如果您想为所有用户设置,请将SET ROOT_KEY="HKEY_CURRENT_USER"替换为SET ROOT_KEY="HKEY_LOCAL_MACHINE"

答案 5 :(得分:12)

实际上,诀窍是命令提示符实际上理解这些非英文字符,只是无法正确显示它们。

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

答案 6 :(得分:10)

在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 ゴシック

现在我们需要添加一个支持Courier New所需字符的TrueType字体。我们通过在字符串名称中添加零来完成此操作,因此在这种情况下,下一个将是“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

答案 7 :(得分:5)

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

  1. 您需要支持Unicode的字体。 Windows附带Lucida控制台,可以通过右键单击命令提示符的标题栏并单击Defaults选项来选择。这也可以访问颜色。请注意,您也可以通过选择Properties来更改以某种方式调用的命令窗口的设置(例如,在此处打开,Visual Studio)。
  2. 您需要将代码页设置为cp65001,这似乎是Microsoft试图为命令提示符提供UTF-7和UTF-8支持。通过在命令提示符中运行 chcp 65001来执行此操作。一旦设置,它将一直保持这种状态,直到窗口关闭。每次启动cmd.exe时都需要重做。
  3. 要获得更持久的解决方案,请参阅超级用户上的this answer。简而言之,使用REG_SZ处的regedit创建HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor(字符串)条目,并将其命名为AutoRun。将其值更改为chcp 65001。如果您不想查看命令的输出消息,请改用@chcp 65001>nul

    某些程序在与此编码交互时遇到问题,MinGW是一个值得注意的程序,在使用无意义的错误消息进行编译时失败。尽管如此,这种方法效果很好,并且不会导致大多数程序出现错误。

答案 8 :(得分:4)

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

MinGW

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

Enter image description here

当然,你也可以获得所有常见的* nix好东西,如grep,find,less等。

答案 9 :(得分:3)

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

我解决了这个问题:

  1. 我将命令提示符的字体更改为Lucida Console。 (这一步必须与你的情况无关。它只能与你在屏幕上看到的内容有关,而不是与真正的角色有关。)

  2. 我将代码页更改为Windows-1253。您可以在命令提示符下通过“chcp 1253”执行此操作。它适合我的情况,我想看看UTF-8。

答案 10 :(得分:2)

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

如果您在Windows 10上安装了Ubuntu bash,则显示文件名,例如Object {action: "cfgeo_settings", cf_geo_enable_ssl: "true"} admin.php?page=cf-geoplugin-settings:1733 /wp-admin/admin-ajax.php admin.php?page=cf-geoplugin-settings:1736 0 dir

  1. 将区域设置为支持非utf 8字符。

  2. 之后,控制台的字体将更改为该区域设置的字体,并且还会更改控制台的编码。

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

    1. ls
    2. 将页面更改为utf-8
    3. 更改为支持utf-8的字体,例如Lucida Console
    4. 使用chcp 65001命令查看文件内容,如果在Windows 10上安装了Ubuntu bash,则使用type
    5. 请注意,在将控制台的编码设置为utf-8后,我无法使用中文输入法在cmd中键入中文字符。
    6. 最懒的解决方案:只需使用控制台模拟器,例如http://cmder.net/

答案 11 :(得分:2)

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

启用此功能:“测试版:使用Unicode UTF-8进行全球语言支持”

  

控制面板->区域设置->管理标签->更改   系统区域设置...

Region Settings

答案 12 :(得分:1)

将代码页更改为1252对我有用。对我来说问题是符号双doller§在Windows Server 2008上由DOS转换为另一个符号。

我在我的BCP声明中使用了CHCP 1252和一个上限^§。

答案 13 :(得分:1)

如果您在DOS窗口中键入路径/文件名时计算机显示正确的路径/文件名,则快速决定.bat文件:

  1. copy con temp.txt [按Enter]
  2. 输入路径/文件名[按Enter]
  3. Ctrl-Z [按Enter]
  4. 这样就可以创建一个.txt文件 - temp.txt。在记事本中打开它,复制文本(不要担心它看起来不可读)并将其粘贴到.bat文件中。 执行在DOS窗口中以这种方式创建的.bat为mе(Cyrillic,Bulgarian)工作。

答案 14 :(得分:1)

更清洁的事情:只需安装可用的免费Microsoft日语语言包即可。 (其他东方语言包也可以使用,但我测试了日语。)

这为您提供了具有较大字形集的字体,使其成为默认行为,更改各种Windows工具,如cmd,写字板等。

答案 15 :(得分:1)

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

Windows使用UTF-16编码两个字节的字符串,因此您需要从程序中的OS中获取它们。有两种方法可以做到这一点-

1)Microsoft有一个扩展,允许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://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvw

阅读:http://utf8everywhere.org 详细信息,尤其是在您支持其他操作系统的情况下。

答案 16 :(得分:1)

从2019年6月开始,使用Windows 10,您无需更改代码页。

请参见“ Introducing Windows Terminal”(摘自Kayla Cinnamon)和Microsoft/Terminal
通过使用Consolas字体,将提供 partial Unicode支持。

Microsoft/Terminal issue 387中所述:

  

目前有87,887个表意文字使用Unicode。你也都需要吗?
  我们需要一个边界,超出边界的字符应通过字体后备/字体链接/其他方式处理。

     

Consolas应该涵盖的内容:

     
      
  • 用作CLI中现代OSS程序使用的符号的字符。
  •   
  • 这些字符应遵循Consolas的设计和指标,并与现有Consolas字符正确对齐。
  •   
     

Consolas不应涵盖的内容:

     
      
  • 超出拉丁,希腊和西里尔字母的字符和标点符号,尤其是字符需要复杂的形状(如阿拉伯语)。
  •   
  • 这些字符应使用字体后备。
  •   

答案 17 :(得分:0)

我遇到了类似的问题,删除了Unicode命名文件,在批处理文件中用短(8点3)名称引用它们。

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

答案 18 :(得分:-4)

至utf-8: chcp 65001

返回默认值: chcp 437