5

在设置过程中,我需要知道如何从 INF 文件 [.inf] 中读取值。我希望安装程序检查我要更新的程序版本,该程序版本不存储在注册表或任何其他文件中,仅在 .inf 文件中。然后必须从中获取版本。

我得到了你的答案,@Tlama,我不能使用 DLL 来获取软件的版本。该程序仅将当前版本保存在 INF 文件中。

我想做的是让安装程序检查我正在使用的软件的当前版本,并在标签文本中显示该版本。

inf信息是这样的:

NetVersion=1.1.1.1
PatchVersion=2.0.1
ProductName=SoftwareX

我只需要 PatchVersion 在它说版本之后显示:####:

在此处输入图像描述

这是我要修复的代码:

function GetInfsam: String;
var
  sVersion : String;
Begin
  sVersion := '';
  GetIniString('', 'PatchVersion', 'sVersion', '{app}\Sam.inf');
  Result := sVersion;
end;

Procedure InitializeWizard7();
var
  L2Ver1 : Tlabel;
  L2Ver2 : Tlabel;
Begin
  L2Ver1:=  TLabel.Create(WizardForm);
  L2Ver1.Transparent:= True;
  L2Ver1.AutoSize:= False;
  L2Ver1.WordWrap:= True;
  L2Ver1.Font.name:= 'Agency FB';
  L2Ver1.Font.Size:= 12;
  L2Ver1.Font.Color:= clwhite;
  L2Ver1.Caption:= 'Version:';
  L2Ver1.Parent:= WizardForm.SelectdirPage;
  L2Ver1.Left := 5;
  L2Ver1.top := 260;
  L2Ver1.Width := 150;
  L2Ver1.Height := 40;

  L2Ver2:=  TLabel.Create(WizardForm);
  L2Ver2.Transparent:= True;
  L2Ver2.AutoSize:= False;
  L2Ver2.WordWrap:= True;
  L2Ver2.Font.name:= 'Agency FB';
  L2Ver2.Font.Size:= 12;
  L2Ver2.Font.Color:= clwhite;
  L2Ver2.Caption:= GetInfsam;
  L2Ver2.Parent:= WizardForm.SelectdirPage;
  L2Ver2.Left := L2Ver1.Width + L2Ver1.Left + 8;
  L2Ver2.top := 260;
  L2Ver2.Width := 100;
  L2Ver2.Height := 40;
End;

请,我需要帮助来修复我的代码。

4

2 回答 2

10

如何读取 INF 文件?

INF 文件只是一种带有specified syntax. 因此,要使用 INF 文件,您需要将它们视为普通的 INI 文件。假设你有一个这样的 INF 文件:

[Add.Code]
File.dll=File.dll

[File.dll]
File=http://www.code.com/file.dll
FileVersion=1,0,0,143

FileVersion您可以使用以下方式读取密钥GetIniString

procedure InitializeWizard;
var
  Version: string;
begin
  Version := GetIniString('File.dll', 'FileVersion', '', 'c:\File.inf');
  if Version <> '' then
    MsgBox('File version: ' + Version, mbInformation, MB_OK);
end;

更新:

1.格式错误的INF文件

根据您的更新,如果您的 INF 文件的内容如下所示:

NetVersion=1.1.1.1
PatchVersion=2.0.1
ProductName=SoftwareX

那么它不是一个格式正确的 INF 文件,而是一个以 INF 扩展名保存的名称值对文本文件。真实 INF 文件必须[]为每个键值集都有一个有效部分,但您的文件中缺少此部分。

2. 空Section参数值不能调用GetIniString函数

您不能GetIniString使用空Section参数值调用函数,因为对于内部调用的GetPrivateProfileString函数,这意味着返回给定文件的所有部分名称,而不是指定键的值。例如下面的调用是无效的,因为第一个参数Section不能为空:

GetIniString('', 'KeyName', 'Default', 'c:\File.xxx');

3. 如何使用名称值对文本文件?

您只需像使用文本文件一样使用该文件。对于键值文本文件处理将是理想的使用TStringList类,或者至少在 Delphi 中。不幸的是,在 InnoSetup 中,TStringList该类没有发布键值内容操作所需的属性,因此您需要制作自己的键值文本文件解析功能。这是获取给定键值的方法。因为键值分隔符应该是=符号。此函数在成功找到AKeyName给定AFileName文件中的键时返回键值ADefault,失败时返回默认值:

function GetKeyValue(const AKeyName, AFileName, ADefault: string): string;
var  
  I: Integer;
  KeyPos: Integer;
  KeyFull: string;
  FileLines: TArrayOfString;
begin
  Result := ADefault;
  if LoadStringsFromFile(AFileName, FileLines) then
  begin
    KeyFull := AKeyName + '=';
    for I := 0 to GetArrayLength(FileLines) - 1 do
    begin
      FileLines[I] := TrimLeft(FileLines[I]);
      KeyPos := Pos(KeyFull, FileLines[I]);
      if KeyPos > 0 then
      begin
        Result := Copy(FileLines[I], KeyPos + Length(AKeyName) + 1, MaxInt);
        Break;
      end;
    end;
  end;
end;

要从当前选择的安装路径中预期的文件中读取PatchVersion密钥的值,Sam.inf您可以使用类似的东西。每当您的用户更改目录编辑框中的文本以及将显示目录选择页面时,此脚本将更新标签值:

var
  // target version label must be declared globally
  L2Ver2: TLabel;

procedure DirEditChange(Sender: TObject);
var
  FilePath: string;
begin
  // assign the expected INF file path
  FilePath := AddBackslash(WizardForm.DirEdit.Text) + 'Sam.inf';
  // read the PatchVersion key value, return N/A if not found
  L2Ver2.Caption := GetKeyValue('PatchVersion', FilePath, 'N/A');
end;

procedure InitializeWizard;
begin
  // create the target label as before
  L2Ver2 := TLabel.Create(WizardForm);
  ...
  // bind the DirEditChange method to the directory edit's OnChange event
  WizardForm.DirEdit.OnChange := @DirEditChange;  
end;

procedure CurPageChanged(CurPageID: Integer);
begin
  // if the page has been turned to the select directory page, update the
  // label caption by firing the assigned OnChange event method manually
  if (CurPageID = wpSelectDir) then
    DirEditChange(nil);
end;
于 2013-03-05T14:24:24.533 回答
3

我所有的 INF 文件都具有类似于 INI 文件的结构。如果这也是你的情况,我建议你打开你的 INF,就好像它是 INI 一样,使用(如 TLama 建议的那样)

在设置功能中:

function GetIniInt(const Section, Key: String; const Default, Min, Max: Longint; const Filename: String): Longint;
function GetIniString(const Section, Key, Default, Filename: String): String;

在预处理器中:

str ReadIni(str 1, str 2, str 3, str? 4)

说明 (来自 Inno Setup 帮助)

从 INI 文件中读取值。参数 1 必须是 INI 文件的名称,参数 2 – INI 文件中某个节的名称,第三个参数是要读取的节中的键。最后一个可选参数可用于提供失败时返回的默认值,如果省略,则返回空字符串。

于 2013-03-05T14:24:59.167 回答