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

时间:2016-11-21 04:30:34

标签: utf-8 inno-setup ini ansi

我有一个UTF-8编码.INI文件,在安装过程中,用户会写一个带有符号和代码的名称,这些符号和代码将被写入.INI文件,完成后或在安装过程中,它将能够转换为UTF-8到ANSI?

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

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

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

1 个答案:

答案 0 :(得分:1)

如果文件包含UTF-8 BOM,则很简单,使用LoadStringsFromFile加载文件,然后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。请参阅:
Inno Setup - Convert array of string to Unicode and back to ANSI