Inno Setup Pascal Script - Reading UTF-16 file

前端 未结 2 1304
伪装坚强ぢ
伪装坚强ぢ 2020-12-06 14:17

I have an .inf file exported from Resource Hacker. The file is in UTF-16 LE encoding.

EXTRALARGELEGENDSII_INI TEXTFILE \"Data.bin\"

LARGEFONTSL         


        
相关标签:
2条回答
  • 2020-12-06 14:50

    The file is in the UTF-16 LE encoding.

    The LoadStringFromFile does not support any Unicode encoding. It loads the file as is, to a byte array (the AnsiString is effectively used as a byte array).

    As the Unicode string (in Unicode version of Inno Setup) actually uses the UTF-16 LE encoding, all you need to do is to copy the byte array bit-wise 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;
    

    See also Inno Setup Reading file in Ansi and Unicode encoding.

    0 讨论(0)
  • 2020-12-06 15:00

    It seems the file you are trying to log is a Windows Unicode (UTF-16LE) Encoded text file.

    You can use iConv Command Line and convert your file to Windows UTF-8 Encoded File.

    The LoadStringFromFile Support Function does not load Unicode Strings well and it only supports loading ANSI and UTF-8 Encoded Text Files.

    Inno Setup Compiler Debug Output stops logging the Text File because it finds a Character it can't load (NULL) and that's why you're getting only "E" in Compiler Debug Output even LoadStringFromFile loads the text file completely.


    You need to download the Setup Program of the iConv as shown below to get iConv Executable File and some DLLs used to convert between character encoding.

    After downloaded, install GnuWin32 (LibIconv for Windows) and go to the installation folder.

    Copy following four files inside the sub directory in installation folder called "bin".

    They are:

    libcharset1.dll

    libiconv2.dll

    iconv.exe

    libintl3.dll

    copy these files to the directory where you store files of your Inno Setup Project.

    Then use following code to do the Conversion.

    [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')); 
    

    Now LoadStringFromFile should load the text file correctly as now it has the Windows UTF-8 Encoding.

    You may also log it after converting it into a Unicode String like Log(String(RESOURCE_INFO)), if you are using Unicode Inno Setup.

    0 讨论(0)
提交回复
热议问题