在Inno Setup中以UTF-8而不是ANSI保存INI文件

时间:2016-01-31 18:08:02

标签: encoding utf-8 inno-setup ini codepages

我开始使用Inno Setup,我的INI文件编码存在一些问题 我想在INI文件中保存用户输入,此输入可以包含重音符。

我使用Inno Setup Unicode,我的setupScript.iss是UTF-8编码的,这是我的代码(部分):

>hihowareyou<

>hihow<部分中[INI] Filename: "{app}\www\conf\config.ini"; Section: "Settings"; Key: "ca.plafondAnnuel"; String: "{code:GetUser|Plafond}" Filename: "{app}\www\conf\config.ini"; Section: "Settings"; Key: "app.siren"; String: "{code:GetUser|Siren}" Filename: "{app}\www\conf\config.ini"; Section: "Settings"; Key: "app.adresse"; String: "{code:GetUser|Adresse}" [Code] var UserPage: TInputQueryWizardPage; ExamplePage : TInputOptionWizardPage; ImmatriculationPage : TInputOptionWizardPage; FakeElemIndex: Integer; FakeElem: TCustomEdit; AdresseTextarea: TNewMemo; procedure InitializeWizard; begin UserPage := CreateInputQueryPage(wpWelcome, 'Configuration de l''application', '', 'Configurez ici votre application. Une fois installée, vous pourrez modifier ces valeurs.'); UserPage.Add('Siren :', False); UserPage.Add('Plafond annuel (utilisé par les auto-entreprises, mettre 0 si vous ne souhaitez pas plafonner votre chiffre d''affaire.):', False); FakeElemIndex := UserPage.Add('Votre adresse complète (telle qu''elle s''affichera sur les devis et factures, avec nom complet):', False); FakeElem := UserPage.Edits[FakeElemIndex]; AdresseTextarea := TNewMemo.Create(WizardForm); AdresseTextarea.Parent := FakeElem.Parent; AdresseTextarea.SetBounds(FakeElem.Left, FakeElem.Top, FakeElem.Width, ScaleY(50)); // Hide the original single-line edit FakeElem.Visible := False; end; function GetUser(Param: String): String; begin if Param = 'Adresse' then Result := AdresseTextarea.Text else if Param = 'Siren' then Result := UserPage.Values[0] else if Param = 'Plafond' then Result := UserPage.Values[1]; end; 返回的值不是UTF-8编码的:我用Notepad ++打开INI文件,我看到该文件是UTF-8编码的。但值getUser|Adresse是ANSI编码的(如果我将文件的编码更改为ANSI,则此值是可读的)

有人可以帮我理解如何以UTF-8保存此用户输入?

非常感谢!

1 个答案:

答案 0 :(得分:2)

Inno Setup([INI]部分和SetIni*部分)的INI功能在内部使用Windows API函数WritePrivateProfileString

此功能根本不支持UTF-8。它支持的全部是ANSI编码和UTF-16 见How to read/write Chinese/Japanese characters from/to INI files?

因此,如果目标应用程序依赖于Windows API函数来读取它,那么它是否能够读取UTF-8编码的INI文件甚至是个问题。

无论如何,如果您需要UTF-8,您必须自己将条目格式化为INI格式,并使用SaveStringsToUTF8File function进行编写。

最后一个选项是通过使用系统调用WritePrivateProfileString来编写看似ANSI编码的字符串,它实际上是UTF-8编码的。

为此,您需要在代码中将字符串转换为UTF-8。您可以使用WideCharToMultiByte

function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD;
  lpWideCharStr: string; cchWideChar: Integer; lpMultiByteStr: AnsiString;
  cchMultiByte: Integer; lpDefaultCharFake: Integer;
  lpUsedDefaultCharFake: Integer): Integer;
  external 'WideCharToMultiByte@kernel32.dll stdcall';

const
  CP_UTF8 = 65001;

function GetStringAsUtf8(S: string): AnsiString;
var
  Len: Integer;
begin
  Len := WideCharToMultiByte(CP_UTF8, 0, S, Length(S), Result, 0, 0, 0);
  SetLength(Result, Len);
  WideCharToMultiByte(CP_UTF8, 0, S, Length(S), Result, Len, 0, 0);
end;

function WritePrivateProfileString(
  lpAppName, lpKeyName, lpString, lpFileName: AnsiString): Integer;
  external 'WritePrivateProfileStringA@kernel32.dll stdcall';

procedure CurStepChanged(CurStep: TSetupStep);
var
  IniFileName: string;
begin
  if CurStep = ssInstall then
  begin
    Log('Writting INI file');
    if not ForceDirectories(ExpandConstant('{app}\www\conf')) then
    begin
      MsgBox('Error creating directory for INI file', mbError, MB_OK);
    end
      else
    begin
      IniFileName := ExpandConstant('{app}\www\conf\config.ini');
      if (WritePrivateProfileString(
            'Settings', 'ca.plafondAnnuel', GetStringAsUtf8(GetUser('Plafond')),
            IniFileName) = 0) or
         (WritePrivateProfileString(
            'Settings', 'app.siren', GetStringAsUtf8(GetUser('Siren')),
            IniFileName) = 0) or
         (WritePrivateProfileString(
            'Settings', 'app.adresse', GetStringAsUtf8(GetUser('Adresse')),
            IniFileName) = 0) then
      begin
        MsgBox('Error writting the INI file', mbError, MB_OK);
      end;
    end;
  end;
end;