unicodeinternationalizationinno-setupgbk

Inno Setup: recording/recover file path in UTF8


We are using Inno Setup (unicode version) to create resource package (or "samples") for our product. The program part of our product knows the location of the samples by a file that is written by samples installer. At current, it is implemented in plain way:

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;

This plain way has a fatal issue: the installer is run in Chinese language Windows, and the whole stuff works in GBK encoding, but our product is built up on UTF8 base.

After some search, I got some solution by calling Windows WideCharToMultiByte inside Pascal code. However this won't work, as it requires UTF16 as input, but what I have is GBK.

In addition, the Inno Setup also won't work with existing UTF8 file name in my SamplePath.txt. If I manually edit the SamplePath.txt file to fill UTF8-encoded Chinese letters, and initialize the app builtin with following code, it displays messy characters in dir selection page:

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

So is there any way to load/store a file name with i18n characters in UTF8?


Solution

  • To load a string from UTF-8 file, use 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;
    

    To save UTF-8 file without BOM: