首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将INI文件保存在UTF-8中,而不是在Inno安装程序中保存ANSI。

将INI文件保存在UTF-8中,而不是在Inno安装程序中保存ANSI。
EN

Stack Overflow用户
提问于 2016-01-31 18:08:02
回答 1查看 5.5K关注 0票数 4

我开始使用Inno安装程序,我的INI文件编码有一些问题。

我希望将用户输入保存在INI文件中,并且这个输入可以包含重音。

我使用Inno安装Unicode,我的setupScript.iss是UTF-8编码的,下面是我的代码(一部分):

代码语言:javascript
运行
复制
[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;

getUser|Adresse[INI]部件中返回的值不是UTF-8编码的:我用Notepad++打开INI文件,看到文件是UTF-8编码的。但是值adresse是ANSI编码的(如果我将文件的编码更改为ANSI,这个值是可读的)

有人可以帮助我理解如何将这个用户输入保存在UTF-8中?

非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-31 20:07:09

Inno安装程序的INI函数([INI]部分和SetIni*函数)在内部使用Windows函数WritePrivateProfileString

这一功能根本不支持UTF-8。它只支持ANSI编码和UTF-16.

请参阅How to read/write Chinese/Japanese characters from/to INI files?

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

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

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

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

代码语言:javascript
运行
复制
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;
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35117362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档