【问题标题】:Inno Setup: recording/recover file path in UTF8Inno Setup:以 UTF8 录制/恢复文件路径
【发布时间】:2019-09-28 00:10:30
【问题描述】:

我们正在使用 Inno Setup(unicode 版本)为我们的产品创建资源包(或“示例”)。我们产品的程序部分通过示例安装程序编写的文件知道示例的位置。目前,它以简单的方式实现:

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if ( CurStep = ssPostInstall) then
  begin
    ForceDirectories(ExpandConstant('{userappdata}\MyCompany\MyApp'))
    SaveStringToFile(ExpandConstant('{userappdata}\MyCompany\MyApp\SamplePath.txt'), ExpandConstant('{app}'), False);
  end;
end;

这种简单的方式有一个致命的问题:安装程序是在中文 Windows 下运行的,整个东西都是 GBK 编码的,但我们的产品是建立在 UTF8 基础上的。

经过一番搜索,我通过在 Pascal 代码中调用 Windows WideCharToMultiByte 得到了一些解决方案。但是这行不通,因为它需要 UTF16 作为输入,但我拥有的是 GBK。

此外,Inno 安装程序也不适用于我的 SamplePath.txt 中现有的 UTF8 文件名。如果我手动编辑 SamplePath.txt 文件以填充 UTF8 编码的中文字母,并使用以下代码初始化 app 内置,它会在 dir 选择页面中显示杂乱的字符:

[Setup]
DefaultDirName={code:GetPreviousSampleDir}

[code]
function GetPreviousSampleDir(Param: String): String;
var
    tmp: AnsiString;
begin
    if FileExists( ExpandConstant('{userappdata}\MyCompany\MyApp\SamplePath.txt') ) then
    begin
        LoadStringFromFile(ExpandConstant('{userappdata}\MyCompany\MyApp\SamplePath.txt'), tmp)
        Result := tmp
    end
    else
    begin
        Result := 'D:\MyApp_samples'
    end;
end;

那么有什么方法可以在 UTF8 中加载/存储带有 i18n 个字符的文件名吗?

【问题讨论】:

  • 您使用的是 Unicode 还是 Ansi Inno 设置?
  • @MartinPrikryl:是的 Unicode 版本,我将把这些信息附加到问题中。
  • 好的,那么请解释一下“所有东西都使用GBK 编码”是什么意思 -- 你从哪里获得GBK 编码? + 你试过SaveStringsToUTF8File吗?
  • @MartinPrikryl SaveStringsToUTF8File 将使用不需要的 BOM 进行写入。加载回部分仍然有问题。
  • @MartinPrikryl 如果你不使用UTF8调用,它会产生带有GBK的内容,它可以加载回GBK编码的文件名并正确显示在目录选择页面中。似乎 Inno Setup 的内部部分使用传统的本地代码页运行,因为现代 Windows 使用 UTF16。

标签: unicode internationalization inno-setup gbk


【解决方案1】:

要从 UTF-8 文件加载字符串,请使用 LoadStringFromFileInCP from
Inno Setup - Convert array of string to Unicode and back to ANSI

const
  CP_UTF8 = 65001;

{ ... }
var
  FileName: string;
  S: string;
begin
  FileName := 'test.txt';
  if not LoadStringFromFileInCP(FileName, S, CP_UTF8) then
  begin
    Log('Error reading the file');
  end
    else
  begin
    Log('Read: ' + S);
  end;
end;

要保存没有 BOM 的 UTF-8 文件:

【讨论】:

  • 我在两个方向上都使用了 Windows API 的方式,它工作正常。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2019-11-07
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多