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 'WideCharToMultiByte@kernel32.dll stdcall';
function MultiByteToWideChar(
CodePage: UINT; dwFlags: DWORD; const lpMultiByteStr: AnsiString; cchMultiByte: Integer;
lpWideCharStr: string; cchWideChar: Integer): Integer;
external 'MultiByteToWideChar@kernel32.dll 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.