Inno Setup: recording/recover file path in UTF8

286 views Asked by At

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?

1

There are 1 answers

1
Martin Prikryl On BEST ANSWER

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: