我们在Team Foundation Server (TFS)中有一个项目,其中有一个非英语字符(š)。当尝试编写一些与构建相关的脚本时,我们偶然发现了一个问题——我们不能将这个字母传递给命令行工具。命令提示符或其他东西会把它弄乱,tf.exe实用程序无法找到指定的项目。
我尝试了不同格式的.bat文件(ANSI, UTF-8,带BOM和不带BOM),以及用JavaScript编写脚本(本质上是Unicode) -但运气不好。如何执行程序并传递一个Unicode命令行?
我们在Team Foundation Server (TFS)中有一个项目,其中有一个非英语字符(š)。当尝试编写一些与构建相关的脚本时,我们偶然发现了一个问题——我们不能将这个字母传递给命令行工具。命令提示符或其他东西会把它弄乱,tf.exe实用程序无法找到指定的项目。
我尝试了不同格式的.bat文件(ANSI, UTF-8,带BOM和不带BOM),以及用JavaScript编写脚本(本质上是Unicode) -但运气不好。如何执行程序并传递一个Unicode命令行?
当前回答
我在这里看到了几个答案,但它们似乎没有解决这个问题——用户希望从命令行获得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 bash shell,如MinGW并使用它:
有一点学习曲线,因为你将需要使用Unix命令行功能,但你会喜欢它的力量,你可以将控制台字符集设置为UTF-8。
当然,您还可以得到所有常见的*nix好东西,如grep、find、less等。
从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.
Try:
chcp 65001
这会将代码页更改为UTF-8。此外,还需要使用Lucida控制台字体。
更改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"
把代码页改成1252对我有用。我遇到的问题是,Windows Server 2008上的DOS正在将符号double doller§转换为另一个符号。
在我的BCP声明^§中,我使用了CHCP 1252和它之前的一个帽。