天天看點

InnoSetup中枚舉出INI檔案的所有sections和鍵值

InnoSetup支援一些INI檔案操作函數,

例如GetIniString,IniKeyExists等等。。

利用這些已有的函數,讀取/删除/檢測鍵值是否存在,都沒有問題。

但是,想要列出一個INI檔案有哪些Sections, 

某個Section下面有哪些鍵值,

就沒法做到了。

所幸InnoSetup有個很好用的 LoadStringsFromFile 函數,

用來讀取文本檔案很友善,讀INI自然不在話下。

然後再做一點簡單的解析,就能得到一個INI中所有的sections和鍵值了。

實作兩個函數如下:

讀取INI檔案中有哪些Sections, 并将其名字存放到 Arr數組裡。

procedure IniGetSections(var Arr: Array of String; const Path: String);

讀取INI檔案的某個Section底下,有哪些鍵名,并将這些鍵名存放到Arr數組裡。

procedure IniGetKeys(var Arr: Array of String; const Path: String; const Section: String);

procedure ArrayAddStr(var Arr: Array of String; Str: String);

var

  Len: Longint;

begin

  Len := GetArrayLength(Arr);

  SetArrayLength(Arr, Len + 1);

  Arr[Len] := Str;

end;

//-- INI

function IniGetSectionName(Line: String; var Name: String): Boolean;

  P0, P1: Integer;

    Line := TrimLeft(Line);

    P0 := Pos('[', Line);

    P1 := Pos(']', Line);

    if (P0 = 1) and (P1 > P0 + 1) then begin

      Name := Copy(Line, P0 + 1, P1 - P0 - 1);

      Result := True;

    end

    else

      Result := False;

function IniGetKeyName(Line: String; var Name: String): Boolean;

  Line := TrimLeft(Line);

  P0 := Pos('=', Line);

  P1 := pOS(';', Line); //; is start of comment

  if (P0 > 1) and ((P1 = 0) or (P1 > P0)) then begin

    Name := Trim(Copy(Line, 1, P0 - 1));

    Result := True;

  end

  else

    Result := False;

  i: Longint;

  Name: String;

  Lines: Array of String;

  SetArrayLength(Arr, 0);

  if not LoadStringsFromFile(Path, Lines) then exit;

  for i := 0 to GetArrayLength(Lines) - 1 do begin

    if IniGetSectionName(Lines[i], Name) then ArrayAddStr(Arr, Name);

  end;

    if IniGetSectionName(Lines[i], Name) then begin

      if CompareText(Name, Section) = 0 then break;

    end;

  if i < GetArrayLength(Lines) then begin

    { The section is }

    for i := i + 1 to GetArrayLength(Lines) - 1 do begin

      if IniGetSectionName(Lines[i], Name) then break

      else if IniGetKeyName(Lines[i], Name) then ArrayAddStr(Arr, Name);