【发布时间】:2021-01-13 14:23:06
【问题描述】:
有没有办法通过安装脚本/Windows 批处理/PowerShell 在传递文件进行转换之前检查文件是否为 UTF-8?
作为背景,我目前正在使用 C++ 中的 Visual Studio 2005(升级到 Visual Studio 2017)开发旧版(日语)Windows 软件。
我正在处理使 GUI 能够显示和输入汉字的要求。因此决定使用 UNICODE 进行项目/解决方案编码。
由于该项目最初使用多字节,为了向后兼容 UNICODE,我决定将配置文件(ini、dat、保存文件)编码为 UTF-8,因为这些文件也被 Web 应用程序引用。
软件的主要部分现在已经完成并且可以工作了,我还有最后一个问题 - 推出版本升级安装程序。
在此安装程序中(使用安装脚本),我需要将保存文件(以前以 SHIFT-JIS 编码,因为这些保存文件包含日语文本)更新为 UTF-8。
我已经在以下几行中创建了一个批处理文件,它将 SHIFT-JIS 转换为 UTF-8,该文件在安装程序的最后部分调用并在转换后被删除。
@echo off
:: Shift_JIS -> UTF-8
setlocal enabledelayedexpansion
for %%f in ("%~dp0\savedfiles\*.sav") do (
echo %%~ff| findstr /l /e /i ".sav"
if !ERRORLEVEL! equ 0 (
powershell -nop -c "&{[IO.File]::WriteAllText($args[1], [IO.File]::ReadAllText($args[0], [Text.Encoding]::GetEncoding(932)))}" \"%%~ff" \"%%~ff"
)
)
但是,这样做的问题是,当用户 (1) 升级、(2) 卸载(.sav 文件被故意留下)和 (3) 重新安装软件时,保存文件会被双重重新编码并导致软件崩溃。 ((1)升级时更新UTF-8日文字符,(3)重新安装后变为垃圾字符。)
【问题讨论】:
-
字节集合并没有什么特别之处,它应该表示表示它使用何种编码的文本。您必须以其他方式跟踪这一点。
-
对于答案,我建议查看A: How to detect UTF-8 in plain C?,特别是建议在文件开头添加标识符的部分。在您的情况下,您需要选择通常不会开始您的 .sav 文件的内容。如果你提前考虑,你可以选择一个字节序列,上面写着“这个文件有一个标题”,然后是一个字节或字节序列,上面写着“我是 UTF-8”——因为未来的变化可能需要更多的标识符。 (这应该是重复的吗?知道替代方案是日语可能会引发其他答案。)
-
谢谢@JaMiT,我已经更新了这个问题。实际上,我最初创建了一个类似的简单 .exe 文件来检查 UTF-8 BOM,并返回简单的真或假,但不幸的是,BOM 会导致 Web 应用程序部分出现显示问题。我认为这篇文章是原因:w3.org/International/questions/qa-utf8-bom.en.html。我将在线程中探索其他解决方案,这很有帮助。
-
@Wolf 是的,您还必须更新读取数据的应用程序代码以说明标头。
-
一些离题提示:
%~dp0扩展为始终以反斜杠结尾的文件夹路径。出于这个原因,永远不要将%~dp0与带有文件/文件夹名称或通配符模式的附加\连接起来,因为这会导致完整的参数字符串中有两个反斜杠,Windows 稍后必须更正。尽管可能,但不要将f用作循环变量,尤其是在同时使用~f之类的修饰符时。有足够多的其他字符不是可用作循环变量的修饰符。使用if not errorlevel 1代替if !ERRORLEVEL! equ 0时不需要延迟扩展。
标签: c++ windows batch-file unicode installscript