我们在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输入/输出已经很多年了(并且每天都这么做。此外,我还为这项任务开发了支持工具)。只要你了解以下事实/限制,问题就很少:
CMD and “console” are unrelated factors. CMD.exe is a just one of programs which are ready to “work inside” a console (“console applications”). AFAIK, CMD has perfect support for Unicode; you can enter/output all Unicode chars when any codepage is active. Windows’ console has A LOT of support for Unicode — but it is not perfect (just “good enough”; see below). chcp 65001 is very dangerous. Unless a program was specially designed to work around defects in the Windows’ API (or uses a C runtime library which has these workarounds), it would not work reliably. Win8 fixes ½ of these problems with cp65001, but the rest is still applicable to Win10. I work in cp1252. As I already said: To input/output Unicode in a console, one does not need to set the codepage.
细节
To read/write Unicode to a console, an application (or its C runtime library) should be smart enough to use not File-I/O API, but Console-I/O API. (For an example, see how Python does it.) Likewise, to read Unicode command-line arguments, an application (or its C runtime library) should be smart enough to use the corresponding API. Console font rendering supports only Unicode characters in BMP (in other words: below U+10000). Only simple text rendering is supported (so European — and some East Asian — languages should work fine — as far as one uses precomposed forms). [There is a minor fine print here for East Asian and for characters U+0000, U+0001, U+30FB.]
实际考虑
The defaults on Window are not very helpful. For best experience, one should tune up 3 pieces of configuration: For output: a comprehensive console font. For best results, I recommend my builds. (The installation instructions are present there — and also listed in other answers on this page.) For input: a capable keyboard layout. For best results, I recommend my layouts. For input: allow HEX input of Unicode. One more gotcha with “Pasting” into a console application (very technical): HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.) Conclusion: many application would not react on HEX input events. Moreover, what happens with a “Pasted” character depends on the current keyboard layout: if the character can be typed without using prefix keys (but with arbitrary complicated combination of modifiers, as in Ctrl-Alt-AltGr-Kana-Shift-Gray*) then it is delivered on an emulated keypress. This is what any application expects — so pasting anything which contains only such characters is fine. However, the “other” characters are delivered by emulating HEX input. Conclusion: unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI: Alt-Space E P. (This is why I recommend using my keyboard layouts!)
我们还应该记住,Windows上的“替代的、更强大的”主机根本不是主机。它们不支持Console-I/O api,因此依赖这些api工作的程序将无法正常工作。(不过,只使用“文件- i /O api到控制台文件句柄”的程序可以很好地工作。)
微软的Powershell就是一个非主机的例子。我不用它;要进行实验,按下并释放WinKey,然后输入powershell。
(另一方面,有一些程序,如ConEmu或ANSICON,试图做更多的事情:他们“试图”拦截控制台i /O api,以使“真正的控制台应用程序”也能工作。这绝对适用于玩具示例程序;在现实生活中,这可能解决不了您的特定问题。实验。)
总结
设置字体,键盘布局(并可选地,允许十六进制输入)。 只使用通过Console-I/O api的程序,并接受Unicode命令行参数。例如,任何由cygwin编译的程序都可以。正如我已经说过的,CMD也很好。
UPD:最初,对于cp65001中的一个错误,我混淆了内核层和CRTL层(UPD²:和Windows用户模式API!)另外:Win8修复了这个错误的一半;我澄清了关于“更好的控制台”应用程序的部分,并添加了Python如何做到这一点的参考。
其他回答
我通过在批处理文件中使用它们的短名称(8点3)来删除以unicode命名的文件,从而避免了类似的问题。
短名称可以通过执行dir /x查看。显然,这只适用于已知的Unicode文件名。
一个快速决定。bat文件,如果你的电脑显示你的路径/文件名正确时,你在dos窗口输入:
copy con temp.txt[按Enter] 输入路径/文件名[按Enter] 按Ctrl-Z[按Enter]
这样你就创建了一个。txt文件- temp.txt。在记事本中打开它,复制文本(不要担心它看起来不可读),并粘贴到你的。bat文件中。 在DOS-window中执行以这种方式创建的.bat对mе(西里尔语,保加利亚语)有效。
一个更好更干净的方法是:安装可用的免费微软日语包。(其他东方语言包也可以,但我已经测试了日语包。)
这将为您提供具有较大字形集的字体,使它们成为默认行为,更改各种Windows工具,如cmd, WordPad等。
这个问题很烦人。我通常在文件名和文件内容中使用中文字符。请注意,我使用的是Windows 10,下面是我的解决方案:
如果在Windows 10上安装了Ubuntu bash,则显示文件名为dir或ls
设置该区域支持非utf8字符。 在此之后,控制台的字体将被更改为该地区的字体,它还将更改控制台的编码。
在完成以上步骤后,为了使用命令行工具显示UTF-8文件的文件内容
通过chcp 65001将页面更改为utf-8 更改为支持utf-8的字体,例如Lucida Console 使用type命令查看文件内容,如果你在Windows 10上安装了Ubuntu bash,可以使用cat命令查看 请注意,在将控制台的编码设置为utf-8后,我无法在cmd中使用中文输入法输入汉字。
最懒的解决方案:只使用控制台模拟器,如http://cmder.net/
我的背景:我在控制台中使用Unicode输入/输出已经很多年了(并且每天都这么做。此外,我还为这项任务开发了支持工具)。只要你了解以下事实/限制,问题就很少:
CMD and “console” are unrelated factors. CMD.exe is a just one of programs which are ready to “work inside” a console (“console applications”). AFAIK, CMD has perfect support for Unicode; you can enter/output all Unicode chars when any codepage is active. Windows’ console has A LOT of support for Unicode — but it is not perfect (just “good enough”; see below). chcp 65001 is very dangerous. Unless a program was specially designed to work around defects in the Windows’ API (or uses a C runtime library which has these workarounds), it would not work reliably. Win8 fixes ½ of these problems with cp65001, but the rest is still applicable to Win10. I work in cp1252. As I already said: To input/output Unicode in a console, one does not need to set the codepage.
细节
To read/write Unicode to a console, an application (or its C runtime library) should be smart enough to use not File-I/O API, but Console-I/O API. (For an example, see how Python does it.) Likewise, to read Unicode command-line arguments, an application (or its C runtime library) should be smart enough to use the corresponding API. Console font rendering supports only Unicode characters in BMP (in other words: below U+10000). Only simple text rendering is supported (so European — and some East Asian — languages should work fine — as far as one uses precomposed forms). [There is a minor fine print here for East Asian and for characters U+0000, U+0001, U+30FB.]
实际考虑
The defaults on Window are not very helpful. For best experience, one should tune up 3 pieces of configuration: For output: a comprehensive console font. For best results, I recommend my builds. (The installation instructions are present there — and also listed in other answers on this page.) For input: a capable keyboard layout. For best results, I recommend my layouts. For input: allow HEX input of Unicode. One more gotcha with “Pasting” into a console application (very technical): HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.) Conclusion: many application would not react on HEX input events. Moreover, what happens with a “Pasted” character depends on the current keyboard layout: if the character can be typed without using prefix keys (but with arbitrary complicated combination of modifiers, as in Ctrl-Alt-AltGr-Kana-Shift-Gray*) then it is delivered on an emulated keypress. This is what any application expects — so pasting anything which contains only such characters is fine. However, the “other” characters are delivered by emulating HEX input. Conclusion: unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI: Alt-Space E P. (This is why I recommend using my keyboard layouts!)
我们还应该记住,Windows上的“替代的、更强大的”主机根本不是主机。它们不支持Console-I/O api,因此依赖这些api工作的程序将无法正常工作。(不过,只使用“文件- i /O api到控制台文件句柄”的程序可以很好地工作。)
微软的Powershell就是一个非主机的例子。我不用它;要进行实验,按下并释放WinKey,然后输入powershell。
(另一方面,有一些程序,如ConEmu或ANSICON,试图做更多的事情:他们“试图”拦截控制台i /O api,以使“真正的控制台应用程序”也能工作。这绝对适用于玩具示例程序;在现实生活中,这可能解决不了您的特定问题。实验。)
总结
设置字体,键盘布局(并可选地,允许十六进制输入)。 只使用通过Console-I/O api的程序,并接受Unicode命令行参数。例如,任何由cygwin编译的程序都可以。正如我已经说过的,CMD也很好。
UPD:最初,对于cp65001中的一个错误,我混淆了内核层和CRTL层(UPD²:和Windows用户模式API!)另外:Win8修复了这个错误的一半;我澄清了关于“更好的控制台”应用程序的部分,并添加了Python如何做到这一点的参考。