Question

i need to know how to read a value from INF file [.inf], during the setup. I want the installer to check the version of the program that i am going to update, This program version is not stored in the registry or any other file, is only in the .inf file. Then is a must to get the version from it.

I got your answers, @Tlama and i cannot use a DLL to get version of the software. This program only save the current version in the INF file.

What i want to do, is to make the installer to check the current versión of the software that i am working with, and display that version in a label text.

The inf information is this:

NetVersion=1.1.1.1
PatchVersion=2.0.1
ProductName=SoftwareX

I just need the PatchVersion to display after where it says version: #### :

enter image description here

this is the code i am trying to fix:

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;

Please, i need help to fix my code.

Was it helpful?

Solution

How to read INF file ?

INF files are just sort of INI files with the specified syntax. So to work with INF files you need to treat them as ordinary INI files. Assuming you have a INF file like this:

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

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

You can read the FileVersion key by using GetIniString this way:

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;

Update:

1. Malformed INF file

According to your update, if the content of your INF file looks like this:

NetVersion=1.1.1.1
PatchVersion=2.0.1
ProductName=SoftwareX

then it's not a well formed INF file, but a name value pair text file saved with INF extension. Real INF files must have a valid [] section for each key value set, but this section is missing in your file.

2. GetIniString function cannot be called with empty Section parameter value

You must not call the GetIniString function with empty Section parameter value, because for the internally called GetPrivateProfileString function it means to return all section names for a given file, not value of a specified key. So for instance the following call is invalid, because the first parameter Section cannot be empty:

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

3. How to work with a name value pair text file ?

You'll just need to work with that file as with a text file. For a key value text file handling would be ideal to use the TStringList class, or at least in Delphi. In InnoSetup unfortunately the TStringList class doesn't have published properties needed for a key value content manipulation, so you'll need to make your own key value text file parsing function. Here's the one for getting value for a given key. As the key value delimiter is supposed to be the = sign. This function returns a key value when succeed to find a AKeyName key in a given AFileName file or default ADefault value when fails:

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;

To read a value of the PatchVersion key from the Sam.inf file expected in the currently selected install path you can use something like this. This script will update the label value whenever your user change the text in the directory edit box and when the directory selection page is going to be displayed:

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;

OTHER TIPS

All my INF files have a structure similar to INI files. If that's your case too I suggest you to open your INF as if it was INI, using (as suggested by TLama)

in setup functions:

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

in preprocessor:

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

Description (from Inno Setup help)

Reads the value from an INI file. Argument 1 must be the name of the INI file, argument 2 – the name of a section in the INI file, the third argument is the key in the section to read. Last optional argument can be used to provide the default value that will be returned on failure, if it is omitted, an empty string is returned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top