2016-10-04 3 views
4

У меня есть файл .inf, экспортированный из Resource Hacker. Файл находится в кодировке UTF-16 LE.Inno Setup Pascal Script - Чтение файла UTF-16

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; 

Я получаю это в Debug Output:

E 

Скажите, пожалуйста, как решить эту проблему.

Заранее спасибо.

ответ

0

Кажется, файл, который вы пытаетесь выполнить, представляет собой кодированный текстовый файл в формате Unicode (UTF-16LE) Windows.

Вы можете использовать Командную строку iConv и преобразовать свой файл в кодированный файл Windows UTF-8.

LoadStringFromFile Support Function не загружает строки Unicode и поддерживает только загрузку кодированных текстовых файлов ANSI и UTF-8.

Отладочный выход компилятора Inno Setup перестает регистрировать текстовый файл, так как находит символ, который он не может загрузить (NULL), и именно поэтому вы получаете только «E» в отладочном выходе компилятора, даже LoadStringFromFile загружает текстовый файл полностью.


необходимо загрузить программу установки в Iconv, как показано ниже, чтобы получить Iconv исполняемый файл и некоторые библиотеки DLL используется для преобразования между кодировки символов.

enter image description here

После загрузки, установки gnuwin32 (LibIconv для Windows) и перейдите в папку установки.

Скопируйте следующие четыре файла внутри подкаталога в установочной папке под названием «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 должен загрузить текстовый файл правильно, так как теперь он имеет UTF-8 кодировке Windows.

Вы также можете зарегистрировать его после преобразования его в строку Unicode, например Log(String(RESOURCE_INFO)), если вы используете Unicode Inno Setup.

+0

Спасибо! Работает как Очарование! – Blueeyes789

+0

1) Почему ANSI? Таким образом вы теряете символы Unicode. Используйте UTF-8! 2) Обратите внимание, что ANSI не совпадает с Windows-1252. Кодировка ANSI отличается от конфигурации Windows. Поэтому, если вы явно конвертируете в Windows-1252, но вы загружаете файл с использованием настроенной кодировки ANSI, вы получаете беспорядок, если только файл не использует только символы ASCII. 3) Вы можете [использовать PowerShell для преобразования кодировки] (http://stackoverflow.com/a/4817683/850848), нет необходимости в стороннем инструменте. Но в любом случае вам не нужен какой-либо внешний инструмент. Вы можете преобразовать это в скрипт Pascal. –

+0

@MartinPrikryl исправлено до UTF-8. Я забыл PowerShell. :-( – GTAVLover

3

Файл находится в кодировке UTF-16 LE.

LoadStringFromFile не поддерживает кодировку Unicode. Он загружает файл как есть, в массив байтов (AnsiString эффективно используется в качестве байтового массива).

Поскольку Unicode string действительно использует кодировку UTF-16 LE, все, что вам нужно сделать, это скопировать массив байтов по-разному в (Unicode) string. И обрезайте UTF-16 LE BOM (FEFF).

procedure RtlMoveMemory(Dest: string; Source: PAnsiChar; Len: Integer); 
    external '[email protected] 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; 

Смотрите также Inno Setup Reading file in Ansi and Unicode encoding.

+0

Что? Я думаю, что это преобразование невозможно. Спасибо за ответ, мне нравится знать, какая функция поддерживает кодировку Unicode. :-) – Blueeyes789

+0

Извините. Я попросил о помощи здесь. Игнорировать предыдущий комментарий. :-( – GTAVLover

+0

См. [Файл чтения Inno Setup в кодировке Ansi и Unicode] (http://stackoverflow.com/q/38968230/850848). –