Search code examples
inno-setupinf

Inno Setup - How to read an INF file during the Setup


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.


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;