我们在 Team Foundation Server (TFS) 中有一个项目,其中包含非英文字符 (š)。在尝试编写一些与构建相关的内容时,我们偶然发现了一个问题——我们无法将š字母传递给命令行工具。命令提示符或其他什么都搞砸了,tf.exe实用程序找不到指定的项目。
我尝试了 .bat 文件的不同格式(ANSI、UTF-8 有和没有BOM)以及用 JavaScript 编写脚本(本质上是 Unicode) - 但没有运气。如何执行程序并将其传递给Unicode命令行?
我们在 Team Foundation Server (TFS) 中有一个项目,其中包含非英文字符 (š)。在尝试编写一些与构建相关的内容时,我们偶然发现了一个问题——我们无法将š字母传递给命令行工具。命令提示符或其他什么都搞砸了,tf.exe实用程序找不到指定的项目。
我尝试了 .bat 文件的不同格式(ANSI、UTF-8 有和没有BOM)以及用 JavaScript 编写脚本(本质上是 Unicode) - 但没有运气。如何执行程序并将其传递给Unicode命令行?
尝试:
chcp 65001
这会将代码页更改为 UTF-8。此外,您需要使用 Lucida 控制台字体。
我的背景:多年来,我在控制台中使用 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
; 所有其他传达角色的方式都发生在;这么多应用程序还没有准备好看到一个字符。(仅适用于使用API 的应用程序。)Alt
KeyDown
KeyUp
Console-I/O
Ctrl-Alt-AltGr-Kana-Shift-Gray*
),那么它会在模拟按键上传递。这是任何应用程序所期望的——因此粘贴仅包含此类字符的任何内容都可以。结论:除非您的键盘布局支持在没有前缀键的情况下输入大量字符,通过控制台的 UI:时,一些有问题的应用程序可能会跳过字符。(这就是为什么我建议使用我的键盘布局!)Paste
Alt-Space E P
还应该记住,Windows 的“替代的、‘功能更强大’的控制台”根本不是控制台。它们不支持Console-I/O
API,因此依赖这些 API 工作的程序将无法运行。(不过,仅使用“控制台文件句柄的 File-I/O API”的程序可以正常工作。)
此类非控制台的一个示例是 Microsoft 的Powershell
. 我不用这个; 进行实验,按下并释放WinKey
,然后键入powershell
。
(另一方面,有诸如ConEmu
or之类的程序ANSICON
试图做更多的事情:它们“试图”拦截Console-I/O
API 以使“真正的控制台应用程序”也可以工作。这绝对适用于玩具示例程序;在现实生活中,这可能或可能无法解决您的特定问题。实验。)
设置字体、键盘布局(并且可选地,允许 HEX 输入)。
仅使用通过Console-I/O
API 并接受 Unicode 命令行参数的程序。例如,任何cygwin
-compiled 程序都应该没问题。正如我已经说过的,CMD
也很好。
UPD:最初,对于 中的一个错误cp65001
,我混合了内核和 CRTL 层(UPD²:和 Windows 用户模式 API!)。 另外: Win8修复了这个bug的一半;我澄清了关于“更好的控制台”应用程序的部分,并添加了对 Python 是如何做到这一点的参考。
我有同样的问题(我来自捷克共和国)。我有一个英文版的 Windows,我必须处理共享驱动器上的文件。文件的路径包括捷克语特有的字符。
对我有用的解决方案是:
在批处理文件中,更改字符集页面
我的批处理文件:
chcp 1250
copy "O:\VEŘEJNÉ\ŽŽŽŽŽŽ\Ž.xls" c:\temp
批处理文件必须保存在 CP 1250 中。
请注意,控制台不会正确显示字符,但它会理解它们......
检查非 Unicode 程序的语言。如果您在 Windows 控制台中遇到俄语问题,则应在此处设置俄语:
更改 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
而不是抑制输出“活动代码页:65001”。chcp 65001
请注意,这些设置仅适用于当前用户。如果您想为所有用户设置它,请将 line 替换SET ROOT_KEY="HKEY_CURRENT_USER"
为SET ROOT_KEY="HKEY_LOCAL_MACHINE"
实际上,诀窍在于命令提示符实际上可以理解这些非英文字符,只是无法正确显示它们。
当我在命令提示符中输入包含一些非英语字符的路径时,它显示为“?? ?????? ?????”。当您提交命令时(在我的情况下 cd "??? ?????? ?????"),一切都按预期工作。
在 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
一个非常简单的选择是安装 Windows bash shell,例如MinGW并使用它:
有一点学习曲线,因为您需要使用 Unix 命令行功能,但您会喜欢它的强大功能,并且可以将控制台字符集设置为 UTF-8。
当然,您还可以获得所有常见的 *nix 好东西,例如 grep、find、less 等。
由于我还没有看到 Python 2.7 的任何完整答案,我将概述两个重要步骤和一个非常有用的可选步骤。
Defaults
选项来选择。这也可以访问颜色。请注意,您还可以通过选择Properties
来更改以某些方式(例如,在此处打开、Visual Studio)调用的命令窗口的设置。cp65001
,这似乎是 Microsoft 为命令提示符提供 UTF-7 和 UTF-8 支持的尝试。chcp 65001
通过在命令提示符下运行来做到这一点。一旦设置,它就会保持这种状态,直到窗口关闭。每次启动 cmd.exe 时都需要重新执行此操作。有关更永久的解决方案,请参阅超级用户上的此答案。简而言之,REG_SZ
使用 regedit at 创建一个(字符串)条目HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor
并将其命名AutoRun
。将其值更改为chcp 65001
。如果您不想看到命令的输出消息,请@chcp 65001>nul
改用。
一些程序在与这种编码交互时遇到了麻烦,MinGW 是一个值得注意的程序,它在编译时会出现无意义的错误消息。尽管如此,这非常有效,并且不会导致大多数程序出现错误。
从 2019 年 6 月开始,使用 Windows 10,您无需更改代码页。
请参阅“介绍 Windows 终端”(来自Kayla Cinnamon)和Microsoft/Terminal。
通过使用 Consolas 字体,将提供部分Unicode 支持。
目前 Unicode 中有 87,887 个表意文字。你也需要它们吗?
我们需要一个边界,超出该边界的字符应该由字体回退/字体链接/其他处理。Consolas 应涵盖的内容:
- 现代 OSS 程序在 CLI 中用作符号的字符。
- 这些角色应遵循 Consolas 的设计和指标,并与现有的 Consolas 角色正确对齐。
Consolas 不应涵盖的内容:
- 拉丁文、希腊文和西里尔文以外的字符和标点符号,尤其是需要复杂造型的字符(如阿拉伯语)。
- 这些字符应使用字体回退处理。
这个问题很烦人。我的文件名和文件内容中通常有中文字符。请注意,我使用的是 Windows 10,这是我的解决方案:
显示文件名,例如dir
或者ls
如果您在 Windows 10 上安装了 Ubuntu bash
设置区域以支持非 utf 8 字符。
之后,控制台的字体将更改为该语言环境的字体,并且还更改了控制台的编码。
完成前面的步骤后,为了使用命令行工具显示 UTF-8 文件的文件内容
chcp 65001
type
命令查看文件内容,或者cat
如果您在 Windows 10 上安装了 Ubuntu bash最懒惰的解决方案:只需使用控制台模拟器,例如http://cmder.net/
对于类似的问题,(我的问题是在命令提示符下显示来自 MySQL 的 UTF-8 字符),
我是这样解决的:
我将命令提示符的字体更改为 Lucida Console。(此步骤必须与您的情况无关。它仅与您在屏幕上看到的内容有关,与真正的角色无关)。
我将代码页更改为 Windows-1253。您可以通过“chcp 1253”在命令提示符下执行此操作。它适用于我想查看 UTF-8 的情况。
我在这里看到了几个答案,但它们似乎没有解决这个问题 - 用户希望从命令行获取 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://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvw
请阅读: http ://utf8everywhere.org 了解详细信息,尤其是在您支持其他操作系统的情况下。
更清洁的做法:只需安装可用的免费 Microsoft 日语语言包。(其他东方语言包也可以,但我测试过日语包。)
这为您提供了具有更大字形集的字体,使它们成为默认行为,更改各种 Windows 工具,如 cmd、写字板等。
将代码页更改为 1252 对我有用。对我来说,问题是符号 double doller § 正在 Windows Server 2008 上由 DOS 转换为另一个符号。
我在 BCP 声明中使用了 CHCP 1252 和前面的上限 ^§。
如果您的计算机在 DOS 窗口中键入时显示路径/文件名正确,则可以快速决定 .bat 文件:
这样您就可以创建一个 .txt 文件 - temp.txt。在记事本中打开它,复制文本(不要担心它看起来不可读)并将其粘贴到您的 .bat 文件中。在 DOS 窗口中执行以这种方式创建的 .bat 对我有用(西里尔文,保加利亚文)。
我通过在批处理文件中通过它们的短(8 点 3)名称引用它们来解决删除 Unicode 命名文件的类似问题。
可以通过做查看短名称dir /x
。显然,这只适用于已知的 Unicode 文件名。