【问题标题】:Handling extended characters in Windows commands?处理 Windows 命令中的扩展字符?
【发布时间】:2009-04-09 19:34:22
【问题描述】:

我正在调试一个 Windows 批处理命令文件。在路径或文件名中使用扩展 (> 0x7f) 字符时失败。该问题似乎与将参数传递给从另一个调用的命令文件有关。

例如,此命令按预期工作:

xcopy "Pezuñero\1 - 001.wav" \temp

这不是:

call another.cmd "Pezuñero" 

“另一个.cmd”的内容:

xcopy "%~1\1 - 001.wav"    \temp

%~1 语法扩展参数并删除引号。这是必要的,因为在真正的命令文件中,调用或被调用的命令文件中的路径可能有空格。

第二个例子的结果(从 CMD 窗口复制)是这样的:

C:\>call another.cmd "Pezu±ero"    

C:\>xcopy "Pezu±ero\1 - 001.wav"    \temp
File not found - 1 - 001.wav
0 File(s) copied

请注意,“ñ”(0xF1)字符已更改为“±”(0xB1)。

谁能解释发生了什么,以及如何解决这个问题?

【问题讨论】:

    标签: windows delphi batch-file


    【解决方案1】:

    脚本必须以 cmd.exe 使用的相同编码编写。

    在提示符下输入 chcp 看看你得到了什么。然后使用支持该编码的编辑器打开文件。对我来说chcp 输出代码页850,所以我在JEdit 中编辑我的脚本,选择IBM850 作为文件编码。我在PSPad 中编辑文件时得到相同的结果,Format 设置为 OEM

    P.S.:我在我的机器上测试了你的步骤,我在 notepad.exe 中写的 ñ 字符(使用默认的 ANSI 编码)也被转换为 ± 从命令提示符读取时,因此看起来您的机器使用类似的 ANSI 和 OEM 编码。请务必尝试将 ñ 替换为 ¤(使用 notepad.exe)。这使得脚本在从命令提示符运行时对我来说可以正常工作(因为 ANSI 的 ¤ 的字节值与 OEM 的 ñ 相同)。

    【讨论】:

      【解决方案2】:

      感谢 McDowell 和 Romulo 为我指明了正确的方向。我意识到我需要更改生成批处理的应用程序(在 Delphi 中),以便它使用与 Windows 中的命令处理器兼容的正确 (OEM) 代码页。我没有找到任何可以转换代码页字符串的东西,但我确实发现了 Windows API 函数 SetFileApisToOEM 和 SetFileApisToANSI;

      我把这些放在程序的开头和结尾,如下所示:

      {main procedure}
      begin
        SetFileApisToOEM;
        {all the rest of the program}
        SetFileApisToANSI;
      end.
      

      现在批处理文件是使用 OEM 代码页生成的,并且当从 CMD 提示符运行时它们可以正常工作。

      【讨论】:

      【解决方案3】:

      我一直是looking at character handling in cmd.exe,我认为Romulo 已经一针见血了。默认情况下,提示使用旧的 DOS (OEM) 代码页(可能是为了与 DOS 程序兼容)。您正在使用(可能)默认的 Windows 代码页(可能是 1252)编写文件,这是不同的。使用 edit.com 编辑批处理文件。

      如果我在提示符下键入 chcp,它会报告代码页 850。

      因此,例如,如果我使用 记事本 输入以下内容:

      DIR Pezuñero
      

      ...这是用二进制值编码为1252

                              ñ
      44 49 52 20 50 65 7A 75 F1 65 72 6F
      

      如果我使用edit 写入文件,它会被编码为850 并带有二进制值:

                              ñ
      44 49 52 20 50 65 7A 75 A4 65 72 6F
      

      我没有看过的一件事是使用 cmd /U 开关,但我很确定这仅适用于内置的 shell 命令,不会帮助您使用 XCOPY。

      【讨论】:

      • 实际上,批处理文件是由应用程序生成的。所以问题变成了如何在 Win32 应用程序(在我的例子中为 Delphi 7)中执行代码页翻译?是否有一个 Windows API 可以将代码页 X 中的字符串转换为代码页 Y?
      【解决方案4】:

      代码页是批处理文件中的一个问题,因为它们不允许包含 Unicode。完全避免此问题的最简单方法可能是使用 WSH 或 Powershell。到目前为止,我还没有找到批处理文件的解决方法,这真的让我很困扰,因为我认为自己是 Unicode 狂热者:)

      【讨论】:

        【解决方案5】:

        您可能需要将代码页设置为顶部带有 ~ 的 n。

        【讨论】:

        • 感谢您提供指向代码页的指针。我对它们不是很熟悉——我了解到 Windows 通常使用代码页 1252,但命令窗口和批处理文件使用代码页 437。我在批处理文件的开头插入了命令“CHCP 1252”。不幸的是,它没有解决问题。
        猜你喜欢
        • 2015-06-23
        • 2022-01-10
        • 1970-01-01
        • 2021-05-23
        • 1970-01-01
        • 1970-01-01
        • 2016-03-21
        • 2012-05-24
        • 1970-01-01
        相关资源
        最近更新 更多