Williams Mogollon
Williams Mogollon

Reputation: 123

To convert a .INI file from UTF-8 encoding to ANSI during installation

I have a UTF-8 encoding .INI file, during the installation the users will write a name with symbols and codes that will be written to the .INI file, after finishing or during the installation it will be able to convert that UTF- 8 to ANSI?

I can not process the file in ANSI from the beginning because the codes and symbols are not recognized in the program

This displays the name processing the file with ANSI from the beginning, when in fact it is: WILLIAMS117 ™

This displays the name processing the file with ANSI from the beginning, when in fact it is: WILLIAMS117 ™

Upvotes: 0

Views: 2238

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202642

If the file has UTF-8 BOM, it's easy, use the LoadStringsFromFile to load the file and the SaveStringsToFile to save it back in Ansi encoding:

function ConvertFileFromUTF8ToAnsi(FileName: string): Boolean;
var
  Lines: TArrayOfString;
begin
  Result :=
    LoadStringsFromFile(FileName, Lines) and
    SaveStringsToFile(FileName, Lines, False);
end;

If the file does not have UTF-8 BOM, you have to convert it on your own:

function WideCharToMultiByte(
  CodePage: UINT; dwFlags: DWORD; lpWideCharStr: string; cchWideChar: Integer;
  lpMultiByteStr: AnsiString; cchMultiByte: Integer;
  lpDefaultCharFake: Integer; lpUsedDefaultCharFake: Integer): Integer;
  external '[email protected] stdcall';

function MultiByteToWideChar(
  CodePage: UINT; dwFlags: DWORD; const lpMultiByteStr: AnsiString; cchMultiByte: Integer; 
  lpWideCharStr: string; cchWideChar: Integer): Integer;
  external '[email protected] stdcall';  

const
  CP_ACP = 0;
  CP_UTF8 = 65001;

function ConvertFileFromUTF8ToAnsi(FileName: string): Boolean;
var
  S: AnsiString;
  U: string;
  Len: Integer;
begin
  Result := LoadStringFromFile(FileName, S);
  if Result then
  begin
    Len := MultiByteToWideChar(CP_UTF8, 0, S, Length(S), U, 0);
    SetLength(U, Len);
    MultiByteToWideChar(CP_UTF8, 0, S, Length(S), U, Len);
    Len := WideCharToMultiByte(CP_ACP, 0, U, Length(U), S, 0, 0, 0);
    SetLength(S, Len);
    WideCharToMultiByte(CP_ACP, 0, U, Length(U), S, Len, 0, 0);

    Result := SaveStringToFile(FileName, S, False);
  end;
end;

You can of course also use an external utility. Like PowerShell:

powershell.exe -ExecutionPolicy Bypass -Command [System.IO.File]::WriteAllText('my.ini', [System.IO.File]::ReadAllText('my.ini', [System.Text.Encoding]::UTF8), [System.Text.Encoding]::Default)

If you cannot to rely on the end-user to have the intended Ansi encoding set as legacy in Windows, you have to specify it explicitly, instead of using CP_ACP. See:
Inno Setup - Convert array of string to Unicode and back to ANSI.

Upvotes: 1

Related Questions