在安装期间将 .INI 文件从 UTF-8 编码转换为 ANSI

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

我有一个UTF-8编码的.INI文件,在安装的时候用户会写一个带符号和代码的名字写入.INI文件,安装完成后或者安装的时候就可以了将该 UTF-8 转换为 ANSI?

我无法从头开始处理 ANSI 文件,因为程序无法识别代码和符号

这显示名称从头开始用 ANSI 处理文件,而实际上它是:WILLIAMS117 ™

如果文件有 UTF-8 BOM,很简单,使用 LoadStringsFromFile to load the file and the SaveStringsToFile 将其保存回 Ansi 编码:

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

如果文件没有UTF-8 BOM,需要自行转换:

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;

您当然也可以使用外部实用程序。喜欢 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)

如果您不能依赖最终用户将预期的 Ansi 编码设置为 Windows 中的遗留编码,则必须明确指定它,而不是使用 CP_ACP。参见:
.