我们在Team Foundation Server(TFS)中有一个项目,其中包含非英语字符(š)。当尝试编写一些与构建相关的东西的脚本时,我们偶然发现了一个问题-我们无法将š字母传递给命令行工具。命令提示符或其他原因将其弄乱了,并且tf.exe实用程序找不到指定的项目。
我已经尝试过.bat文件的不同格式(ANSI,带有和不带有BOM的 UTF-8 )以及使用JavaScript编写脚本(固有地是Unicode)的脚本-但没有运气。如何执行程序并将其传递给Unicode命令行?
我们在Team Foundation Server(TFS)中有一个项目,其中包含非英语字符(š)。当尝试编写一些与构建相关的东西的脚本时,我们偶然发现了一个问题-我们无法将š字母传递给命令行工具。命令提示符或其他原因将其弄乱了,并且tf.exe实用程序找不到指定的项目。
我已经尝试过.bat文件的不同格式(ANSI,带有和不带有BOM的 UTF-8 )以及使用JavaScript编写脚本(固有地是Unicode)的脚本-但没有运气。如何执行程序并将其传递给Unicode命令行?
Answers:
我的背景:多年来,我在控制台中使用Unicode输入/输出(并且每天都要做很多工作。此外,我还为此任务开发了支持工具)。就您所了解的以下事实/限制而言,几乎没有问题:
CMD
与“控制台”无关。 CMD.exe
是准备在控制台中“工作”的程序之一(“控制台应用程序”)。CMD
具有对Unicode的完美支持;您可以在任何代码页处于活动状态时输入/输出所有Unicode字符。 chcp 65001
是非常危险的 除非专门设计一个程序来解决Windows API中的缺陷(或使用具有这些解决方法的C运行时库),否则该程序将无法可靠地工作。 Win8可以解决其中½个问题cp65001
,但其余问题仍然适用于Win10。cp1252
。正如我已经说过的:要在控制台中输入/输出Unicode,不需要设置codepage。File-I/O
API,而不是Console-I/O
API。(例如,请参见Python如何做到的。)U+10000
)。仅支持简单的文本呈现(因此,只要使用预设的形式,欧洲语言(和某些东亚语言)应该可以正常工作)。[ 这里对东亚和U + 0000,U + 0001,U + 30FB字符有较小的罚款。]Window 的默认设置不是很有帮助。为了获得最佳体验,应该调整3种配置:
带有“粘贴”到控制台应用程序中的另一个陷阱(非常技术):
KeyUp
的Alt
; 所有其他传递角色的方式都在发生KeyDown
; 如此之多的应用程序还没有准备好在上看到一个字符KeyUp
。(仅适用于使用Console-I/O
API的应用程序。)Ctrl-Alt-AltGr-Kana-Shift-Gray*
),则可以在模拟的按键上进行输入。这是任何应用程序所期望的-因此,粘贴仅包含此类字符的任何内容都可以。结论:除非您的键盘布局支持输入许多不带前缀键的字符,否则某些错误的应用程序可能会在您Paste
通过控制台的UI时跳过字符:Alt-Space E P
。(这就是为什么我建议使用键盘布局的原因!)
还应该记住,Windows的“替代的'功能更强大的'控制台” 根本不是控制台。它们不支持Console-I/O
API,因此依赖这些API起作用的程序将无法运行。(不过,仅使用“控制台文件句柄的File-I / O API”的程序可以正常工作。)
这种非控制台的一个示例是MicroSoft的一部分Powershell
。我不用这个; 实验,按一下并释放WinKey
,然后输入powershell
。
(在另一方面,也有诸如程序ConEmu
或ANSICON
尝试做更多的事情:它们“尝试”拦截Console-I/O
API以使“真正的控制台应用程序”也能工作。这肯定适用于玩具示例程序;在现实生活中,这可能或可能无法解决您的特定问题。进行实验。)
设置字体,键盘布局(以及可选的允许十六进制输入)。
仅使用通过Console-I/O
API并接受Unicode命令行参数的程序。例如,任何cygwin
编译程序都可以。正如我已经说过的,CMD
也可以。
UPD:最初,由于中的bug cp65001
,我混合使用了内核和CRTL层(UPD²:和Windows用户模式API!)。 另外: Win8修复了此错误的一半;我澄清了有关“更好的控制台”应用程序的部分,并添加了有关Python如何实现的参考。
.log
文件来看,这是zip -ru
[?!]中的间歇性错误。不知道如何调试它–或将来避免使用…)
尝试:
chcp 65001
它将代码页更改为UTF-8。另外,您需要使用Lucida控制台字体。
我遇到了同样的问题(我来自捷克共和国)。我安装了英文版Windows,并且必须使用共享驱动器上的文件。文件的路径包括捷克专用字符。
适用于我的解决方案是:
在批处理文件中,更改字符集页面
我的批处理文件:
chcp 1250
copy "O:\VEŘEJNÉ\ŽŽŽŽŽŽ\Ž.xls" c:\temp
批处理文件必须保存在CP 1250中。
请注意,控制台不会正确显示字符,但会理解它们。
á
,é
,í
,ó
,和ú
。
检查非Unicode程序的语言。如果您在Windows控制台中遇到俄语问题,则应在此处设置俄语:
cmd
,只会将默认代码页cp866
(仍为8位字符集)切换到该代码页。它甚至使用cp866
而不是cp1251
添加自己的麻烦。
更改Windows控制台的默认“代码页”是非常困难的。当您在网络上搜索时,会发现不同的建议,但是其中一些建议可能会完全破坏Windows,即PC无法再启动。
最安全的解决方案是:转到您的注册表项HKEY_CURRENT_USER\Software\Microsoft\Command Processor
并添加String value 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"
实际上,诀窍在于命令提示符实际上可以理解这些非英语字符,只是无法正确显示它们。
当我在命令提示符下输入包含一些非英语字符的路径时,它显示为“ ???????????????????”。当您提交命令时(在我的案例中为cd“ ??????????????????”),一切按预期进行。
.cmd
批处理文件时,我仍然需要放在chcp 65001
批处理文件的顶部。
在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”:
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
由于我还没有看到Python 2.7的完整答案,因此我将概述两个重要步骤和一个非常有用的可选步骤。
Defaults
选项来选择它。这也可以访问颜色。请注意,您也可以通过选择更改以某些方式(例如,在此处打开,Visual Studio)调用的命令窗口的设置Properties
。cp65001
,这似乎是Microsoft尝试向命令提示符提供UTF-7和UTF-8支持。通过chcp 65001
在命令提示符下运行来执行此操作。一旦设置,它将保持这种方式,直到关闭窗口。每次启动cmd.exe时都需要重做一次。有关更永久的解决方案,请参阅超级用户上的此答案。简而言之,REG_SZ
使用regedit 创建一个(String)条目,HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor
并将其命名为AutoRun
。将其值更改为chcp 65001
。如果您不想看到命令的输出消息,请使用@chcp 65001>nul
改用。
某些程序无法与该编码进行交互,MinGW是一个值得注意的程序,在编译时会出现无意义的错误消息而失败。但是,这非常有效,并且不会引起大多数程序的错误。
一个非常简单的选择是安装Windows bash shell(例如MinGW)并使用:
您需要使用Unix命令行功能,因此需要进行一些学习,但是您会喜欢它的强大功能,可以将控制台字符集设置为UTF-8。
当然,您还可以获得所有常用的* nix好东西,例如grep,find,less等。
对于类似的问题,(我的问题是在命令提示符下显示来自MySQL的UTF-8字符),
我这样解决了:
我将命令提示符的字体更改为Lucida Console。(此步骤必须与您的情况无关。它仅与您在屏幕上看到的内容有关,而与角色的真实情况无关)。
我将代码页更改为Windows-1253。您可以通过“ chcp 1253”在命令提示符下执行此操作。它适用于我想看UTF-8的情况。
这个问题很烦人。我的文件名和文件内容通常带有中文字符。请注意,我正在使用Windows 10,这是我的解决方案:
要显示文件名,例如dir
或ls
是否在Windows 10上安装了Ubuntu bash
设置区域以支持非UTF 8字符。
此后,控制台的字体将更改为该语言环境的字体,并且还更改了控制台的编码。
完成前面的步骤后,为了使用命令行工具显示UTF-8文件的文件内容
chcp 65001
type
命令来查看文件内容,或者cat
如果您在Windows 10上安装了Ubuntu bash最懒惰的解决方案:只需使用控制台仿真器,例如http://cmder.net/
point
命令输出中的汉字仍然乱码。
我在这里看到了几个答案,但它们似乎并未解决问题-用户希望从命令行获取Unicode输入。
Windows使用UTF-16编码两个字节的字符串,因此您需要从操作系统中的程序中获取它们。有两种方法可以做到这一点 -
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 以获取详细信息,尤其是在您支持其他操作系统的情况下。
从2019年6月开始,使用Windows 10,您将无需更改代码页。
请参见“ Windows终端简介 ”(来自Kayla Cinnamon)和Microsoft / Terminal。
通过使用Consolas字体,将提供部分 Unicode支持。
当前有87,887个表意文字使用Unicode。您还需要所有这些吗?
我们需要一个边界,超出该边界的字符应通过字体后备/字体链接/其他方式处理。Consolas应该涵盖的内容:
- 用作CLI中现代OSS程序使用的符号的字符。
- 这些字符应遵循Consolas的设计和指标,并与现有Consolas字符正确对齐。
Consolas不应涵盖的内容:
- 超出拉丁语,希腊语和西里尔字母的脚本的字符和标点符号,尤其是需要复杂形状的字符(如阿拉伯语)。
- 这些字符应使用字体后备进行处理。
一个更好的清洁方法:只需安装可用的免费Microsoft日语语言包。(其他东方语言包也可以,但是我已经测试了日语。)
这为您提供了带有较大字形集的字体,使其成为默认行为,并更改了各种Windows工具(如cmd,写字板等)。
将代码页更改为1252对我有用。对我来说,问题是符号double doller§正在Windows Server 2008上由DOS转换为另一个符号。
我在BCP语句^§中使用过CHCP 1252和瓶盖。