我们在Team Foundation Server(TFS)中有一个项目,其中包含非英语字符(š)。当尝试编写一些与构建相关的东西的脚本时,我们偶然发现了一个问题-我们无法将š字母传递给命令行工具。命令提示符或其他原因使它混乱,并且tf.exe实用程序找不到指定的项目。带有和不带有BOM的文件以及使用JavaScript编写脚本的脚本(本质上是Unicode)-但没有运气。如何执行程序并将其传递给Unicode命令行?

评论

@JohannesDewender-复制粘贴出错了?

Python 3.6:“ Windows上的默认控制台接受该版本的所有Unicode字符”(嗯,大多数对我来说),但是您需要配置控制台:右键单击Windows顶部(cmd或python IDLE的顶部) ),在默认/字体中选择“ Lucida控制台”。

在Windows控制台应用程序中输出unicode字符串,在Windows中使用C ++将Unicode输出到控制台

如何在Windows控制台上输出Unicode字符串的可能重复项

@LưuVĩnhPhúc-不,这是关于传递unicode命令行参数,而不是在控制台中显示文本。控制台可能根本不参与。

#1 楼

我的背景:多年来,我在控制台中使用Unicode输入/输出(并且每天都要做很多工作。此外,我还专门为此任务开发了支持工具)。就您所了解的以下事实/局限而言,几乎没有问题:

CMD和“控制台”是不相关的因素。 CMD.exe只是准备在控制台中“工作”的程序之一(“控制台应用程序”)。
AFAIK,CMD完美支持Unicode;您可以在任何代码页处于活动状态时输入/输出所有Unicode字符。
Windows控制台对Unicode有很多支持,但它并不完美(仅“足够好”;请参见下文)。

chcp 65001非常危险。除非专门设计一个程序来解决Windows API中的缺陷(或使用具有这些解决方法的C运行时库),否则该程序将无法可靠运行。 Win8使用cp65001解决了其中的½问题,但其余问题仍然适用于Win10。
我在cp1252中工作。正如我已经说过的:要在控制台中输入/输出Unicode,不需要设置代码页。

详细信息


读取/写入Unicode对于控制台,应用程序(或其C运行时库)应该足够聪明,以使用File-I/O API,而不是Console-I/O API。 (例如,查看Python的工作方式。)
同样,要读取Unicode命令行参数,应用程序(或其C运行时库)应足够聪明以使用相应的API。
字体渲染仅支持BMP中的Unicode字符(换句话说,就是U+10000之下)。仅支持简单的文本呈现(因此,只要使用预设的形式,欧洲语言(和某些东亚语言)应该可以正常工作)。 [这里为东亚和U + 0000,U + 0001,U + 30FB字符提供了一个小字样。]

实际考虑事项



Window的默认设置不是很有帮助。为了获得最佳体验,应该调整3种配置:


输出:全面的控制台字体。为了获得最佳结果,我推荐我的构建。 (安装说明在此处-并在此页的其他答案中也列出。)
对于输入:功能强大的键盘布局。为了获得最佳效果,我建议使用我的布局。
对于输入:允许以十六进制输入Unicode。



还有一个将“粘贴”到控制台应用程序中的陷阱(非常技术性):


HEX输入在KeyUpAlt上传递字符;传递角色的所有其他方式都在KeyDown上进行;许多应用程序还没有准备好在KeyUp上看到字符。 (仅适用于使用Console-I/O API的应用程序。)结论:许多应用程序不会对HEX输入事件做出反应。
此外,“粘贴”字符会发生什么取决于当前的键盘布局:如果该字符可以在不使用前缀键的情况下进行键入(但可以使用任意复杂的修饰符组合,例如Ctrl-Alt-AltGr-Kana-Shift-Gray*),然后在模拟的按键上进行传递。这是任何应用程序所期望的— —因此,粘贴仅包含此类字符的任何内容都可以。
但是,“其他”字符是通过模拟十六进制输入来传递的。

结论:除非您使用键盘布局支持输入许多不带前缀键的字符,当您通过控制台UI Paste进行调试时,某些错误的应用程序可能会跳过字符。 (这就是为什么我建议使用键盘布局的原因!)


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

这样的非控制台的一个示例是MicroSoft Console-I/O的一部分。我不用这个;要进行实验,请按下并释放Powershell,然后键入WinKey


(另一方面,有些程序例如powershellConEmu会尝试做更多的事情:它们“尝试”拦截ANSICON API,以使“真正的控制台应用程序”也能工作。这绝对适用于玩具示例程序;在现实生活中,

摘要


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

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

评论


好的,对于这些事情,您应该被接受!太棒了!

– Vilx-
17年12月16日在13:02

我是C ++的新手,仔细阅读后无法理解此答案。有人可以帮我解决这个问题还是做个简单的解释?

–里克
18年6月6日在14:13

@Bachi感谢Bachi,我发现我的键盘布局v73(如上所述)缺少一些支持文件。现在修复! (从我的.log文件来看,它是zip -ru [?!]中的间歇性错误。不知道如何调试它-或将来避免使用…)

–伊莉亚·扎克哈维奇(Ilya Zakharevich)
18/09/20'2:50

@Rick:对!我在Python中添加了一个变通办法的链接(但现在无法找到该补丁的直接链接……)。

–伊莉亚·扎克哈维奇(Ilya Zakharevich)
18-09-20在3:51

@IlyaZakharevich:D谢谢。但是我以某种方式放弃了在Windows上使用unicode。我稍后将使用Linux。

–里克
18-09-20在4:14

#2 楼

请尝试:

chcp 65001


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

评论


您知道是否有办法将其设置为默认值吗?

–AnnanFay
2011年11月14日下午13:55

请注意,Windows的代码页65001支持中存在严重的实现错误,这些错误会破坏许多依赖C标准库IO方法的应用程序,因此这非常脆弱。 (批处理文件也只能在65001中停止工作。)不幸的是,UTF-8是Windows中的二等公民。

– bobince
2011-12-29 21:51

@bobince Windows代码页65001支持中是否包含错误示例?我很好奇,因为我从来没有遇到过,并且谷歌搜索也没有发现任何东西。 (当然,批处理文件确实会停止工作,但是UTF-8几乎不是二等公民...)

–罗马·斯塔科夫
2012年12月3日在2:09



@romkyns:我的理解是,返回字节数的调用(例如fread / fwrite / etc)实际上返回了字符数。这会导致各种各样的症状,例如输入读取不完整,陷入混乱,批处理文件损坏等。一些背景。用于CJK“多字节”语言环境的默认代码页具有内置的特殊处理程序来解决此问题,但是65001不能-不支持。

– bobince
2012年12月4日12:26



但是,有趣的问题是-该错误是因为它应该报告字节,而是报告字符-还是因为使用它的应用程序错误地假定了bytes =字符?换句话说,是API失败还是API使用失败?

–基本
13年11月27日在13:04

#3 楼

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

对我有用的解决方案是:

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

我的批处理文件:

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


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

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

评论


干杯!我需要这样做,以便可以在批处理文件中输入版权字符。

–Lea Hayes
2012年7月30日,下午3:18

在与您几乎相同的情况下,这对我也非常有效。相反,我的路径包含爱尔兰盖尔语字符,即á,é,í,ó和ú。

–Seany84
2014年2月4日在21:43



@vanna解决了我的“网络路径上的土耳其语字符和路径中的空格”。你很棒。

– caglaror
2014年12月4日上午11:39

还可以找到以下资源:msdn.microsoft.com/en-us/library/windows/desktop/…,ss64.com/nt/chcp.html,technet.microsoft.com/en-us/library/bb490874.aspx土耳其语chcp是857。

– caglaror
2014-12-04 11:42



您可能只需要使用其他字体来正确显示字符,Lucida Console就为我工作。

– VlastimilOvčáčík
16年1月5日,11:38

#4 楼

检查非Unicode程序的语言。如果Windows控制台中的俄语存在问题,则应在此处设置俄语:



评论


这不能在cmd中启用对Unicode的支持,它只能将默认代码页切换为cp866(仍为8位字符集)。它甚至使用cp866代替cp1251,这增加了它自己的麻烦。

– ivan_pozdeev
17-10-28在2:30



另请参阅以下我的回答,以获取更新的Windows 10版本中的新选项

– zvi
19年4月14日在11:33

#5 楼

更改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”。

您可以从中获得的所有可用数字的完整列表代码页标识符

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

评论


好主意和可用示例!

–user257319
2015年12月5日,0:30

#6 楼

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

当我在命令提示符中输入包含一些非英语字符的路径时,显示为“ ???????????????????”。当您提交命令时(在我的案例中为cd“ ??? ?????? ?????”),一切按预期进行。

评论


这可能有点危险,因为您可能会遇到命名冲突。例如,如果您有两个都呈现为“ ???”的文件,然后输入“ cd ???”它不知道使用哪个(或更糟的是选择一个任意的)。

–约翰
09年6月16日在13:53

您无需输入???,您可以输入实名,而实名只会显示为???。可以将其视为密码输入框。输入的任何内容均显示为***,但提交的内容为原始文本。

–用户
09年6月16日在14:52

对于直接在命令提示符下运行的命令,确实可以使用。但是,运行.cmd批处理文件时,我仍然需要将chcp 65001放在批处理文件的顶部。

– Wisbucky
17-10-23在22:07

在您的情况下,这是一个字体问题……内容在那里,只是没有合适的字体来显示它。但是OP是不同的。

– WesternGun
17-10-30在12:58

#7 楼

在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。我们通过在字符串名称上添加零来完成此操作,因此在这种情况下,下一个将是“ 000”:

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


将默认字体设置为“ Courier New”:

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


将字体大小设置为20:

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


如果需要,可以启用快速编辑:

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


评论


通常,使用代码页65001只能在带有Creators更新的Windows 10中没有错误的情况下工作。在Windows 7中,它将同时具有输出和输入错误。在Windows 8和Windows 10的早期版本中,它仅具有输入错误,该输入错误将输入限制为7位ASCII。

–太阳神
17年9月9日13:43

我尝试使用此方法,现在字体非常小,似乎是永久的。

–绿色
10月18日6:41

#8 楼

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


您需要一种支持Unicode的字体。 Windows随附有Lucida Console,可通过右键单击命令提示符的标题栏并单击Defaults选项来选择它。这也可以访问颜色。请注意,您还可以通过选择Properties来更改以某些方式(例如,在此处打开,Visual Studio)调用的命令窗口的设置。
您需要将代码页设置为cp65001,这似乎是微软试图提供的UTF-7和UTF-8支持命令提示符。通过在命令提示符下运行chcp 65001来执行此操作。一旦设置,它将保持这种方式,直到关闭窗口。每次启动cmd.exe时都需要重做一次。

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

某些程序无法与此编码进行交互,MinGW是一个值得注意的程序,在编译时会出现错误的错误消息。但是,此方法效果很好,并且不会引起大多数程序的错误。

#9 楼

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

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


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




评论


如何通过使用Powershell或cmd实现此目的?

– Corey
19年11月19日,0:48

我试图在控制台中显示中文字符,并且这样做在Windows 10 64位(安装为土耳其语,后来更改为英文)中不起作用。接下来,我将尝试安装中文,看看是否可以使用。

–akinuri
4月25日12:02

#10 楼

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

请参阅“ Windows终端简介”(来自Kayla Cinnamon)和Microsoft / Terminal。
通过使用

Microsoft/Terminal第387期中所述:


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

Consolas应该涵盖的内容:


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

Consolas不应涵盖的内容:


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



#11 楼

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



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



当然,您还会获得所有常用的* nix好东西,例如grep,find,less等。

评论


在这种(旧)情况下,问题在于脚本而不是控制台。使用bash脚本可以解决此问题吗?

– Vilx-
16年1月2日,15:32

是的,的确,可以将它们的bash脚本标记为UTF-8,并且比Windows批处理文件具有更多的功能-我知道这是一个旧案例,但认为该选项值得标记,以备将来参考,因为MS似乎没有在Unicode方面变得更好。

–史蒂夫·巴恩斯(Steve Barnes)
16年1月2日在21:46

grep,查找和更少。

– Peter Mortensen
17年1月1日23:47

输出UTF-8编码的字符就可以了。但是输入仍然由系统代码页编码。

–里克
2018年6月6日14:01



补充一下,如果您使用Git,Windows用户可能已经具有bash外壳:只需打开Git> Git Bash窗口即可。

– Skomisa
18-09-25在1:53

#12 楼

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

我这样解决:


我将命令提示符的字体更改为Lucida Console。 (此步骤必须与您的情况无关。它只与您在屏幕上看到的内容有关,而与字符的真实性无关)。
我将代码页更改为Windows-1253。您可以通过“ chcp 1253”在命令提示符下执行此操作。它适用于我想查看UTF-8的情况。


评论


Windws-1253不是Unicode代码页。这是一个标准的256个字符的代码页。显然,您只使用了可以在该代码页中显示的字符,但是它不是通用的。

– Vilx-
2012年12月2日13:05



#13 楼

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

如果在Windows 10上安装了Ubuntu bash,则显示文件名,例如dirls


设置区域以支持非utf 8字符。
之后,控制台的字体将更改为该语言环境的字体,并且还会更改控制台的编码。

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


将页面更改为utf- 8 by chcp 65001

更改为支持utf-8的字体,例如Lucida Console
使用type命令查看文件内容,或者如果在Windows 10上安装了Ubuntu bash,则使用cat
请注意,将控制台的编码设置为utf-8后,我无法使用中文输入法在cmd中键入中文字符。

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

评论


这不适合我。点命令输出中的汉字仍然乱码。

–于如
18年1月15日在3:37



@SiqingYu我放弃了疯狂的设置。只需使用blog.miniasp.com/post/2015/09/27/Useful-tool-Cmder.aspx

– code4j
18年1月16日在9:09



我以前使用过Cmder,但是它不能代替Visual Studio使用的开发人员控制台。

–于如
18年1月17日,0:41

@SiqingYu您的意思是C#交互式Powershell吗?

– code4j
18年1月18日在10:22

不是交互式Power Shell,而是Visual C ++也使用的开发人员控制台。它是Win32控制台应用程序项目中的默认调试控制台。

–于如
18年1月18日在11:46



#14 楼

我在这里看到了几个答案,但是它们似乎并没有解决这个问题-用户希望从命令行获取Unicode输入。您需要从程序中的操作系统获取这些信息。有两种方法可以做到这一点-

1)Microsoft有一个扩展,允许main使用宽字符数组:
int wmain(int argc,wchar_t * argv []);
https://msdn.microsoft.com/zh-cn/library/6wd819wh.aspx

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

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

评论


啊,不,对不起,您错过了这个问题。这是当我编写一个将接收unicode字符的程序时。我的问题是关于将unicode字符发送到另一个程序(希望该程序支持接收它们,但除反汇编外,我真的没有办法知道)。

– Vilx-
18年8月31日在15:24

#15 楼

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



复制con temp.txt [按Enter ]
键入路径/文件名[按Enter]
按Ctrl-Z [按Enter]

以这种方式创建.txt文件-temp.txt。在记事本中打开它,复制文本(不要担心它看起来不可读)并将其粘贴到您的.bat文件中。
执行在DOS窗口中以这种方式创建的.bat对mе有用(西里尔文,保加利亚文) 。

#16 楼

更好的清洁方法是:只需安装可用的免费Microsoft日语语言包。 (其他东方语言包也可以使用,但我已经测试了日语版本。)

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

#17 楼

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

我在BCP语句^§。中使用过CHCP 1252和一个大写字母。 >

评论


谢谢工作!我不知道为什么人们对此表示反对,对于某些人来说,它是一种有效的选择。.此代码页1252确实在Windows Server 2012上也解决了该问题,在Windows Server 2012上,相同的CP 65001代码对我不起作用。我想这取决于编辑批处理脚本的代码页或操作系统的默认设置。在这种情况下,它是使用记事本在具有en-US基本OS的德国MUI机器上创建的。

–托尼·沃尔
17年1月5日在13:15

#18 楼

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

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