Inno Setup Pascal 脚本 - 读取 UTF-16 文件

Inno Setup Pascal Script - Reading UTF-16 file

我有一个从 Resource Hacker 导出的 .inf 文件。该文件采用 UTF-16 LE 编码。

EXTRALARGELEGENDSII_INI TEXTFILE "Data.bin"

LARGEFONTSLEGENDSII_INI TEXTFILE "Data_2.bin"

NORMALLEGENDSII_INI TEXTFILE "Data_3.bin"

THEMES_INI TEXTFILE "Data_4.bin" 

当我使用 LoadStringFromFile function 加载它时:

procedure LoadResources;
var
  RESOURCE_INFO: AnsiString;
begin
  LoadStringFromFile(ExpandConstant('{tmp}\SKINRESOURCE - INFO.inf'), RESOURCE_INFO);
  Log(String(RESOURCE_INFO));
end;

我在调试输出中得到这个:

E

请告诉我如何解决这个问题。

提前致谢。

文件采用 UTF-16 LE 编码。

LoadStringFromFile不支持任何Unicode编码。它按原样将文件加载到字节数组(AnsiString 有效地用作字节数组)。

作为 Unicode string(在 – the only version as of Inno Setup 6) actually uses the UTF-16 LE encoding, all you need to do is to copy the byte array bitwise to the (Unicode) string. And trim the UTF-16 LE BOMFEFF)中。

procedure RtlMoveMemory(Dest: string; Source: PAnsiChar; Len: Integer);
  external 'RtlMoveMemory@kernel32.dll stdcall';

function LoadStringFromUTF16LEFile(FileName: string; var S: string): Boolean;
var
  A: AnsiString;
begin
  Result := LoadStringFromFile(FileName, A);
  if Result then
  begin
    SetLength(S, Length(A) div 2);
    RtlMoveMemory(S, A, Length(S) * 2);
    { Trim BOM, if any }
    if (Length(S) >= 1) and (Ord(S[1]) = $FEFF) then
      Delete(S, 1, 1);
  end;
end;

另请参阅:

您尝试记录的文件似乎是 Windows Unicode (UTF-16LE) 编码的文本文件。

您可以使用 iConv 命令行并将您的文件转换为 Windows UTF-8 编码文件。

LoadStringFromFile Support Function 不能很好地加载 Unicode 字符串,它只支持加载 ANSI 和 UTF-8 编码的文本文件。

Inno Setup Compiler Debug Output 停止记录文本文件,因为它找到了一个无法加载的字符(NULL),这就是为什么你在 Compiler Debug Output 中只得到 "E" 甚至 LoadStringFromFile 完全加载文本文件。


您需要下载iConv的安装程序,如下图所示,以获得iConv可执行文件和一些用于字符编码之间转换的DLL。

下载后,安装 GnuWin32(Windows 的 LibIconv)并进入安装文件夹。

在名为"bin".

的安装文件夹的子目录中复制以下四个文件

他们是:

libcharset1.dll

libiconv2.dll

iconv.exe

libintl3.dll

将这些文件复制到您存储 Inno 安装项目文件的目录中。

然后使用以下代码进行转换。

[Files]
Source: "libcharset1.dll"; Flags: dontcopy
Source: "iconv.exe"; Flags: dontcopy
Source: "libiconv2.dll"; Flags: dontcopy
Source: "libintl3.dll"; Flags: dontcopy

[Code]
function InitializeSetup(): Boolean
var
  ErrorCode: Integer;
begin
  ExtractTemporaryFile('iconv.exe');
  ExtractTemporaryFile('libcharset1.dll');
  ExtractTemporaryFile('libintl3.dll');
  ExtractTemporaryFile('libiconv2.dll');
  ShellExec('Open', ExpandConstant('CMD.exe'), ExpandConstant('/C iConv -f UTF-16LE -t UTF-8 < SKINRESOURCE-INFO.inf > SKINRESOURCE-INFO-ANSI.inf'), ExpandConstant('{tmp}'), SW_HIDE, ewWaitUntilTerminated, ErrorCode); 
  DeleteFile(ExpandConstant('{tmp}\SKINRESOURCE-INFO.inf')); 

现在 LoadStringFromFile 应该正确加载文本文件,因为现在它具有 Windows UTF-8 编码。

如果您使用的是 Unicode Inno Setup,您也可以在将其转换为 Unicode 字符串后记录它,例如 Log(String(RESOURCE_INFO))