Search code examples
installationinno-setuppascalscript

Insert a line to a text file/template in Inno Setup before a specific line if doesn't exist yet


How can I add a line to a file/template before a specific other line, if it doesn't exist?

For example for the following JS file, I have to make sure that there's dependencies.push(...) line between the ABOVE THIS LINE and BELOW THIS LINE comment-lines. If the dependencies.push(...) is not present, I have to add it before the BELOW THIS LINE comment-line:

(function(ng) {
    var dependencies = [];

    /*DO NOT MODIFY ABOVE THIS LINE!*/

    dependencies.push("mxdfNewTransaction.controller.mxdfNewTransactionCtrl");

    /*DO NOT MODIFY BELOW THIS LINE!*/

    ng.module('prismApp.customizations', dependencies, null);
})(angular);

I have to also do the same thing with a similar HTML template file.

Thanks for your help.


Solution

  • You have to parse the file line-by-line to find the spot to insert your code.

    Something like this:

    function AddLineToTemplate(
      FileName: string; StartLine, EndLine, AddLine: string): Boolean;
    var
      Lines: TArrayOfString;
      Count, I, I2: Integer;
      Line: string;
      State: Integer;
    begin
      Result := True;
    
      if not LoadStringsFromFile(FileName, Lines) then
      begin
        Log(Format('Error reading %s', [FileName]));
        Result := False;
      end
        else
      begin
        State := 0;
        
        Count := GetArrayLength(Lines);
        for I := 0 to Count - 1 do
        begin
          Line := Trim(Lines[I]);
          if (CompareText(Line, StartLine) = 0) then
          begin
            State := 1;
            Log(Format('Start line found at %d', [I]));
          end
            else
          if (State = 1) and (CompareText(Line, AddLine) = 0) then
          begin
            Log(Format('Line already present at %d', [I]));
            State := 2;
            break;
          end
            else
          if (State = 1) and (CompareText(Line, EndLine) = 0) then
          begin
            Log(Format('End line found at %d, inserting', [I]));
            SetArrayLength(Lines, Count + 1);
            for I2 := Count - 1 downto I do
              Lines[I2 + 1] := Lines[I2];
            Lines[I] := AddLine;
            State := 2;
    
            if not SaveStringsToFile(FileName, Lines, False) then
            begin
              Log(Format('Error writing %s', [FileName]));
              Result := False;
            end
              else
            begin
              Log(Format('Modifications saved to %s', [FileName]));
            end;
    
            break;
          end;
        end;
    
        if Result and (State <> 2) then
        begin
          Log(Format('Spot to insert line was not found in %s', [FileName]));
          Result := False;
        end;
      end;
    end;
    

    You can use it like this:

    if AddLineToTemplate(
         'C:\path\to\customizations.js',
         '/*DO NOT MODIFY ABOVE THIS LINE!*/',
         '/*DO NOT MODIFY BELOW THIS LINE!*/', 
         '    dependencies.push("mxdfNewTransaction.controller.mxdfNewTransactionCtrl");') then
    begin
      Log('Success');
    end
      else
    begin
      Log('Failure');
    end;
    

    Beware of the LoadStringsFromFile and SaveStringsToFile limitations, when working with Unicode files. See Inno Setup Reading file in Ansi and Unicode encoding.