psy*_*low 6 windows batch command-line localization
将控制台应用程序的输出(我在消息的其余部分中使用术语命令)正确重定向到具有 1252 编码的文件中(以使其可以在默认配置下从任何记事本软件中读取)。
\n\nChcp 对内部命令和一些外部命令(最近的)有效
\n\n首先值得注意的是,CHCP 在 Win7 和 Win 10 下的运行方式有所不同。
\n\n如果从 cmd 提示符运行以下批处理,您会注意到命令输出在 win10 控制台中正确显示,而 win7 控制台则严重渲染 ASCII 字符。
\n\nfor /f "tokens=2 delims=:" %%G in (\'chcp\') do Set _cp_=%%G\nchcp 1252\n@echo test an internal command\ndir\n@echo test an external (recent) command: Robocopy\nrobocopy .\\ .\\ /L\n@echo test an external (legacy) command: Xcopy\nxcopy test.txt 2>&1\nchcp %_cp_%\necho end of test.cmd batch \n
Run Code Online (Sandbox Code Playgroud)\n\n顺便说一句,我有兴趣知道是什么导致了这种差异,尽管它\xe2\x80\x99s并不是该消息的真正目的,并且因为它\xe2\x80\x99s可以通过添加 ps 调用 \xe2\x80\x9cpowershell 轻松修复[ console]::outputencoding=[system.text.encoding]::getencoding(850)\xe2\x80\x9d 在第一个 chcp 命令之后的批处理中。
\n\n当批处理输出重定向到文件:test.cmd > test.txt 时,无论发生什么真正的问题。
\n\n在这种情况下,无论操作系统如何,结果都是相同的。内部命令和新外部命令(Robocopy、Bcdedit 等)的输出均经过正确的 1252 编码。旧命令(xcopy、chcp 等)不是(在 OEM 代码页中输出)。简而言之,大多数命令不受 CHCP 或通过 powershell 进行的等效[控制台]更改的影响。
\n\n旧版命令代码基于 CRT,而内部命令和最新的外部命令则使用 Win32 API。它\xe2\x80\x99s 基于MSDN 全球化逐步开发中关于控制台应用程序开发的最后一节!
由于至少 win10 控制台中显示的内容(所有命令输出的编码相同)和存储的文件不同(输出编码根据命令而变化),因此输出/输入流可能会根据它们指向的句柄类型进行不同的处理。控制台功能可用于重定向情况下的显示和 I/O 文件功能。基于高级控制台输入和输出函数的推测!
MS 建议控制台应用程序的代码强制对输出流进行 OEM 编码。参考号 控制台应用程序问题\n如果在外部命令的代码中应用 MS 建议,则可以解释为什么无论应用什么控制台代码页,将其输出流重定向到文件中始终都编码为 OEM_CP。奇怪的是,受SetFileApisToOEM影响的函数中没有提到 readfile 和 writefile
最后,我不知道旧命令和最近引入的命令之间的区别是否是因为它们的代码尊重 MS 建议,并且只是因为字符串文字是 OEM 与 ANSI 编码的。
\n\n如果3是正确的,那么肯定很少。:\n\n\xe2\x80\x99可以更改注册表项HKLM\system\currentset\control\NLS\codepage OEMCP=1252的值。\xe2\x80\x99 不安全(不要尝试设置 Unicode 65001,您的系统可能会拒绝启动)且不方便(需要重新启动)。\n或者,仅使用 OEM 编码内容填充文件,并使用 PS 脚本对文件进行转码批次结束。如果必须定期访问和检查文件,则简单但不太优雅。
\n\n如果2正确,则可能存在控制I/O文件函数readfile和writefile编码的函数。
\n\n如果1正确,则应该可以控制当前用户会话的国际设置或文化,从而控制 CRT 应用程序的代码页。从 Win8 开始,可以通过Powershell 在 Windows 中配置国际设置\xe2\x80\x99 。命令行应用程序也能够执行此类操作。\n无论如何,这里的困难在于创建 \xe2\x80\x9cculture\xe2\x80\x9d 并将 OEM 代码页设置为 1252,因为\xe2\x80\x99 不存在在预定义的集合中。
\n\n即使该问题没有有效的解决方案,也请毫不犹豫地分享您对该主题的知识。我只是想了解微软是如何实现这些东西的。
\n4 年后我意识到:-p 我从未发布过我在脚本中经常使用的解决方法来解决这个问题。它\xe2\x80\x99是一个短批处理,有问题的命令(即几乎所有外部批处理命令)通过管道输入。
\n:: Description : Transcode the OEM output stream of external commands to ANSI chars in order to get notepad readable files with redirections\n:: Usage: prog.exe | output1252\n:: 2>&1 prog.exe | output1252 > log.txt\n@echo off\nsetlocal\n:: CodePage of the command and console programs (OEM code page)\nset OEM_CP=850\nchcp %OEM_CP% >NUL\n:: The default local Windows codepage (ANSI code page), for Western Europe: 1252\nset ANSI_CP=1252\n\n>NUL chcp %ANSI_CP% & for /F delims^=^ eol^= %%A in ('more') do (\n call :WRITEOUT %%A)\necho:\ngoto :eof\n\n:WRITEOUT\n echo %*\ngoto :eof\n
Run Code Online (Sandbox Code Playgroud)\n:: Description : Transcode OEM 850 input data to ANSI-1252 output\n:: Usage: ThatBatch <850.txt >1252.txt\n:: prog.exe | ThatBatch\n:: 2>&1 prog.exe | ThatBatch > log.txt\n@echo off\n0<NUL chcp 850 >NUL\nclip\n0<NUL chcp 1252 >NUL\npowershell Get-Clipboard\n
Run Code Online (Sandbox Code Playgroud)\n这些示例将 OEM 850 转码为 ANSI-1252,但它们可以轻松调整以转码任何代码页(也可能是 Unicode)。请随意改进它们(实现输入/输出代码页作为参数)并满足您的需求..
\n 归档时间: |
|
查看次数: |
3730 次 |
最近记录: |