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 BOM(FEFF
)中。
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))
。
我有一个从 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
(在 string
. And trim the UTF-16 LE BOM(FEFF
)中。
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))
。