How to read and compare a number from a txt file during installation

I need my setup to check the first line of a txt file during setup and compare it to whatever number I want.

This is a txt file:

enter image description here

This is the code I'm trying to change:

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;

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';
  // I WANT TO READ THE FIRST LINE OF THE TXT FILE AND return N/A if not found
  L2Ver2.Caption := GetKeyValue('', 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 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;

      

I got the code from this post: Inno Setup - How to read INF file during installation

I'm not sure how to edit function GetKeyValue

this other piece of code tooL2Ver2.Caption := GetKeyValue('', FilePath, 'N/A');

+3


source to share


1 answer


How can I read a specific line from a text file?

Except for the function LoadStringsFromFile

, you cannot use this function. The following function I wrote loads the text file given by the parameter FileName

and tries to copy the string from the 0 based index to the Index

output parameter Line

. If the download of the given file is complete, and the file has enough lines to satisfy the requested Index

, it returns True, False otherwise.

function TryGetFileLine(const FileName: string; Index: Integer; out Line: string): Boolean;
var  
  FileLines: TArrayOfString;
begin
  // the function succeed when the file can be loaded and the count of lines is
  // greater than the requested line index (it is 0 based index, hence the line
  // count must be greater)
  Result := LoadStringsFromFile(FileName, FileLines) and (GetArrayLength(FileLines) > Index);
  // if the above succeeded, return the file line of the requested index to the
  // output parameter
  if Result then
    Line := FileLines[Index];
end;

      

For shorter code, I chose 0-based indexing, so if you want to read the first line of a file, you must ask for index 0, index for the second line 1, and so on. To get the first line, it would be:

var
  S: string;
begin
  // if the file could be opened and has at least one line, then the following
  // call succeed and the variable S will contain the first line of the file
  if TryGetFileLine('C:\File.txt', 0, S) then
    MsgBox('The first line of the given file is: ' + S, mbInformation, MB_OK);
end;

      

How can I convert a string to an integer?

There are currently several ways to convert a string to a 32-bit integer in Inno Setup. StrToInt

and StrToIntDef

. The first one tries to convert the passed string to an integer, and if that fails, it returns -1. The second does the same, except when the conversion fails, it returns the value specified by the parameter def

.

Unfortunately, none of the above functions can reliably determine if a given string has been converted without losing one value in the integer range. Consider the following code:

var
  Value1: Integer;
  Value2: Integer;
begin
  Value1 := StrToInt('-1');
  Value2 := StrToInt('Non integer');

  if Value1 = Value2 then
  begin
    MsgBox('Err, the result is the same for string of value -1 and for a non ' +
      'integer string.', mbInformation, MB_OK);
  end;
end;

      



The above code demonstrates that if you use a function StrToInt

, you won't be able to determine if a string (in your case, a string read from a file) contains a value -1

or not an integer value. The def

function parameter is applied in the same way StrToIntDef

.

However, you can fix this problem if you explicitly check if the string contains the return value of the function if the conversion fails. The following function returns True if the string S

contains a valid integer value; otherwise, False. If the conversion succeeds, the converted value is returned to the output parameter Value

:

function TryStrToInt(const S: string; out Value: Integer): Boolean;
var
  I: Integer;
begin
  I := StrToIntDef(S, -1);
  Result := (I <> -1) or (S = '-1');
  if Result then
    Value := I;
end;

      

Using this function looks like this:

var
  I: Integer;
begin
  if TryStrToInt('12345', I) then
  begin
    MsgBox('The passed string was converted to integer. Its value is: ' +
      IntToStr(I), mbInformation, MB_OK);
  end;
end;

      

Safe until the end ...

You did not specify which version values ​​in your text file, so I assumed they are 32-bit integers and could have any value in the range (even though I believe in reality that you will only use positive values. where the built-in integer conversion functions may suffice).

However, a more robust string for an integer conversion function in the codebase is fine. So let's stick the above functions together to try and read the first line of a text file and convert it to an integer:

var
  S: string;
  I: Integer;
begin
  // if the first line of the file was successfully read and could have been
  // converted to integer, then...
  if TryGetFileLine('C:\File.txt', 0, S) and TryStrToInt(S, I) then
  begin
    MsgBox('The first line of the given file was successfully read and could ' +
      'have been converted to integer. Its value is: ' + IntToStr(I),
      mbInformation, MB_OK);
    // here the variable I contains the value that you can compare in a way
    // of your choice
  end;
end;

      

+2


source







All Articles